in templates/vm_instance.py [0:0]
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())
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