Skip to content

Commit

Permalink
add output for repo build and bake yaml export
Browse files Browse the repository at this point in the history
  • Loading branch information
colbylwilliams committed Oct 14, 2022
1 parent 537ad7d commit e3640e4
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 48 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Microsoft Azure CLI Custom Image Helper 'az' Extension adds useful "utilities" f
To install the Azure CLI Custom Image Helper extension, simply run the following command:

```sh
az extension add --source https://github.com/colbylwilliams/az-bake/releases/latest/download/bake-0.0.20-py3-none-any.whl -y
az extension add --source https://github.com/colbylwilliams/az-bake/releases/latest/download/bake-0.0.21-py3-none-any.whl -y
```

### Update
Expand Down
5 changes: 5 additions & 0 deletions bake/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
Release History
===============

0.0.21
++++++
+ Add bake yaml commands
* Add output to bake repo to track packer

0.0.20
++++++
+ Try VS images
Expand Down
71 changes: 62 additions & 9 deletions bake/azext_bake/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,69 @@
short-summary: Create and manage sandboxes.
"""

# helps['bake sandbox create'] = """
# type: command
# short-summary: Create a sandbox.
# examples:
# - name: Create a sandbox.
# text: az bake sandbox create -n mySandbox -l westus2 -p myPrefix
# - name: Create a sandbox with a custom templates.json file.
# text: az bake sandbox create -n mySandbox -l westus2 -p myPrefix --templates-url
# """
helps['bake sandbox create'] = """
type: command
short-summary: Create a sandbox.
examples:
- name: Create a sandbox.
text: az bake sandbox create -sb mySandbox -n myPrefix
"""

helps['bake sandbox validate'] = """
type: command
short-summary: Validate a sandbox.
examples:
- name: Validate a sandbox.
text: az bake sandbox validate -sb mySandbox
"""

helps['bake repo'] = """
type: group
short-summary: Configure, validate, and bake images in a repo.
"""

helps['bake repo'] = """
type: command
short-summary: Bake all images in a repo.
examples:
- name: Build all the images in a repo.
text: az bake repo -r .
"""

helps['bake repo validate'] = """
type: command
short-summary: Validate a repo.
examples:
- name: Validate a repo.
text: az bake repo validate -r .
"""


helps['bake yaml'] = """
type: group
short-summary: Export and validate bake.yaml files.
"""

helps['bake yaml export'] = """
type: command
short-summary: Export a bake.yaml file.
examples:
- name: Export a bake.yaml file.
text: az bake yaml export -sb MySandbox -g /My/Gallery/Resource/ID
"""

helps['bake yaml validate'] = """
type: command
short-summary: Validate a bake.yaml file.
examples:
- name: Validate a bake.yaml file.
text: az bake yaml validate -f ./bake.yaml
"""

helps['bake _builder'] = """
type: group
short-summary: Used by the builder container to execute packer.
"""

# ----------------
# az bake repo
Expand Down
74 changes: 43 additions & 31 deletions bake/azext_bake/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Licensed under the MIT License.
# ------------------------------------

from argcomplete.completers import DirectoriesCompleter, FilesCompleter
from azure.cli.core.commands.parameters import (
file_type, get_location_type, get_resource_group_completion_list,
tags_type)
Expand All @@ -12,7 +13,8 @@
from ._validators import (bake_source_version_validator,
gallery_resource_id_validator, image_names_validator,
repository_path_validator,
sandbox_resource_group_name_validator)
sandbox_resource_group_name_validator,
yaml_out_validator)

# get_resource_group_completion_list,)

Expand All @@ -27,48 +29,32 @@ def load_arguments(self, _):
# )

sandbox_resource_group_name_type = CLIArgumentType(
options_list=['--sandbox', '-sb', '-g'],
completer=get_resource_group_completion_list,
# id_part='resource_group',
help="Name of the sandbox resource group. You can configure the default using `az configure --defaults bake-sandbox=<name>`",
configured_default='bake-sandbox',
validator=sandbox_resource_group_name_validator,
options_list=['--sandbox', '-sb', '-g'], configured_default='bake-sandbox',
completer=get_resource_group_completion_list, validator=sandbox_resource_group_name_validator,
help='Name of the sandbox resource group. You can configure the default using `az configure --defaults bake-sandbox=<name>`'
)

