Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c8de859
Add test for latest profile
qwordy Jan 6, 2020
428a4f2
Merge branch 'dev' of https://github.com/Azure/azure-cli into imagebu…
qwordy Jan 7, 2020
6735e4f
Merge branch 'dev' of https://github.com/Azure/azure-cli into imagebu…
qwordy Jan 13, 2020
95c68a3
Merge branch 'dev' of https://github.com/Azure/azure-cli into imagebu…
qwordy Jan 15, 2020
448b7b3
[Compute] image template create: add --customize and --distribute
qwordy Jan 15, 2020
782c901
Merge branch 'dev' of https://github.com/Azure/azure-cli into imagebu…
qwordy Jan 15, 2020
67d1b0c
Add history
qwordy Jan 15, 2020
e52f447
Fix style
qwordy Jan 15, 2020
01efbdb
Update test
qwordy Jan 16, 2020
07c00c0
merge
qwordy Feb 28, 2020
a4aa547
rename template to builder
qwordy Mar 1, 2020
57198e5
update help
qwordy Mar 1, 2020
815a91d
add image_template
qwordy Mar 4, 2020
8f8a648
Merge branch 'dev' of https://github.com/Azure/azure-cli into imagebu…
qwordy Mar 4, 2020
29aba58
--image-template
qwordy Mar 4, 2020
50c79dc
Merge branch 'dev' of https://github.com/Azure/azure-cli into imagebu…
qwordy Mar 5, 2020
35fd323
test
qwordy Mar 5, 2020
ef13ba5
remove --customize and --distribute
qwordy Mar 5, 2020
3bd036e
try-catch json error
qwordy Mar 5, 2020
ba7181c
help
qwordy Mar 5, 2020
0ed0d23
fix style
qwordy Mar 5, 2020
785855a
fix a bug; update help
qwordy Mar 5, 2020
c88fda4
test of local file
qwordy Mar 5, 2020
7f9aaf6
Add example
qwordy Mar 5, 2020
8c1b812
error handle
qwordy Mar 5, 2020
b7ce361
help
qwordy Mar 6, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 44 additions & 44 deletions src/azure-cli/azure/cli/command_modules/vm/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,12 @@
short-summary: List custom VM images.
"""

helps['image template'] = """
helps['image builder'] = """
type: group
short-summary: Manage and build image builder templates.
"""

helps['image template create'] = """
helps['image builder create'] = """
type: command
short-summary: Create an image builder template.
parameters:
Expand All @@ -180,7 +180,7 @@
scripts="https://my-script-url.net/customize_script.sh"
imagesource="Canonical:UbuntuServer:18.04-LTS:18.04.201903060"

az image template create --image-source $imagesource -n mytemplate -g my-group \\
az image builder create --image-source $imagesource -n mytemplate -g my-group \\
--scripts $scripts --managed-image-destinations image_1=westus \\
--shared-image-destinations my_shared_gallery/linux_image_def=westus,brazilsouth

Expand All @@ -192,171 +192,171 @@

# create and update template object in local cli cache. Defers put request to ARM
# Cache object ttl set via az configure.
az image template create --image-source $imagesource -n mytemplate \\
az image builder create --image-source $imagesource -n mytemplate \\
-g my-group --scripts $script --defer

# add customizers
az image template customizer add -n mytemplate -g my-group \\
az image builder customizer add -n mytemplate -g my-group \\
--customizer-name my-pwsh-script --exit-codes 0 1 --inline-script \\
"mkdir c:\\buildActions" "echo Azure-Image-Builder-Was-Here \\
> c:\\buildActions\\Output.txt" --type powershell --defer

az image template customizer add -n mytemplate -g my-group \\
az image builder customizer add -n mytemplate -g my-group \\
--customizer-name my-file-customizer --type file \\
--file-source "https://my-file-source.net/file.txt" \\
--dest-path "c:\\buildArtifacts\\file.txt" --defer

