def GenerateComputeVM(context, create_disks_separately=True): """Generates one VM instance resource. Args: context: Template context dictionary. create_disks_separately: When true (default), all new disk resources are created as separate resources. This is legacy behaviour from when multiple disks creation was not allowed in the disks property. Returns: dictionary representing instance resource. """ prop = context.properties boot_disk_type = prop.setdefault(BOOTDISKTYPE, DEFAULT_DISKTYPE) prop[default.DISKTYPE] = boot_disk_type can_ip_fwd = prop.setdefault(CAN_IP_FWD, DEFAULT_IP_FWD) disks = prop.setdefault(default.DISKS, list()) local_ssd = prop.setdefault(default.LOCAL_SSD, 0) if disks: if create_disks_separately: # Legacy alternative from when multiple disks on creation were not allowed new_disks = prop.setdefault(default.DISK_RESOURCES, list()) SetDiskProperties(context, disks) disks, prop[DISK_RESOURCES] = GenerateDisks( context, disks, new_disks) else: # All new disks (except local ssd) must provide a sourceImage or existing # source. Add blank source image if non provided. SetDiskProperties(context, disks, add_blank_src_img=True) machine_type = prop.setdefault(MACHINETYPE, DEFAULT_MACHINETYPE) metadata = prop.setdefault(METADATA, dict()) SetMetadataDefaults(metadata) vm_name = MakeVMName(context) provide_boot = prop.setdefault(PROVIDE_BOOT, DEFAULT_PROVIDE_BOOT) tags = prop.setdefault(TAGS, dict([("items", [])])) zone = prop.setdefault(ZONE, DEFAULT_ZONE) if provide_boot: dev_mode = DEVIMAGE in prop and prop[DEVIMAGE] src_image = common.MakeC2DImageLink(prop[SRCIMAGE], dev_mode) boot_name = common.AutoName(context.env["name"], default.DISK, "boot") disk_size = prop.get(BOOTDISKSIZE, DEFAULT_BOOTDISKSIZE) disk_type = common.MakeLocalComputeLink(context, DISKTYPE) autodelete = prop.get(AUTODELETE_BOOTDISK, DEFAULT_AUTODELETE_BOOTDISK) disks = PrependBootDisk(disks, boot_name, disk_type, disk_size, src_image, autodelete) if local_ssd: disks = AppendLocalSSDDisks(context, disks, local_ssd) machine_type = common.MakeLocalComputeLink(context, default.MACHINETYPE) # To be consistent with Dev console and gcloud, service accounts need to be # explicitly disabled remove_scopes = prop[NO_SCOPE] if NO_SCOPE in prop else False if remove_scopes and SERVICE_ACCOUNTS in prop: prop.pop(SERVICE_ACCOUNTS) else: # Make sure there is a default service account prop.setdefault(SERVICE_ACCOUNTS, copy.deepcopy(DEFAULT_SERVICE_ACCOUNT)) resource = [] resource.insert( 0, { "name": vm_name, "type": default.INSTANCE, "properties": { "zone": zone, "machineType": machine_type, "canIpForward": can_ip_fwd, "disks": disks, "networkInterfaces": GetNetworkInterfaces(context), "tags": tags, "metadata": metadata, }, }, ) # Pass through any additional properties to the VM if SERVICE_ACCOUNTS in prop: resource[0]["properties"].update( {SERVICE_ACCOUNTS: prop[SERVICE_ACCOUNTS]}) if GUEST_ACCELERATORS in prop: for accelerators in prop[GUEST_ACCELERATORS]: accelerators["acceleratorType"] = common.MakeAcceleratorTypeLink( context, accelerators["acceleratorType"]) resource[0]["properties"].update( {GUEST_ACCELERATORS: prop[GUEST_ACCELERATORS]}) # GPUs cannot be attached to live migratable instances. See: # https://cloud.google.com/compute/docs/gpus/#restrictions resource[0]["properties"].update( {"scheduling": { "onHostMaintenance": "terminate" }}) return resource
def GenerateComputeVM(context, create_disks_separately=True): """Generates one VM instance resource. Args: context: Template context dictionary. create_disks_separately: When true (default), all new disk resources are created as separate resources. This is legacy behaviour from when multiple disks creation was not allowed in the disks property. Returns: dictionary representing instance resource. """ prop = context.properties boot_disk_type = prop.setdefault(BOOTDISKTYPE, DEFAULT_DISKTYPE) prop[default.DISKTYPE] = boot_disk_type can_ip_fwd = prop.setdefault(CAN_IP_FWD, DEFAULT_IP_FWD) disks = prop.setdefault(default.DISKS, list()) local_ssd = prop.setdefault(default.LOCAL_SSD, 0) if disks: if create_disks_separately: # Legacy alternative from when multiple disks on creation were not allowed new_disks = prop.setdefault(default.DISK_RESOURCES, list()) SetDiskProperties(context, disks) disks, prop[DISK_RESOURCES] = GenerateDisks(context, disks, new_disks) else: # All new disks (except local ssd) must provide a sourceImage or existing # source. Add blank source image if non provided. SetDiskProperties(context, disks, add_blank_src_img=True) machine_type = prop.setdefault(MACHINETYPE, DEFAULT_MACHINETYPE) metadata = prop.setdefault(METADATA, dict()) SetMetadataDefaults(metadata) network = prop.setdefault(NETWORK, DEFAULT_NETWORK) vm_name = MakeVMName(context) provide_boot = prop.setdefault(PROVIDE_BOOT, DEFAULT_PROVIDE_BOOT) tags = prop.setdefault(TAGS, dict([('items', [])])) zone = prop.setdefault(ZONE, DEFAULT_ZONE) has_external_ip = prop.get(HAS_EXTERNAL_IP, DEFAULT_HAS_EXTERNAL_IP) static_ip = prop.get(STATIC_IP, DEFAULT_STATIC_IP) nat_ip = prop.get(NAT_IP, None) if provide_boot: dev_mode = DEVIMAGE in prop and prop[DEVIMAGE] src_image = common.MakeC2DImageLink(prop[SRCIMAGE], dev_mode) boot_name = common.AutoName(context.env['name'], default.DISK, 'boot') disk_size = prop.get(BOOTDISKSIZE, DEFAULT_BOOTDISKSIZE) disk_type = common.MakeLocalComputeLink(context, DISKTYPE) autodelete = prop.get(AUTODELETE_BOOTDISK, DEFAULT_AUTODELETE_BOOTDISK) disks = PrependBootDisk(disks, boot_name, disk_type, disk_size, src_image, autodelete) if local_ssd: disks = AppendLocalSSDDisks(context, disks, local_ssd) machine_type = common.MakeLocalComputeLink(context, default.MACHINETYPE) network = common.MakeGlobalComputeLink(context, default.NETWORK) subnetwork = '' if default.SUBNETWORK in prop: subnetwork = common.MakeSubnetworkComputeLink(context, default.SUBNETWORK) # To be consistent with Dev console and gcloud, service accounts need to be # explicitly disabled remove_scopes = prop[NO_SCOPE] if NO_SCOPE in prop else False if remove_scopes and SERVICE_ACCOUNTS in prop: prop.pop(SERVICE_ACCOUNTS) else: # Make sure there is a default service account prop.setdefault(SERVICE_ACCOUNTS, copy.deepcopy(DEFAULT_SERVICE_ACCOUNT)) resource = [] access_configs = [] if has_external_ip: access_config = {'name': default.EXTERNAL, 'type': default.ONE_NAT} access_configs.append(access_config) if static_ip and nat_ip: raise common.Error( 'staticIP=True and natIP cannot be specified at the same time') if static_ip: address_resource, nat_ip = MakeStaticAddress(vm_name, zone) resource.append(address_resource) if nat_ip: access_config['natIP'] = nat_ip else: if static_ip: raise common.Error('staticIP cannot be True when hasExternalIP is False') if nat_ip: raise common.Error( 'natIP must not be specified when hasExternalIP is False') network_interfaces = [] if subnetwork: network_interfaces.insert(0, { 'network': network, 'subnetwork': subnetwork, 'accessConfigs': access_configs }) else: network_interfaces.insert(0, { 'network': network, 'accessConfigs': access_configs }) resource.insert(0, { 'name': vm_name, 'type': default.INSTANCE, 'properties': { 'zone': zone, 'machineType': machine_type, 'canIpForward': can_ip_fwd, 'disks': disks, 'networkInterfaces': network_interfaces, 'tags': tags, 'metadata': metadata, } }) # Pass through any additional properties to the VM if SERVICE_ACCOUNTS in prop: resource[0]['properties'].update({SERVICE_ACCOUNTS: prop[SERVICE_ACCOUNTS]}) if GUEST_ACCELERATORS in prop: for accelerators in prop[GUEST_ACCELERATORS]: accelerators['acceleratorType'] = common.MakeAcceleratorTypeLink( context, accelerators['acceleratorType']) resource[0]['properties'].update( {GUEST_ACCELERATORS: prop[GUEST_ACCELERATORS]}) # GPUs cannot be attached to live migratable instances. See: # https://cloud.google.com/compute/docs/gpus/#restrictions resource[0]['properties'].update( {'scheduling': {'onHostMaintenance': 'terminate'}}) return resource
def GenerateComputeVM(context, create_disks_separately=True): """Generates one VM instance resource. Args: context: Template context dictionary. create_disks_separately: When true (default), all new disk resources are created as separate resources. This is legacy behaviour from when multiple disks creation was not allowed in the disks property. Returns: dictionary representing instance resource. """ prop = context.properties boot_disk_type = prop.setdefault(BOOTDISKTYPE, DEFAULT_DISKTYPE) prop[default.DISKTYPE] = boot_disk_type can_ip_fwd = prop.setdefault(CAN_IP_FWD, DEFAULT_IP_FWD) disks = prop.setdefault(default.DISKS, list()) local_ssd = prop.setdefault(default.LOCAL_SSD, 0) project = context.env[default.PROJECT] deployApiToGke = context.properties['deployApiToGke'] datashare_install_bucket_name = project + '-install-bucket' datashare_ingestion_bucket_name = project + '-cds-bucket' k8s_cluster_name = 'datashare-cluster-resource' # gce_service_account = context.properties['gceServiceAccount'] if disks: if create_disks_separately: # Legacy alternative from when multiple disks on creation were not allowed new_disks = prop.setdefault(default.DISK_RESOURCES, list()) SetDiskProperties(context, disks) disks, prop[DISK_RESOURCES] = GenerateDisks(context, disks, new_disks) else: # All new disks (except local ssd) must provide a sourceImage or existing # source. Add blank source image if non provided. SetDiskProperties(context, disks, add_blank_src_img=True) machine_type = prop.setdefault(MACHINETYPE, DEFAULT_MACHINETYPE) metadata = prop.setdefault(METADATA, dict()) SetMetadataDefaults(metadata) vm_name = MakeVMName(context) provide_boot = prop.setdefault(PROVIDE_BOOT, DEFAULT_PROVIDE_BOOT) tags = prop.setdefault(TAGS, dict([('items', [])])) zone = prop.setdefault(ZONE, DEFAULT_ZONE) if provide_boot: dev_mode = DEVIMAGE in prop and prop[DEVIMAGE] src_image = common.MakeC2DImageLink(prop[SRCIMAGE], dev_mode) boot_name = common.AutoName(context.env['name'], default.DISK, 'boot') disk_size = prop.get(BOOTDISKSIZE, DEFAULT_BOOTDISKSIZE) disk_type = common.MakeLocalComputeLink(context, DISKTYPE) autodelete = prop.get(AUTODELETE_BOOTDISK, DEFAULT_AUTODELETE_BOOTDISK) disks = PrependBootDisk(disks, boot_name, disk_type, disk_size, src_image, autodelete) if local_ssd: disks = AppendLocalSSDDisks(context, disks, local_ssd) machine_type = common.MakeLocalComputeLink(context, default.MACHINETYPE) # To be consistent with Dev console and gcloud, service accounts need to be # explicitly disabled remove_scopes = prop[NO_SCOPE] if NO_SCOPE in prop else False if remove_scopes and SERVICE_ACCOUNTS in prop: prop.pop(SERVICE_ACCOUNTS) else: # Make sure there is a default service account prop.setdefault(SERVICE_ACCOUNTS, copy.deepcopy(DEFAULT_SERVICE_ACCOUNT)) resource = [] resource.insert( 0, { 'name': vm_name, 'type': default.INSTANCE, 'metadata': { 'dependsOn': [ datashare_ingestion_bucket_name ] }, 'properties': { 'zone': zone, 'machineType': machine_type, 'canIpForward': can_ip_fwd, 'disks': disks, 'networkInterfaces': GetNetworkInterfaces(context), 'tags': tags, 'metadata': metadata, } }) if deployApiToGke: resource[0]['metadata']['dependsOn'].append(k8s_cluster_name) if context.properties['useRuntimeConfigWaiter']: configName = context.properties['waiterConfigName'] resource[0]['metadata']['dependsOn'].append(configName) resource[0]['metadata']['dependsOn'].append(datashare_install_bucket_name) # Pass through any additional properties to the VM if SERVICE_ACCOUNTS in prop: resource[0]['properties'].update({SERVICE_ACCOUNTS: prop[SERVICE_ACCOUNTS]}) if GUEST_ACCELERATORS in prop: for accelerators in prop[GUEST_ACCELERATORS]: accelerators['acceleratorType'] = common.MakeAcceleratorTypeLink( context, accelerators['acceleratorType']) resource[0]['properties'].update( {GUEST_ACCELERATORS: prop[GUEST_ACCELERATORS]}) # GPUs cannot be attached to live migratable instances. See: # https://cloud.google.com/compute/docs/gpus/#restrictions resource[0]['properties'].update( {'scheduling': {'onHostMaintenance': 'terminate'}}) return resource