gallery_resource_id_type = CLIArgumentType(
options_list=['--gallery', '-r'],
completer=get_resource_group_completion_list,
# id_part='name',
help="Resource Id of a Azure Compute Gallery. You can configure the default using `az configure --defaults bake-gallery=<id>`",
configured_default='bake-gallery',
validator=gallery_resource_id_validator,
options_list=['--gallery', '-r'], configured_default='bake-gallery',
completer=get_resource_group_completion_list, validator=gallery_resource_id_validator,
help='Resource Id of a Azure Compute Gallery. You can configure the default using `az configure --defaults bake-gallery=<id>`'
)

# yaml_outfile_type validator also validates yaml_outdir_type and yaml_stdout_type
yaml_outfile_type = CLIArgumentType(options_list=['--outfile'], completer=FilesCompleter(), validator=yaml_out_validator, help='When set, saves the output as the specified file path.')
yaml_outdir_type = CLIArgumentType(options_list=['--outdir'], completer=DirectoriesCompleter(), help='When set, saves the output at the specified directory.')
yaml_stdout_type = CLIArgumentType(options_list=['--stdout'], action='store_true', help='When set, prints all output to stdout instead of corresponding files.')

with self.argument_context('bake upgrade') as c:
c.argument('version', options_list=['--version', '-v'], help='Version (tag). Default: latest stable.',
validator=bake_source_version_validator, completer=get_version_completion_list)
c.argument('prerelease', options_list=['--pre'], action='store_true',
help='Update to the latest template prerelease version.')

for scope in ['bake image', 'bake repo', 'bake _builder', 'bake sandbox validate']:
with self.argument_context(scope) as c:
c.ignore('sandbox')
c.ignore('gallery')

for scope in ['bake image', 'bake _builder']:
with self.argument_context(scope) as c:
c.ignore('image')

for scope in ['bake image', 'bake sandbox']:
with self.argument_context(scope) as c:
c.argument('sandbox_resource_group_name', sandbox_resource_group_name_type)

for scope in ['bake image', 'bake sandbox validate']:
with self.argument_context(scope) as c:
c.argument('gallery_resource_id', gallery_resource_id_type)

# sandbox create uses a command level validator, param validators will be ignored
with self.argument_context('bake sandbox create') as c:
c.argument('sandbox_resource_group_name', sandbox_resource_group_name_type)
c.argument('gallery_resource_id', gallery_resource_id_type)
c.argument('location', get_location_type(self.cli_ctx))
c.argument('tags', tags_type)

Expand Down Expand Up @@ -110,6 +96,12 @@ def load_arguments(self, _):
c.argument('templates_url', arg_group='Advanced', help='URL to custom templates.json file.')
c.argument('template_file', arg_group='Advanced', type=file_type, help='Path to custom sandbox arm/bicep template.')

with self.argument_context('bake sandbox validate') as c:
c.argument('sandbox_resource_group_name', sandbox_resource_group_name_type)
c.argument('gallery_resource_id', gallery_resource_id_type)
c.ignore('sandbox')
c.ignore('gallery')