# add distributors
az image template output add -n mytemplate -g my-group --is-vhd \\
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 template output add -n mytemplate -g my-group \\
az image builder output add -n mytemplate -g my-group \\
--output-name my-win-image-managed --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 template update -n mytemplate -g my-group
az image builder update -n mytemplate -g my-group
"""

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

helps['image template customizer add'] = """
helps['image builder customizer add'] = """
type: command
short-summary: Add an image builder customizer to an image builder template.
long-summary: Must be used with --defer
examples:
- name: Add an inline shell customizer to an image template in the cli object cache
text: |
az image template customizer add -n mytemplate -g my-group \\
az image builder customizer add -n mytemplate -g my-group \\
--inline-script "sudo mkdir /buildArtifacts" \\
"sudo cp /tmp/index.html /buildArtifacts/index.html" \\
--customizer-name shell-script-inline --type shell --defer

- name: Add a file customizer to an image template in the cli object cache
text: |
az image template customizer add -n mytemplate -g my-group \\
az image builder customizer add -n mytemplate -g my-group \\
--customizer-name my-file --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 template customizer add -n mytemplate -g my-group \\
az image builder customizer add -n mytemplate -g my-group \\
--customizer-name shell-script-url \\
--restart-check-command "echo Azure-Image-Builder-Restarted-the-VM > \\
c:\\buildArtifacts\\restart.txt" \\
--type windows-restart --restart-timeout 10m --defer

"""

helps['image template customizer clear'] = """
helps['image builder customizer clear'] = """
type: command
short-summary: Remove all image builder customizers from an image builder template.
long-summary: Must be used with --defer
"""

helps['image template customizer remove'] = """
helps['image builder customizer remove'] = """
type: command
short-summary: Remove an image builder customizer from an image builder template.
long-summary: Must be used with --defer
"""

helps['image template delete'] = """
helps['image builder delete'] = """
type: command
short-summary: Delete image builder template.
"""

helps['image template list'] = """
helps['image builder list'] = """
type: command
short-summary: List image builder templates.
"""

helps['image template output'] = """
helps['image builder output'] = """
type: group
short-summary: Manage image builder template output distributors.
long-summary: >
A customized image can be distributed as a managed image,
a shared image in a shared image gallery (SIG), or as a VHD blob.
"""

helps['image template output add'] = """
helps['image builder output add'] = """
type: command
short-summary: Add an image builder output distributor to an image builder template.
long-summary: Must be used with --defer. The output distributor can be a managed image, a gallery image, or as a VHD blob.
examples:
- name: Add a managed image distributor to an image template in the cli object cache. Specify a run output name.
text: |
az image template output add -n mytemplate -g my-group \\
az image builder output add -n mytemplate -g my-group \\
--managed-image my_desired_image_name --output-name managed_image_run_01 --defer

- name: Add a shared image gallery distributor to an image template in the cli object cache. Specify its replication regions.
text: |
az image template output add -n mytemplate -g my-group --gallery-name my_shared_gallery \\
az image builder output add -n mytemplate -g my-group --gallery-name my_shared_gallery \\
--gallery-replication-regions westus brazilsouth \\
--gallery-image-definition linux_image_def --defer

- name: Add a VHD distributor to an image template in the cli object cache.
text: |
az image template output add -n mytemplate -g my-group \\
az image builder output add -n mytemplate -g my-group \\
--output-name my_vhd_image --is-vhd --defer

"""

helps['image template output clear'] = """
helps['image builder output clear'] = """
type: command
short-summary: Remove all image builder output distributors from an image builder template.
long-summary: Must be used with --defer
"""

helps['image template output remove'] = """
helps['image builder output remove'] = """
type: command
short-summary: Remove an image builder output distributor from an image builder template.
long-summary: Must be used with --defer
"""

helps['image template run'] = """
helps['image builder run'] = """
type: command
short-summary: Build an image builder template.
examples:
- name: Start a template build run and then wait for it to finish.
text: |
az image template run -n mytemplate -g my-group --no-wait
az image builder run -n mytemplate -g my-group --no-wait

