Skip to content

Commit

Permalink
[Compute] az image builder: Add parameter `--staging-resource-group…
Browse files Browse the repository at this point in the history
…` in `create` command to support custom resource group naming and add subgroup `validator` to manage validate information of template (#23303)
  • Loading branch information
yanzhudd authored Jul 25, 2022
1 parent 32028f9 commit 8226f54
Show file tree
Hide file tree
Showing 18 changed files with 4,014 additions and 1,731 deletions.
89 changes: 67 additions & 22 deletions src/azure-cli/azure/cli/command_modules/vm/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,19 +363,19 @@
- az vm image list
- az vm image show
examples:
- name: Create an image builder template from an UbuntuLTS 18.04 image. Distribute it as a managed image and a shared image gallery image version
- name: Create an image builder template from an UbuntuLTS 18.04 image. Distribute it as a managed image and a shared image gallery image version. Specify the staging resource group id as the image template that will be used to build the image.
text: |
scripts="https://my-script-url.net/customize_script.sh"
imagesource="Canonical:UbuntuServer:18.04-LTS:18.04.201903060"
az image builder create --image-source $imagesource -n mytemplate -g my-group \\
az image builder create --image-source $imagesource -n myTemplate -g myGroup \\
--scripts $scripts --managed-image-destinations image_1=westus \\
--shared-image-destinations my_shared_gallery/linux_image_def=westus,brazilsouth \\
--identity myidentity
--identity myIdentity --staging-resource-group myStagingResourceGroup
- name: Create an image builder template using an image template file.
text: |
az image builder create -g my-group -n mytemplate --image-template filename
az image builder create -g my-group -n myTemplate --image-template filename
- name: >
[Advanced] Create an image template with multiple customizers and distributors using the CLI's object cache via --defer. Supports features such as: customizer and output names, powershell exit codes, inline scripts, windows restart, file customizers, artifact tags and vhd output distributors.
Expand All @@ -385,32 +385,32 @@
# create and update template object in local cli cache. Defers put request to ARM
# Cache object ttl set via az configure.
az image builder create --image-source $imagesource -n mytemplate \\
-g my-group --scripts $script --identity myidentity --defer
az image builder create --image-source $imagesource -n myTemplate \\
-g myGroup --scripts $script --identity myIdentity --defer
# add customizers
az image builder customizer add -n mytemplate -g my-group \\
--customizer-name my-pwsh-script --exit-codes 0 1 --inline-script \\
az image builder customizer add -n myTemplate -g myGroup \\
--customizer-name myPwshScript --exit-codes 0 1 --inline-script \\
"mkdir c:\\buildActions" "echo Azure-Image-Builder-Was-Here \\
> c:\\buildActions\\Output.txt" --type powershell --defer
az image builder customizer add -n mytemplate -g my-group \\
--customizer-name my-file-customizer --type file \\
az image builder customizer add -n myTemplate -g myGroup \\
--customizer-name myFileCustomizer --type file \\
--file-source "https://my-file-source.net/file.txt" \\
--dest-path "c:\\buildArtifacts\\file.txt" --defer
# add distributors
az image builder output add -n mytemplate -g my-group --is-vhd \\
--output-name my-win-image-vhd --artifact-tags "is_vhd=True" --defer
az image builder output add -n myTemplate -g myGroup --is-vhd \\
--output-name myWinImageVhd --artifact-tags "is_vhd=True" --defer
az image builder output add -n mytemplate -g my-group \\
--output-name my-win-image-managed --managed-image winImage \\
az image builder output add -n myTemplate -g myGroup \\
--output-name myWinImageManaged --managed-image winImage \\
--managed-image-location eastus \\
--artifact-tags "is_vhd=False" --defer
# Stop deferring put request to ARM. Create the template from the object cache.
# Cache object will be deleted.
az image builder update -n mytemplate -g my-group
az image builder update -n myTemplate -g myGroup
"""

helps['image builder customizer'] = """
Expand All @@ -425,28 +425,28 @@
examples:
- name: Add an inline shell customizer to an image template in the cli object cache
text: |
az image builder customizer add -n mytemplate -g my-group \\
az image builder customizer add -n myTemplate -g myGroup \\
--inline-script "sudo mkdir /buildArtifacts" \\
"sudo cp /tmp/index.html /buildArtifacts/index.html" \\
--customizer-name shell-script-inline --type shell --defer
--customizer-name shellScriptInline --type shell --defer
- name: Add a file customizer to an image template in the cli object cache
text: |
az image builder customizer add -n mytemplate -g my-group \\
--customizer-name my-file --type file \\
az image builder customizer add -n myTemplate -g myGroup \\
--customizer-name myFile --type file \\
--file-source "https://my-remote-file.html" --dest-path "/tmp/index.html" --defer
- name: Add a windows restart customizer to an image template in the cli object cache
text: |
az image builder customizer add -n mytemplate -g my-group \\
--customizer-name shell-script-url \\
az image builder customizer add -n myTemplate -g myGroup \\
--customizer-name shellScriptUrl \\
--restart-check-command "echo Azure-Image-Builder-Restarted-the-VM > \\
c:\\buildArtifacts\\restart.txt" \\
--type windows-restart --restart-timeout 10m --defer
- name: Add a windows update customizer to an image template in the cli object cache.
text: |
az image builder customizer add -n mytemplate -g my-group --customizer-name win_update --type windows-update --search-criteria IsInstalled=0 --filters "exclude:\\$_.Title -like \\'*Preview*\\'" "include:\\$true" --update-limit 20 --defer
az image builder customizer add -n myTemplate -g myGroup --customizer-name winUpdate --type windows-update --search-criteria IsInstalled=0 --filters "exclude:\\$_.Title -like \\'*Preview*\\'" "include:\\$true" --update-limit 20 --defer
"""

helps['image builder customizer clear'] = """
Expand All @@ -461,6 +461,51 @@
long-summary: Must be used with --defer
"""

helps['image builder validator'] = """
type: group
short-summary: Manage image builder template validate.
"""

helps['image builder validator add'] = """
type: command
short-summary: Add validate to an existing image builder template.
long-summary: Must be used with --defer
examples:
- name: Add validate with continue distribute on failure set to true. If not specified, the default value of continue distribute on failure is false.
If validation fails and this field is set to false, output image(s) will not be distributed.
text: |
az image builder validator add -n myTemplate -g myGroup --continue-distribute-on-failure true --defer
- name: Add validate with source validation only set to true. If not specified, the default value of source validation only is false.
If this field is set to true, the image specified in the source section will directly be validated.
text: |
az image builder validator add -n myTemplate -g myGroup --source-validation-only true --defer
- name: Add validate with source validation only and continue distribute on failure set to false.
text: |
az image builder validator add -n myTemplate -g myGroup --defer
"""

helps['image builder validator remove'] = """
type: command
short-summary: Remove validate from an existing image builder template.
long-summary: Must be used with --defer
examples:
- name: Remove validate from an existing image builder template.
text: |
az image builder validator remove -n myTemplate -g myGroup --defer
"""

helps['image builder validator show'] = """
type: command
short-summary: Show validate of an existing image builder template.
long-summary: Must be used with --defer
examples:
- name: Show validate of an existing image builder template.
text: |
az image builder validator show -n myTemplate -g myGroup --defer
"""

helps['image builder delete'] = """
type: command
short-summary: Delete image builder template.
Expand Down
56 changes: 52 additions & 4 deletions src/azure-cli/azure/cli/command_modules/vm/_image_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from azure.cli.core.commands import cached_get, cached_put
from azure.cli.core.commands.client_factory import get_subscription_id
from azure.cli.core.commands.validators import get_default_location_from_resource_group, validate_tags
from azure.cli.core.azclierror import RequiredArgumentMissingError
from azure.cli.core.azclierror import RequiredArgumentMissingError, ResourceNotFoundError

from azure.cli.command_modules.vm._client_factory import _compute_client_factory
from azure.cli.command_modules.vm._validators import _get_resource_id
Expand Down Expand Up @@ -394,7 +394,8 @@ def create_image_template( # pylint: disable=too-many-locals, too-many-branches
source_dict=None, scripts_list=None, destinations_lists=None, build_timeout=None, tags=None,
source=None, scripts=None, checksum=None, managed_image_destinations=None,
shared_image_destinations=None, no_wait=False, image_template=None, identity=None,
vm_size=None, os_disk_size=None, vnet=None, subnet=None, proxy_vm_size=None, build_vm_identities=None):
vm_size=None, os_disk_size=None, vnet=None, subnet=None, proxy_vm_size=None, build_vm_identities=None,
staging_resource_group=None):
from azure.mgmt.imagebuilder.models import (ImageTemplate, ImageTemplateSharedImageVersionSource,
ImageTemplatePlatformImageSource, ImageTemplateManagedImageSource,
ImageTemplateShellCustomizer, ImageTemplatePowerShellCustomizer,
Expand Down Expand Up @@ -434,6 +435,8 @@ def create_image_template( # pylint: disable=too-many-locals, too-many-branches
content['tags'] = obj['tags']
if 'identity' in obj:
content['identity'] = obj['identity']
if 'staging_resource_group' in obj:
content['staging_resource_group'] = obj['staging_resource_group']
return client.virtual_machine_image_templates.begin_create_or_update(
parameters=content, resource_group_name=resource_group_name, image_template_name=image_template_name)

Expand Down Expand Up @@ -504,9 +507,13 @@ def create_image_template( # pylint: disable=too-many-locals, too-many-branches
raise RequiredArgumentMissingError('Usage error: --proxy-vm-size is only configurable when --subnet is specified.')
vm_profile = ImageTemplateVmProfile(vm_size=vm_size, os_disk_size_gb=os_disk_size, user_assigned_identities=build_vm_identities, vnet_config=vnet_config) # pylint: disable=line-too-long

image_template = ImageTemplate(source=template_source, customize=template_scripts, distribute=template_destinations,
image_template = ImageTemplate(source=template_source, distribute=template_destinations,
location=location, build_timeout_in_minutes=build_timeout, tags=(tags or {}),
identity=identity_body, vm_profile=vm_profile)
identity=identity_body, vm_profile=vm_profile,
staging_resource_group=staging_resource_group)

if len(template_scripts) > 0:
image_template.customize = template_scripts

return cached_put(cmd, client.virtual_machine_image_templates.begin_create_or_update, parameters=image_template,
resource_group_name=resource_group_name, image_template_name=image_template_name)
Expand Down Expand Up @@ -696,4 +703,45 @@ def clear_template_customizer(cmd, client, resource_group_name, image_template_n
return cached_put(cmd, client.virtual_machine_image_templates.begin_create_or_update, parameters=existing_image_template, # pylint: disable=line-too-long
resource_group_name=resource_group_name, image_template_name=image_template_name)


def add_template_validator(cmd, client, resource_group_name, image_template_name,
dis_on_failure=False, source_validation_only=False):
_require_defer(cmd)
from azure.mgmt.imagebuilder.models import ImageTemplatePropertiesValidate

existing_image_template = cached_get(cmd, client.virtual_machine_image_templates.get,
resource_group_name=resource_group_name,
image_template_name=image_template_name)
image_template_properties_validate = ImageTemplatePropertiesValidate(
continue_distribute_on_failure=dis_on_failure, source_validation_only=source_validation_only)
existing_image_template.validate = image_template_properties_validate

return cached_put(cmd, client.virtual_machine_image_templates.begin_create_or_update,
parameters=existing_image_template, resource_group_name=resource_group_name,
image_template_name=image_template_name)


def remove_template_validator(cmd, client, resource_group_name, image_template_name):
_require_defer(cmd)
existing_image_template = cached_get(cmd, client.virtual_machine_image_templates.get,
resource_group_name=resource_group_name,
image_template_name=image_template_name)

if not existing_image_template.validate:
raise ResourceNotFoundError("No validate existing in this image template, no need to remove.")

existing_image_template.validate = None

return cached_put(cmd, client.virtual_machine_image_templates.begin_create_or_update, parameters=existing_image_template, # pylint: disable=line-too-long
resource_group_name=resource_group_name, image_template_name=image_template_name)


def show_template_validator(cmd, client, resource_group_name, image_template_name):
_require_defer(cmd)

existing_image_template = cached_get(cmd, client.virtual_machine_image_templates.get,
resource_group_name=resource_group_name,
image_template_name=image_template_name)
return existing_image_template.validate

# endregion
4 changes: 4 additions & 0 deletions src/azure-cli/azure/cli/command_modules/vm/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ def load_arguments(self, _):
c.argument('build_timeout', type=int, help="The Maximum duration to wait while building the image template, in minutes. Default is 60.")
c.argument('image_template', help='Local path or URL to an image template file. When using --image-template, all other parameters are ignored except -g and -n. Reference: https://docs.microsoft.com/azure/virtual-machines/linux/image-builder-json')
c.argument('identity', nargs='+', help='List of user assigned identities (name or ID, space delimited) of the image template.')
c.argument('staging_resource_group', min_api='2022-02-14', help='The staging resource group id in the same subscription as the image template that will be used to build the image.')

# VM profile
c.argument('vm_size', help='Size of the virtual machine used to build, customize and capture images. Omit or specify empty string to use the default (Standard_D1_v2)')
Expand Down Expand Up @@ -350,6 +351,9 @@ def load_arguments(self, _):
c.argument('file_source', arg_type=ib_file_customizer_type, help="The URI of the file to be downloaded into the image. It can be a github link, SAS URI for Azure Storage, etc.")
c.argument('dest_path', arg_type=ib_file_customizer_type, help="The absolute destination path where the file specified in --file-source will be downloaded to in the image")

with self.argument_context('image builder validator add', min_api='2022-02-14') as c:
c.argument('dis_on_failure', options_list=['--continue-distribute-on-failure', '--dis-on-failure'], arg_type=get_three_state_flag(), help="If validation fails and this parameter is set to false, output image(s) will not be distributed.")
c.argument('source_validation_only', arg_type=get_three_state_flag(), help="If this parameter is set to true, the image specified in the 'source' section will directly be validated. No separate build will be run to generate and then validate a customized image.")
# endregion

# region AvailabilitySets
Expand Down
5 changes: 5 additions & 0 deletions src/azure-cli/azure/cli/command_modules/vm/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,11 @@ def load_command_table(self, _):
g.custom_command('remove', 'remove_template_output', supports_local_cache=True)
g.custom_command('clear', 'clear_template_output', supports_local_cache=True)

with self.command_group('image builder validator', image_builder_image_templates_sdk, custom_command_type=image_builder_custom) as g:
g.custom_command('add', 'add_template_validator', supports_local_cache=True)
g.custom_command('remove', 'remove_template_validator', supports_local_cache=True)
g.custom_show_command('show', 'show_template_validator', supports_local_cache=True)

with self.command_group('snapshot', compute_snapshot_sdk, operation_group='snapshots', min_api='2016-04-30-preview') as g:
g.custom_command('create', 'create_snapshot', validator=process_snapshot_create_namespace, supports_no_wait=True)
g.command('delete', 'begin_delete')
Expand Down
Loading

0 comments on commit 8226f54

Please sign in to comment.