# bake repo uses a command level validator, param validators will be ignored
with self.argument_context('bake repo') as c:
c.argument('repository_path', options_list=['--repo-path', '-r'], type=file_type,
Expand All @@ -121,16 +113,36 @@ def load_arguments(self, _):
c.argument('repository_token', options_list=['--repo-token'], arg_group='Repo', help='Repository token.')
c.argument('repository_revision', options_list=['--repo-revision'], arg_group='Repo', help='Repository revision.')
c.ignore('is_ci')
c.ignore('repo')
c.ignore('sandbox')
c.ignore('gallery')
c.ignore('images')
c.ignore('repo')

# bake image uses a command level validator, param validators will be ignored
with self.argument_context('bake image') as c:
c.argument('sandbox_resource_group_name', sandbox_resource_group_name_type)
c.argument('gallery_resource_id', gallery_resource_id_type)
c.argument('image_path', options_list=['--image-path', '-i'], type=file_type, help='Path to image to bake.')
c.argument('bake_yaml', options_list=['--bake-yaml', '-b'], type=file_type, help='Path to bake.yaml file.')
c.ignore('sandbox')
c.ignore('gallery')
c.ignore('image')

with self.argument_context('bake yaml export') as c:
c.argument('sandbox_resource_group_name', sandbox_resource_group_name_type)
c.argument('gallery_resource_id', gallery_resource_id_type)
c.argument('outfile', yaml_outfile_type, default='./bake.yml')
c.argument('outdir', yaml_outdir_type)
c.argument('stdout', yaml_stdout_type)
c.ignore('sandbox')
c.ignore('gallery')
c.ignore('images')

with self.argument_context('bake _builder') as c:
c.ignore('in_builder')
c.ignore('sandbox')
c.ignore('gallery')
c.ignore('image')
c.ignore('repo')
c.ignore('storage')
c.ignore('suffix')
20 changes: 20 additions & 0 deletions bake/azext_bake/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,26 @@ def templates_version_validator(cmd, ns):
ns.templates_url = f'https://github.com/colbylwilliams/az-bake/releases/download/{ns.version}/templates.json'


def yaml_out_validator(cmd, ns):
if ns.outfile:
if getattr(ns.outfile, 'is_default', None) is None:
if ns.outdir or ns.stdout:
raise MutuallyExclusiveArgumentError(
'Only use one of --outdir | --outfile | --stdout',
recommendation='Remove all --outdir, --outfile, and --stdout to output a bake.yaml file '
'in the current directory, or only specify --stdout to output to stdout.')
ns.outfile = Path(ns.outfile).resolve()
elif ns.outdir and ns.stdout:
raise MutuallyExclusiveArgumentError(
'Only use one of --outdir | --stdout',
recommendation='Remove all --outdir and --stdout to output a bake.yaml file '
'in the current directory, or only specify --stdout to output to stdout.')
else:
ns.outfile = None
if ns.outdir:
ns.outdir = _validate_dir_path(ns.outdir)


def _validate_object(path, obj, properties, parent_key=None):

key_prefix = f'{parent_key}.' if parent_key else ''
Expand Down
10 changes: 10 additions & 0 deletions bake/azext_bake/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,20 @@ def load_command_table(self, _): # pylint: disable=too-many-statements
with self.command_group('bake repo') as g:
g.custom_command('validate', 'bake_repo_validate', validator=process_bake_repo_validate_namespace)

with self.command_group('bake yaml') as g:
g.custom_command('export', 'bake_yaml_export')
g.custom_command('validate', 'bake_yaml_validate')

# with self.command_group('bake image') as g:
# g.custom_command('test', 'bake_image_test')

with self.command_group('bake _builder') as g:
g.custom_command('build', 'bake_builder_build', validator=builder_validator)

# with self.command_group('bake validate') as g:
# g.custom_command('image', 'bake_validate_image')
# g.custom_command('repo', 'bake_validate_repo', validator=process_bake_repo_validate_namespace)
# g.custom_command('sandbox', 'bake_validate_sandbox')
# g.custom_command('yaml', 'bake_validate_yaml')

# with self.command_group('bake')
59 changes: 54 additions & 5 deletions bake/azext_bake/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
import json
import os

import yaml
from knack.log import get_logger
from knack.util import CLIError

from ._arm import (create_image_definition,
deploy_arm_template_at_resource_group,
ensure_gallery_permissions, get_gallery,
ensure_gallery_permissions, get_arm_output, get_gallery,
get_image_definition, image_version_exists)
from ._github import (get_github_release, get_release_templates,
get_template_url)
Expand Down Expand Up @@ -77,7 +78,14 @@ def bake_builder_build(cmd, in_builder=False, repo=None, storage=None, sandbox=N

save_packer_vars_file(sandbox, gallery, image)

return packer_execute(image)
success = packer_execute(image)

if not success:
raise CLIError('Packer build failed')
else:
logger.info('Packer build succeeded')

return success

# sandbox, gallery, and images come from validator

Expand Down Expand Up @@ -142,11 +150,20 @@ def bake_repo(cmd, repository_path, is_ci=False, image_names=None, sandbox=None,
deployment, outputs = deploy_arm_template_at_resource_group(cmd, sandbox['resourceGroup'],
template_file=template_file, template_uri=template_uri,
parameters=[image_params])
logger.info(f'Finished deploying {image["name"]} builder')
logs = get_arm_output(outputs, 'logs')
portal = get_arm_output(outputs, 'portal')

logger.warning(f'Finished deploying builder for {image["name"]} but packer is still running.')
logger.warning(f'You can check the progress of the packer build:')
logger.warning(f' - Azure CLI: {logs}')
logger.warning(f' - Azure Portal: {portal}')
logger.warning(f'')

deployments.append(deployment)

hook.end(message=' ')
return deployments

return True


def bake_repo_validate(cmd, repository_path, sandbox=None, gallery=None, images=None):
Expand Down Expand Up @@ -196,9 +213,41 @@ def bake_sandbox_create(cmd, location, sandbox_resource_group_name, name_prefix,
template_file=template_file, template_uri=template_uri,
parameters=[params])
logger.info(f'Finished deploying sandbox')
logger.warning(f'Successfully deployed sandbox environment')
logger.warning(f'You can configure it as your default sandbox using `az configure --defaults bake-sandbox={sandbox_resource_group_name}`')

hook.end(message=' ')
return deployment
return True


def bake_yaml_export(cmd, sandbox_resource_group_name, gallery_resource_id, sandbox=None, gallery=None, images=None,
outfile='./bake.yml', outdir=None, stdout=False):
logger.info('Exporting bake.yaml file')

bake_obj = {
'version': 1.0,
'sandbox': sandbox,
'gallery': gallery
}
if images:
bake_obj['images'] = images

if stdout:
print(yaml.safe_dump(bake_obj, default_flow_style=False, sort_keys=False))
elif outfile:
with open(outfile, 'w') as f:
yaml.safe_dump(bake_obj, f, default_flow_style=False, sort_keys=False)
elif outdir:
with open(outdir / 'bake.yml', 'w') as f:
yaml.safe_dump(bake_obj, f, default_flow_style=False, sort_keys=False)

return


def bake_yaml_validate(cmd):
logger.info('Validating bake.yaml file')
return True
# raise CLIError('Not implemented')


def bake_sandbox_validate(cmd, sandbox_resource_group_name, gallery_resource_id=None, sandbox=None, gallery=None):
Expand Down
1 change: 1 addition & 0 deletions bake/azext_bake/templates/builder/builder.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,4 @@ resource group 'Microsoft.ContainerInstance/containerGroups@2021-10-01' = {
}

output logs string = 'az container logs -g ${resourceGroup().name} -n ${validImageName}'
output portal string = 'https://portal.azure.com/#@${tenant().tenantId}${group.id}/containers'
2 changes: 1 addition & 1 deletion bake/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
logger.warn("Wheel is not available, disabling bdist_wheel hook")

# Must match a HISTORY.rst entry.
VERSION = '0.0.20'
VERSION = '0.0.21'

# The full list of classifiers is available at
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
Expand Down
2 changes: 1 addition & 1 deletion builder/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ LABEL maintainer="Microsoft" \
RUN apk add --no-cache packer --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community

# install az-bake
RUN az extension add --source https://github.com/colbylwilliams/az-bake/releases/latest/download/bake-0.0.20-py3-none-any.whl -y
RUN az extension add --source https://github.com/colbylwilliams/az-bake/releases/latest/download/bake-0.0.21-py3-none-any.whl -y

# Terminate container on stop
STOPSIGNAL SIGTERM
Expand Down

0 comments on commit e3640e4

Please sign in to comment.