in perfkitbenchmarker/providers/azure/azure_virtual_machine.py [0:0]
def _Create(self):
"""See base class."""
assert self.network is not None
os_disk_args = self.create_os_disk_strategy.GetCreationCommand()[
'create-disk'
]
enable_secure_boot = azure_flags.AZURE_SECURE_BOOT.value
if (
self.trusted_launch_unsupported_type
and enable_secure_boot is not None
):
raise errors.Benchmarks.UnsupportedConfigError(
"Please don't set --azure_secure_boot for"
f' {self.machine_type} machine_type. Attemping to update secure boot'
' flag on a VM with standard security type fails with error "Use of'
' UEFI settings is not supported...".',
)
security_args = []
secure_boot_args = []
# if machine is confidential or trusted launch, we can update secure boot
if self.machine_type_is_confidential:
security_args = [
'--enable-vtpm',
'true',
'--security-type',
'ConfidentialVM',
'--os-disk-security-encryption-type',
'VMGuestStateOnly',
]
if enable_secure_boot is None:
secure_boot_args = [
'--enable-secure-boot',
'true',
]
if enable_secure_boot is not None:
secure_boot_args = [
'--enable-secure-boot',
str(enable_secure_boot).lower(),
]
tags = {}
tags.update(self.vm_metadata)
tags.update(util.GetResourceTags(self.resource_group.timeout_minutes))
# Signal (along with timeout_utc) that VM is short lived.
tags['vm_nature'] = 'ephemeral'
tag_args = ['--tags'] + util.FormatTags(tags)
create_cmd = (
[
azure.AZURE_PATH,
'vm',
'create',
'--location',
self.region,
'--image',
self.image,
'--size',
self.machine_type,
'--admin-username',
self.user_name,
'--name',
self.name,
]
+ os_disk_args
+ security_args
+ secure_boot_args
+ self.resource_group.args
+ self.nic.args
+ tag_args
)
if self.hypervisor_generation > 1:
# Always specify disk controller type if supported (gen 2 hypervisor).
# If a machine supports both NVMe and SCSI, it will use NVMe, but PKB will
# assume it defaults to SCSI and fail to find the disk.
# Note this does mean PKB will downgrade machines that support both to
# SCSI unless they are explicitly specified as NVMe.
# TODO(pclay): Detect whether SKUs support NVMe.
if self.SupportsNVMe():
create_cmd.extend(['--disk-controller-type', 'NVMe'])
else:
create_cmd.extend(['--disk-controller-type', 'SCSI'])
if self.trusted_launch_unsupported_type:
create_cmd.extend(['--security-type', 'Standard'])
if self.boot_startup_script:
create_cmd.extend(['--custom-data', self.boot_startup_script])
if self._RequiresUltraDisk():
self.ultra_ssd_enabled = True
create_cmd.extend(['--ultra-ssd-enabled'])
if self.availability_zone:
create_cmd.extend(['--zone', self.availability_zone])
# Resources in Availability Set are not allowed to be
# deployed to particular hosts.
if self.use_dedicated_host:
create_cmd.extend(
['--host-group', self.host.host_group, '--host', self.host.name]
)
num_hosts = len(self.host_list)
if self.network.placement_group:
create_cmd.extend(self.network.placement_group.AddVmArgs())
if self.low_priority:
create_cmd.extend(['--priority', 'Spot'])
if self.password:
create_cmd.extend(['--admin-password', self.password])
else:
create_cmd.extend(['--ssh-key-value', self.ssh_public_key])
# Uses a custom default because create has a very long tail.
azure_vm_create_timeout = 1800
_, stderr, retcode = vm_util.IssueCommand(
create_cmd, timeout=azure_vm_create_timeout, raise_on_failure=False
)
if retcode:
if 'quota' in stderr.lower():
raise errors.Benchmarks.QuotaFailure(
virtual_machine.QUOTA_EXCEEDED_MESSAGE + stderr
)
elif self.low_priority and (
re.search(r'requested VM size \S+ is not available', stderr)
or re.search(r'not available in location .+ for subscription', stderr)
or re.search(
r'Following SKUs have failed for Capacity Restrictions', stderr
)
):
raise errors.Benchmarks.InsufficientCapacityCloudFailure(stderr)
elif re.search(
r'requested VM size \S+ is not available', stderr
) or re.search(r'not available in location .+ for subscription', stderr):
raise errors.Benchmarks.UnsupportedConfigError(stderr)
elif self.low_priority and 'OverconstrainedAllocationRequest' in stderr:
raise errors.Benchmarks.InsufficientCapacityCloudFailure(stderr)
elif _OS_PROVISIONING_TIMED_OUT in stderr:
raise errors.Resource.ProvisionTimeoutError(stderr)
elif "Virtual Machine Scale Set with '<NULL>' security type." in stderr:
raise errors.Resource.CreationError(
f'Failed to create VM: {self.machine_type} is likely a confidential'
' machine, which PKB does not support at this time.\n\n'
f' Full error: {stderr} return code: {retcode}'
)
elif "cannot boot Hypervisor Generation '1'" in stderr:
raise errors.Resource.CreationError(
f'Failed to create VM: {self.machine_type} is unable to support V1 '
'Hypervision. Please update _MACHINE_TYPES_ONLY_SUPPORT_GEN1_IMAGES'
' in azure_virtual_machine.py.\n\n'
f' Full error: {stderr} return code: {retcode}'
)
elif self.use_dedicated_host and 'AllocationFailed' in stderr:
if self.num_vms_per_host:
raise errors.Resource.CreationError(
'Failed to create host: %d vms of type %s per host exceeds '
'memory capacity limits of the host'
% (self.num_vms_per_host, self.machine_type)
)
else:
logging.warning(
'Creation failed due to insufficient host capacity. A new host '
'will be created and instance creation will be retried.'
)
with self._lock:
if num_hosts == len(self.host_list):
new_host = AzureDedicatedHost(
self.name,
self.region,
self.resource_group,
self.host_series_sku,
self.availability_zone,
)
self.host_list.append(new_host)
new_host.Create()
self.host = self.host_list[-1]
raise errors.Resource.RetryableCreationError()
elif not self.use_dedicated_host and 'AllocationFailed' in stderr:
raise errors.Benchmarks.InsufficientCapacityCloudFailure(stderr)
elif (
not self.use_dedicated_host
and 'OverconstrainedZonalAllocationRequest' in stderr
):
raise errors.Benchmarks.UnsupportedConfigError(stderr)
elif _SKU_NOT_AVAILABLE in stderr:
raise errors.Benchmarks.UnsupportedConfigError(stderr)
else:
raise errors.Resource.CreationError(stderr)