az image template wait -n mytemplate -g aibmdi \\
az image builder wait -n mytemplate -g aibmdi \\
--custom "lastRunStatus.runState!='running'"

az image template show -n mytemplate -g my-group
az image builder show -n mytemplate -g my-group
"""

helps['image template show'] = """
helps['image builder show'] = """
type: command
short-summary: Show an image builder template.
examples:
- name: Show an image builder template (autogenerated)
text: |
az image template show --name mytemplate --resource-group my-group
az image builder show --name mytemplate --resource-group my-group
crafted: true
"""

helps['image template show-runs'] = """
helps['image builder show-runs'] = """
type: command
short-summary: Show an image builder template's run outputs.
examples:
- name: Run a template build run and then view its run outputs.
text: |
az image template run -n mytemplate -g my-group --no-wait
az image builder run -n mytemplate -g my-group --no-wait

az image template wait -n mytemplate -g aibmdi \\
az image builder wait -n mytemplate -g aibmdi \\
--custom "lastRunStatus.runState!='running'"

az image template show-runs -n mytemplate -g my-group
az image builder show-runs -n mytemplate -g my-group
"""

helps['image template update'] = """
helps['image builder update'] = """
type: command
short-summary: Update an image builder template.
long-summary: >
Expand All @@ -367,33 +367,33 @@
examples:
- name: |
Create a template resource from a template object in the cli cache.
See "az image template create / output add / customizer add --help" and "az cache -h" for more information
See "az image builder create / output add / customizer add --help" and "az cache -h" for more information
text: |
# create and write template object to local cli cache
az image template create --image-source {image_source} -n mytemplate -g my-group \\
az image builder create --image-source {image_source} -n mytemplate -g my-group \\
--scripts {script} --managed-image-destinations image_1=westus --defer

# add customizers and outputs to local cache template object via az image template output / customizer add
# one can also update cache object properties through generic update options, such as: --set
az image template output add -n mytemplate -g my-group --output-name my-win-image-managed \\
az image builder output add -n mytemplate -g my-group --output-name my-win-image-managed \\
--artifact-tags "is_vhd=False" --managed-image winImage --managed-image-location eastus --defer

# send template create request to azure to create template resource
az image template update -n mytemplate -g my-group
az image builder update -n mytemplate -g my-group
"""

helps['image template wait'] = """
helps['image builder wait'] = """
type: command
short-summary: Place the CLI in a waiting state until a condition of the template is met.
examples:
- name: Start a template build run and then wait for it to finish.
text: |
az image template run -n mytemplate -g my-group --no-wait
az image builder run -n mytemplate -g my-group --no-wait

az image template wait -n mytemplate -g aibmdi \\
az image builder wait -n mytemplate -g aibmdi \\
--custom "lastRunStatus.runState!='running'"

az image template show -n mytemplate -g my-group
az image builder show -n mytemplate -g my-group
"""

helps['image update'] = """
Expand Down
67 changes: 45 additions & 22 deletions src/azure-cli/azure/cli/command_modules/vm/_image_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
# i.e something like image_builder/_client_factory image_builder/commands.py image_builder/_params.py

import re
import json
from json import JSONDecodeError
from enum import Enum


Expand Down Expand Up @@ -374,12 +376,16 @@ def create_image_template( # pylint: disable=too-many-locals
cmd, client, resource_group_name, image_template_name, location=None,
source_dict=None, scripts_list=None, destinations_lists=None, build_timeout=None, tags=None,
source=None, scripts=None, checksum=None, managed_image_destinations=None, # pylint: disable=unused-argument
shared_image_destinations=None, no_wait=False): # pylint: disable=unused-argument, too-many-locals
shared_image_destinations=None, no_wait=False, customize=None, distribute=None, image_template=None): # pylint: disable=unused-argument, too-many-locals
from azure.mgmt.imagebuilder.models import (ImageTemplate, ImageTemplateSharedImageVersionSource,
ImageTemplatePlatformImageSource, ImageTemplateIsoSource, ImageTemplateManagedImageSource, # pylint: disable=line-too-long
ImageTemplateShellCustomizer, ImageTemplatePowerShellCustomizer,
ImageTemplateManagedImageDistributor, ImageTemplateSharedImageDistributor) # pylint: disable=line-too-long

