def create_container(cmd, resource_group_name, name=None, image=None, location=None, cpu=1, memory=1.5, restart_policy='Always', ports=None, protocol=None, os_type='Linux', ip_address=None, dns_name_label=None, command_line=None, environment_variables=None, secure_environment_variables=None, registry_login_server=None, registry_username=None, registry_password=None, azure_file_volume_share_name=None, azure_file_volume_account_name=None, azure_file_volume_account_key=None, azure_file_volume_mount_path=None, log_analytics_workspace=None, log_analytics_workspace_key=None, vnet=None, vnet_name=None, vnet_address_prefix='10.0.0.0/16', subnet=None, subnet_address_prefix='10.0.0.0/24', network_profile=None, gitrepo_url=None, gitrepo_dir='.', gitrepo_revision=None, gitrepo_mount_path=None, secrets=None, secrets_mount_path=None, file=None, assign_identity=None, identity_scope=None, identity_role='Contributor', no_wait=False): """Create a container group. """ if file: return _create_update_from_file(cmd.cli_ctx, resource_group_name, name, location, file, no_wait) if not name: raise CLIError("error: the --name/-n argument is required unless specified with a passed in file.") if not image: raise CLIError("error: the --image argument is required unless specified with a passed in file.") ports = ports or [80] protocol = protocol or ContainerGroupNetworkProtocol.tcp container_resource_requirements = _create_resource_requirements(cpu=cpu, memory=memory) image_registry_credentials = _create_image_registry_credentials(registry_login_server=registry_login_server, registry_username=registry_username, registry_password=registry_password, image=image) command = shlex.split(command_line) if command_line else None volumes = [] mounts = [] azure_file_volume = _create_azure_file_volume(azure_file_volume_share_name=azure_file_volume_share_name, azure_file_volume_account_name=azure_file_volume_account_name, azure_file_volume_account_key=azure_file_volume_account_key) azure_file_volume_mount = _create_azure_file_volume_mount(azure_file_volume=azure_file_volume, azure_file_volume_mount_path=azure_file_volume_mount_path) if azure_file_volume: volumes.append(azure_file_volume) mounts.append(azure_file_volume_mount) secrets_volume = _create_secrets_volume(secrets) secrets_volume_mount = _create_secrets_volume_mount(secrets_volume=secrets_volume, secrets_mount_path=secrets_mount_path) if secrets_volume: volumes.append(secrets_volume) mounts.append(secrets_volume_mount) diagnostics = None tags = {} if log_analytics_workspace and log_analytics_workspace_key: log_analytics = LogAnalytics( workspace_id=log_analytics_workspace, workspace_key=log_analytics_workspace_key) diagnostics = ContainerGroupDiagnostics( log_analytics=log_analytics ) elif log_analytics_workspace and not log_analytics_workspace_key: diagnostics, tags = _get_diagnostics_from_workspace( cmd.cli_ctx, log_analytics_workspace) if not diagnostics: raise CLIError('Log Analytics workspace "' + log_analytics_workspace + '" not found.') elif not log_analytics_workspace and log_analytics_workspace_key: raise CLIError('"--log-analytics-workspace-key" requires "--log-analytics-workspace".') gitrepo_volume = _create_gitrepo_volume(gitrepo_url=gitrepo_url, gitrepo_dir=gitrepo_dir, gitrepo_revision=gitrepo_revision) gitrepo_volume_mount = _create_gitrepo_volume_mount(gitrepo_volume=gitrepo_volume, gitrepo_mount_path=gitrepo_mount_path) if gitrepo_volume: volumes.append(gitrepo_volume) mounts.append(gitrepo_volume_mount) # Concatenate secure and standard environment variables if environment_variables and secure_environment_variables: environment_variables = environment_variables + secure_environment_variables else: environment_variables = environment_variables or secure_environment_variables identity = None if assign_identity is not None: identity = _build_identities_info(assign_identity) # Set up VNET, subnet and network profile if needed if subnet and not network_profile: network_profile = _get_vnet_network_profile(cmd, location, resource_group_name, vnet, vnet_address_prefix, subnet, subnet_address_prefix) cg_network_profile = None if network_profile: cg_network_profile = ContainerGroupNetworkProfile(id=network_profile) cgroup_ip_address = _create_ip_address(ip_address, ports, protocol, dns_name_label, network_profile) container = Container(name=name, image=image, resources=container_resource_requirements, command=command, ports=[ContainerPort( port=p, protocol=protocol) for p in ports] if cgroup_ip_address else None, environment_variables=environment_variables, volume_mounts=mounts or None) cgroup = ContainerGroup(location=location, identity=identity, containers=[container], os_type=os_type, restart_policy=restart_policy, ip_address=cgroup_ip_address, image_registry_credentials=image_registry_credentials, volumes=volumes or None, network_profile=cg_network_profile, diagnostics=diagnostics, tags=tags) container_group_client = cf_container_groups(cmd.cli_ctx) lro = sdk_no_wait(no_wait, container_group_client.create_or_update, resource_group_name, name, cgroup) if assign_identity is not None and identity_scope: from azure.cli.core.commands.arm import assign_identity cg = container_group_client.get(resource_group_name, name) assign_identity(cmd.cli_ctx, lambda: cg, lambda cg: cg, identity_role, identity_scope) return lro
def execute(self, context: dict) -> int: # Check name again in case it was templated. self._check_name(self.name) self._ci_hook = AzureContainerInstanceHook(self.ci_conn_id) if self.fail_if_exists: self.log.info("Testing if container group already exists") if self._ci_hook.exists(self.resource_group, self.name): raise AirflowException("Container group exists") if self.registry_conn_id: registry_hook = AzureContainerRegistryHook(self.registry_conn_id) image_registry_credentials: Optional[list] = [ registry_hook.connection, ] else: image_registry_credentials = None environment_variables = [] for key, value in self.environment_variables.items(): if key in self.secured_variables: e = EnvironmentVariable(name=key, secure_value=value) else: e = EnvironmentVariable(name=key, value=value) environment_variables.append(e) volumes: List[Union[Volume, Volume]] = [] volume_mounts: List[Union[VolumeMount, VolumeMount]] = [] for conn_id, account_name, share_name, mount_path, read_only in self.volumes: hook = AzureContainerVolumeHook(conn_id) mount_name = "mount-%d" % len(volumes) volumes.append( hook.get_file_volume(mount_name, share_name, account_name, read_only)) volume_mounts.append( VolumeMount(name=mount_name, mount_path=mount_path, read_only=read_only)) exit_code = 1 try: self.log.info("Starting container group with %.1f cpu %.1f mem", self.cpu, self.memory_in_gb) if self.gpu: self.log.info("GPU count: %.1f, GPU SKU: %s", self.gpu.count, self.gpu.sku) resources = ResourceRequirements(requests=ResourceRequests( memory_in_gb=self.memory_in_gb, cpu=self.cpu, gpu=self.gpu)) if self.ip_address and not self.ports: self.ports = [ContainerPort(port=80)] self.log.info( "Default port set. Container will listen on port 80") container = Container( name=self.name, image=self.image, resources=resources, command=self.command, environment_variables=environment_variables, volume_mounts=volume_mounts, ports=self.ports, ) container_group = ContainerGroup( location=self.region, containers=[ container, ], image_registry_credentials=image_registry_credentials, volumes=volumes, restart_policy=self.restart_policy, os_type=self.os_type, tags=self.tags, ip_address=self.ip_address, ) self._ci_hook.create_or_update(self.resource_group, self.name, container_group) self.log.info("Container group started %s/%s", self.resource_group, self.name) exit_code = self._monitor_logging(self.resource_group, self.name) self.log.info("Container had exit code: %s", exit_code) if exit_code != 0: raise AirflowException( "Container had a non-zero exit code, %s" % exit_code) return exit_code except CloudError: self.log.exception("Could not start container group") raise AirflowException("Could not start container group") finally: if exit_code == 0 or self.remove_on_error: self.on_kill()
def create_container(cmd, resource_group_name, name=None, image=None, location=None, cpu=1, memory=1.5, restart_policy='Always', ports=None, protocol=None, os_type='Linux', ip_address=None, dns_name_label=None, command_line=None, environment_variables=None, registry_login_server=None, registry_username=None, registry_password=None, azure_file_volume_share_name=None, azure_file_volume_account_name=None, azure_file_volume_account_key=None, azure_file_volume_mount_path=None, log_analytics_workspace=None, log_analytics_workspace_key=None, gitrepo_url=None, gitrepo_dir='.', gitrepo_revision=None, gitrepo_mount_path=None, secrets=None, secrets_mount_path=None, file=None, no_wait=False): """Create a container group. """ if file: return _create_update_from_file(cmd.cli_ctx, resource_group_name, name, location, file, no_wait) if not name: raise CLIError( "error: the --name/-n argument is required unless specified with a passed in file." ) if not image: raise CLIError( "error: the --image argument is required unless specified with a passed in file." ) ports = ports or [80] protocol = protocol or ContainerGroupNetworkProtocol.tcp container_resource_requirements = _create_resource_requirements( cpu=cpu, memory=memory) image_registry_credentials = _create_image_registry_credentials( registry_login_server=registry_login_server, registry_username=registry_username, registry_password=registry_password, image=image) command = shlex.split(command_line) if command_line else None volumes = [] mounts = [] azure_file_volume = _create_azure_file_volume( azure_file_volume_share_name=azure_file_volume_share_name, azure_file_volume_account_name=azure_file_volume_account_name, azure_file_volume_account_key=azure_file_volume_account_key) azure_file_volume_mount = _create_azure_file_volume_mount( azure_file_volume=azure_file_volume, azure_file_volume_mount_path=azure_file_volume_mount_path) if azure_file_volume: volumes.append(azure_file_volume) mounts.append(azure_file_volume_mount) secrets_volume = _create_secrets_volume(secrets) secrets_volume_mount = _create_secrets_volume_mount( secrets_volume=secrets_volume, secrets_mount_path=secrets_mount_path) if secrets_volume: volumes.append(secrets_volume) mounts.append(secrets_volume_mount) diagnostics = None tags = {} if log_analytics_workspace and log_analytics_workspace_key: log_analytics = LogAnalytics(workspace_id=log_analytics_workspace, workspace_key=log_analytics_workspace_key) diagnostics = ContainerGroupDiagnostics(log_analytics=log_analytics) elif log_analytics_workspace and not log_analytics_workspace_key: diagnostics, tags = _get_diagnostics_from_workspace( cmd.cli_ctx, log_analytics_workspace) if not diagnostics: raise CLIError('Log Analytics workspace "' + log_analytics_workspace + '" not found.') elif not log_analytics_workspace and log_analytics_workspace_key: raise CLIError( '"--log-analytics-workspace-key" requires "--log-analytics-workspace".' ) gitrepo_volume = _create_gitrepo_volume(gitrepo_url=gitrepo_url, gitrepo_dir=gitrepo_dir, gitrepo_revision=gitrepo_revision) gitrepo_volume_mount = _create_gitrepo_volume_mount( gitrepo_volume=gitrepo_volume, gitrepo_mount_path=gitrepo_mount_path) if gitrepo_volume: volumes.append(gitrepo_volume) mounts.append(gitrepo_volume_mount) cgroup_ip_address = _create_ip_address(ip_address, ports, protocol, dns_name_label) container = Container( name=name, image=image, resources=container_resource_requirements, command=command, ports=[ContainerPort(port=p, protocol=protocol) for p in ports] if cgroup_ip_address else None, environment_variables=environment_variables, volume_mounts=mounts or None) cgroup = ContainerGroup( location=location, containers=[container], os_type=os_type, restart_policy=restart_policy, ip_address=cgroup_ip_address, image_registry_credentials=image_registry_credentials, volumes=volumes or None, diagnostics=diagnostics, tags=tags) container_group_client = cf_container_groups(cmd.cli_ctx) return sdk_no_wait(no_wait, container_group_client.create_or_update, resource_group_name, name, cgroup)
def create_container(client, resource_group_name, name, image, location=None, cpu=1, memory=1.5, restart_policy='Always', ports=None, os_type='Linux', ip_address=None, dns_name_label=None, command_line=None, environment_variables=None, registry_login_server=None, registry_username=None, registry_password=None, azure_file_volume_share_name=None, azure_file_volume_account_name=None, azure_file_volume_account_key=None, azure_file_volume_mount_path=None, secrets=None, secrets_mount_path=None): """Create a container group. """ ports = ports or [80] container_resource_requirements = _create_resource_requirements( cpu=cpu, memory=memory) image_registry_credentials = _create_image_registry_credentials( registry_login_server=registry_login_server, registry_username=registry_username, registry_password=registry_password, image=image) command = shlex.split(command_line) if command_line else None volumes = [] mounts = [] azure_file_volume = _create_azure_file_volume( azure_file_volume_share_name=azure_file_volume_share_name, azure_file_volume_account_name=azure_file_volume_account_name, azure_file_volume_account_key=azure_file_volume_account_key) azure_file_volume_mount = _create_azure_file_volume_mount( azure_file_volume=azure_file_volume, azure_file_volume_mount_path=azure_file_volume_mount_path) if azure_file_volume: volumes.append(azure_file_volume) mounts.append(azure_file_volume_mount) secrets_volume = _create_secrets_volume(secrets) secrets_volume_mount = _create_secrets_volume_mount( secrets_volume=secrets_volume, secrets_mount_path=secrets_mount_path) if secrets_volume: volumes.append(secrets_volume) mounts.append(secrets_volume_mount) cgroup_ip_address = _create_ip_address(ip_address, ports, dns_name_label) container = Container( name=name, image=image, resources=container_resource_requirements, command=command, ports=[ContainerPort(port=p) for p in ports] if cgroup_ip_address else None, environment_variables=environment_variables, volume_mounts=mounts or None) cgroup = ContainerGroup( location=location, containers=[container], os_type=os_type, restart_policy=restart_policy, ip_address=cgroup_ip_address, image_registry_credentials=image_registry_credentials, volumes=volumes or None) return client.create_or_update(resource_group_name, name, cgroup)
def _start_container(self, resource_handler): log.debug('Starting Azure ACI') location = self.res['location'].lower() self.resource_client.resource_groups.create_or_update( self.res['resource_group'], {'location': self.res['location']}) container_group_name = unique_vmname(self.node_def) network_type = self.res['network_type'] network_profile = None if 'gpu_type' in self.res: count = self.res['gpu_count'] if 'gpu_count' in self.res else 1 gpu = GpuResource(count=count, sku=self.res['gpu_type']) container_resource_requests = ResourceRequests( memory_in_gb=self.res['memory'], cpu=self.res['cpu_cores'], gpu=gpu) else: container_resource_requests = ResourceRequests( memory_in_gb=self.res['memory'], cpu=self.res['cpu_cores']) container_resource_requirements = ResourceRequirements( requests=container_resource_requests) ports = [] ipports = [] for porte in self.res.get('ports', []): port = porte protocol = 'TCP' if isinstance(porte, str) and '/' in porte: (port, protocol) = port.split('/') port = int(port) ports.append(ContainerPort(port=port, protocol=protocol)) ipports.append(Port(protocol=protocol, port=port)) environment = [] if network_type.lower() == 'public': pubip_var = EnvironmentVariable(name='_OCCOPUS_ALLOCATED_FQDN', value='%s.%s.azurecontainer.io' % (container_group_name, location)) environment.append(pubip_var) for env in self.env: edata = env.split('=', 1) if len(edata) != 2: continue env_var = EnvironmentVariable(name=edata[0], value=edata[1]) environment.append(env_var) container = Container( name=container_group_name, image=self.res['image'], resources=container_resource_requirements, ports=ports, command=self.command if self.command is not None else None, environment_variables=environment) if network_type.lower() == 'public': group_ip_address = IpAddress(ports=ipports, dns_name_label=container_group_name, type='Public') self.vnet_name = None elif network_type.lower() == 'private': vnet_name = unique_vmname(self.node_def) + '-vnet' if self.res.get( 'vnet_name', None) == None else self.res['vnet_name'] self.vnet_name = vnet_name subnet_name = unique_vmname( self.node_def) + '-subnet' if self.res.get( 'subnet_name', None) == None else self.res['subnet_name'] network_profile_name = unique_vmname(self.node_def) + '-netprofile' if self.res.get('vnet_name', None) == None: log.debug('Creating vnet') async_vnet_creation = self.network_client.virtual_networks.create_or_update( self.res['resource_group'], vnet_name, { 'location': location, 'address_space': { 'address_prefixes': ['10.0.0.0/16'] } }) async_vnet_creation.wait() self.created_resources['virtual_network'] = vnet_name log.debug('Created vnet') if self.res.get('subnet_name', None) == None: # Create Subnet log.debug('Creating Subnet') aci_delegation_service_name = "Microsoft.ContainerInstance/containerGroups" aci_delegation = Delegation( name=aci_delegation_service_name, service_name=aci_delegation_service_name) subnet = Subnet(name=subnet_name, location=location, address_prefix='10.0.0.0/24', delegations=[aci_delegation]) subnet_info = self.network_client.subnets.create_or_update( self.res['resource_group'], vnet_name, subnet_name, subnet).result() self.created_resources['subnet'] = subnet_name log.debug('Creatied Subnet') else: subnet_info = self.network_client.subnets.get( self.res['resource_group'], vnet_name, subnet_name) default_network_profile_name = "aci-network-profile-{}-{}".format( vnet_name, subnet_name) network_profile_ops = self.network_client.network_profiles network_profile = NetworkProfile( name=default_network_profile_name, location=location, container_network_interface_configurations=[ ContainerNetworkInterfaceConfiguration( name="eth0", ip_configurations=[ IPConfigurationProfile(name="ipconfigprofile", subnet=subnet_info) ]) ]) network_profile = network_profile_ops.create_or_update( self.res['resource_group'], network_profile_name, network_profile).result() group_ip_address = IpAddress(ports=ipports, type='Private') else: errormsg = '[{0}] Network type "{1}" is not supported. Please use either "Public" or "Private"'.format( resource_handler.name, network_type) log.debug(errormsg) raise NodeCreationError(None, errormsg) cg_network_profile = None if network_profile: cg_network_profile = ContainerGroupNetworkProfile( id=network_profile.id) self.created_resources['network_profile'] = network_profile_name group = ContainerGroup(location=location, containers=[container], os_type=self.res['os_type'], ip_address=group_ip_address, network_profile=cg_network_profile) # Create the container group self.aci_client.container_groups.create_or_update( self.res['resource_group'], container_group_name, group) return container_group_name
def create_container(cmd, resource_group_name, name=None, image=None, location=None, cpu=1, memory=1.5, restart_policy='Always', ports=None, os_type='Linux', ip_address=None, dns_name_label=None, command_line=None, environment_variables=None, registry_login_server=None, registry_username=None, registry_password=None, azure_file_volume_share_name=None, azure_file_volume_account_name=None, azure_file_volume_account_key=None, azure_file_volume_mount_path=None, gitrepo_url=None, gitrepo_dir='.', gitrepo_revision=None, gitrepo_mount_path=None, secrets=None, secrets_mount_path=None, file=None): """Create a container group. """ if file: return _create_update_from_file(cmd.cli_ctx, resource_group_name, name, location, file) if not name: raise CLIError( "error: the --name/-n argument is required unless specified with a passed in file." ) if not image: raise CLIError( "error: the --image argument is required unless specified with a passed in file." ) ports = ports or [80] container_resource_requirements = _create_resource_requirements( cpu=cpu, memory=memory) image_registry_credentials = _create_image_registry_credentials( registry_login_server=registry_login_server, registry_username=registry_username, registry_password=registry_password, image=image) command = shlex.split(command_line) if command_line else None volumes = [] mounts = [] azure_file_volume = _create_azure_file_volume( azure_file_volume_share_name=azure_file_volume_share_name, azure_file_volume_account_name=azure_file_volume_account_name, azure_file_volume_account_key=azure_file_volume_account_key) azure_file_volume_mount = _create_azure_file_volume_mount( azure_file_volume=azure_file_volume, azure_file_volume_mount_path=azure_file_volume_mount_path) if azure_file_volume: volumes.append(azure_file_volume) mounts.append(azure_file_volume_mount) secrets_volume = _create_secrets_volume(secrets) secrets_volume_mount = _create_secrets_volume_mount( secrets_volume=secrets_volume, secrets_mount_path=secrets_mount_path) if secrets_volume: volumes.append(secrets_volume) mounts.append(secrets_volume_mount) gitrepo_volume = _create_gitrepo_volume(gitrepo_url=gitrepo_url, gitrepo_dir=gitrepo_dir, gitrepo_revision=gitrepo_revision) gitrepo_volume_mount = _create_gitrepo_volume_mount( gitrepo_volume=gitrepo_volume, gitrepo_mount_path=gitrepo_mount_path) if gitrepo_volume: volumes.append(gitrepo_volume) mounts.append(gitrepo_volume_mount) cgroup_ip_address = _create_ip_address(ip_address, ports, dns_name_label) container = Container( name=name, image=image, resources=container_resource_requirements, command=command, ports=[ContainerPort(port=p) for p in ports] if cgroup_ip_address else None, environment_variables=environment_variables, volume_mounts=mounts or None) cgroup = ContainerGroup( location=location, containers=[container], os_type=os_type, restart_policy=restart_policy, ip_address=cgroup_ip_address, image_registry_credentials=image_registry_credentials, volumes=volumes or None) container_group_client = cf_container_groups(cmd.cli_ctx) raw_response = container_group_client.create_or_update(resource_group_name, name, cgroup, raw=True) return raw_response.output