if image_template is not None:

return

template_source, template_scripts, template_destinations = None, [], []

# create image template source settings
Expand All @@ -394,29 +400,46 @@ def create_image_template( # pylint: disable=too-many-locals

# create image template customizer settings
# Script structure can be found in _parse_script's function definition
for script in scripts_list:
script.pop("is_url")
script["script_uri"] = script.pop("script")

if script["type"] == ScriptType.SHELL:
template_scripts.append(ImageTemplateShellCustomizer(**script))
elif script["type"] == ScriptType.POWERSHELL:
template_scripts.append(ImageTemplatePowerShellCustomizer(**script))
else: # Should never happen
logger.debug("Script %s has type %s", script["script"], script["type"])
raise CLIError("Script {} has an invalid type.".format(script["script"]))
if customize is not None:
if scripts_list:
raise CLIError('usage error: Do not use --scripts and --customize together')
try:
template_scripts = json.loads(customize)
except JSONDecodeError:
raise CLIError('usage error: JSON decode error in --customize')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

show error stacktrace to user

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good advice

else:
for script in scripts_list:
script.pop("is_url")
script["script_uri"] = script.pop("script")

if script["type"] == ScriptType.SHELL:
template_scripts.append(ImageTemplateShellCustomizer(**script))
elif script["type"] == ScriptType.POWERSHELL:
template_scripts.append(ImageTemplatePowerShellCustomizer(**script))
else: # Should never happen
logger.debug("Script %s has type %s", script["script"], script["type"])
raise CLIError("Script {} has an invalid type.".format(script["script"]))

# create image template distribution / destination settings
for dest_type, rid, loc_info in destinations_lists:
parsed = parse_resource_id(rid)
if dest_type == _DestType.MANAGED_IMAGE:
template_destinations.append(ImageTemplateManagedImageDistributor(
image_id=rid, location=loc_info, run_output_name=parsed['name']))
elif dest_type == _DestType.SHARED_IMAGE_GALLERY:
template_destinations.append(ImageTemplateSharedImageDistributor(
gallery_image_id=rid, replication_regions=loc_info, run_output_name=parsed['child_name_1']))
else:
logger.info("No applicable destination found for destination %s", str(tuple([dest_type, rid, loc_info])))
if distribute is not None:
if destinations_lists:
raise CLIError('usage error: Do not use (--managed-image-destinations | --shared-image-destinations) and --distribute together')
try:
template_destinations = json.loads(distribute)
except JSONDecodeError:
raise CLIError('usage error: JSON decode error in --distribute')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls append error stacktrace to usre


else:
for dest_type, rid, loc_info in destinations_lists:
parsed = parse_resource_id(rid)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is rid validated at above?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. The code leaves the work to server side.

if dest_type == _DestType.MANAGED_IMAGE:
template_destinations.append(ImageTemplateManagedImageDistributor(
image_id=rid, location=loc_info, run_output_name=parsed['name']))
elif dest_type == _DestType.SHARED_IMAGE_GALLERY:
template_destinations.append(ImageTemplateSharedImageDistributor(
gallery_image_id=rid, replication_regions=loc_info, run_output_name=parsed['child_name_1']))
else:
logger.info("No applicable destination found for destination %s", str(tuple([dest_type, rid, loc_info])))

image_template = ImageTemplate(source=template_source, customize=template_scripts, distribute=template_destinations,
location=location, build_timeout_in_minutes=build_timeout, tags=(tags or {}))
Expand Down
Loading