Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extending basic build support #5035

Merged
merged 2 commits into from
Jun 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion src/containerapp-compose/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
Release History
===============

0.2.0
++++++
* Add basic build support for compose services
* Fix bug in specifying memory

0.1.0
++++++
* Initial release.
* Initial release.
100 changes: 54 additions & 46 deletions src/containerapp-compose/azext_containerapp_compose/_monkey_patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

import sys

from knack.log import get_logger
from azure.cli.core.azclierror import AzCLIError

Expand All @@ -16,44 +14,6 @@ def __init__(self, error_msg) -> None:
super().__init__(error_msg, recommendation)


def uncache(exclude):
pkgs = []
for mod in exclude:
pkg = mod.split('.', 1)[0]
pkgs.append(pkg)
to_uncache = []
for mod in sys.modules:
if mod in exclude:
continue
if mod in pkgs:
to_uncache.append(mod)
continue
for pkg in pkgs:
if mod.startswith(pkg + '.'):
to_uncache.append(mod)
break
for mod in to_uncache:
del sys.modules[mod]


# Monkey patch for the PollingAnimation
# removes the spinner and message written to standard out
# which breaks the ability to re-use output from the
# the containerapp compose create command
# example:
# `URL=$(az containerapp compose create -e myenv -g myrg --query [0].properties.configuration.ingress.fqdn -o tsv)`
# In that example, the URL variable would include a number of lines with the polling animation,
# making it difficult to reusue the output from the CLI command.
def tick(self):
self.currTicker += 1
self.currTicker = self.currTicker % len(self.tickers)


# Monkey patch for the PollingAnimation (see above)
def flush(self): # noqa: W0613 pylint: disable=unused-argument
pass


logger = get_logger(__name__)


Expand All @@ -65,12 +25,14 @@ def log_containerapp_extension_required():


try:
from azext_containerapp import custom # pylint: disable=unused-import
from azext_containerapp import _utils # pylint: disable=unused-import
from azext_containerapp import _clients # pylint: disable=unused-import
_clients.PollingAnimation.tick = tick
_clients.PollingAnimation.flush = flush
uncache("azext_containerapp._clients")
from azext_containerapp import custom
from azext_containerapp import _utils
from azext_containerapp._up_utils import (ContainerApp,
ContainerAppEnvironment,
ResourceGroup,
_get_registry_from_app,
_get_registry_details,
) # pylint: disable=unused-import
from azext_containerapp import _clients # pylint: disable=unused-import
from azext_containerapp._clients import ManagedEnvironmentClient # pylint: disable=unused-import
except ModuleNotFoundError:
Expand Down Expand Up @@ -101,6 +63,52 @@ def create_containerapps_compose_environment(cmd,
tags=tags)


def build_containerapp_from_compose_service(cmd,
name,
source,
dockerfile,
resource_group_name,
managed_env,
location,
image,
target_port,
ingress,
registry_server,
registry_user,
registry_pass,
env_vars,
logs_key=None,
logs_customer_id=None):

resource_group = ResourceGroup(cmd, name=resource_group_name, location=location)
env = ContainerAppEnvironment(cmd,
managed_env,
resource_group,
location=location,
logs_key=logs_key,
logs_customer_id=logs_customer_id)
app = ContainerApp(cmd,
name,
resource_group,
None,
image,
env,
target_port,
registry_server,
registry_user,
registry_pass,
env_vars,
ingress)

if not registry_server:
_get_registry_from_app(app, True) # if the app exists, get the registry
_get_registry_details(cmd, app, True) # fetch ACR creds from arguments registry arguments

app.create_acr_if_needed()
app.run_acr_build(dockerfile, source, False)
return app.image, app.registry_server, app.registry_user, app.registry_pass


def create_containerapp_from_service(*args, **kwargs):
return custom.create_containerapp(*args, **kwargs)

Expand Down
44 changes: 39 additions & 5 deletions src/containerapp-compose/azext_containerapp_compose/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
logger = get_logger(__name__)


def resolve_configuration_element_list(compose_service, unsupported_configuration):
def resolve_configuration_element_list(compose_service, unsupported_configuration, area=None):
if area is not None:
compose_service = getattr(compose_service, area)
config_list = []
for configuration_element in unsupported_configuration:
try:
Expand All @@ -27,11 +29,18 @@ def resolve_configuration_element_list(compose_service, unsupported_configuratio


def warn_about_unsupported_build_configuration(compose_service):
unsupported_configuration = ["args", "ssh", "cache_from", "cache_to", "extra_hosts",
"isolation", "labels", "no_cache", "pull", "shm_size",
"target", "secrets", "tags"]
if compose_service.build is not None:
message = f"Build configuration for {compose_service.build.compose_path} is not currently supported."
message += " Work is planned to add that capability."
config_list = resolve_configuration_element_list(compose_service, unsupported_configuration, 'build')
message = "These build configuration settings from the docker-compose file are yet supported."
message += " Currently, we support supplying a build context and optionally target Dockerfile for a service."
message += " See https://aka.ms/containerapp/compose/build_support for more information or to add feedback."
logger.warning(message)
if len(config_list) >= 1:
logger.warning(message)
for item in config_list:
logger.warning(" %s", item)


def warn_about_unsupported_runtime_host_configuration(compose_service):
Expand Down Expand Up @@ -110,6 +119,7 @@ def create_containerapps_from_compose(cmd, # pylint: disable=R0914
from ._monkey_patch import (
create_containerapp_from_service,
create_containerapps_compose_environment,
build_containerapp_from_compose_service,
load_yaml_file,
show_managed_environment)

Expand Down Expand Up @@ -142,6 +152,7 @@ def create_containerapps_from_compose(cmd, # pylint: disable=R0914
message = "Unsupported platform found. "
message += "Azure Container Apps only supports linux/amd64 container images."
raise InvalidArgumentValueError(message)
image = service.image
warn_about_unsupported_elements(service)
logger.info( # pylint: disable=W1203
f"Creating the Container Apps instance for {service_name} under {resource_group_name} in {location}.")
Expand All @@ -161,11 +172,34 @@ def create_containerapps_from_compose(cmd, # pylint: disable=R0914
elif secret_env_ref is not None:
environment = secret_env_ref

if service.build is not None:
logger.warning("Build configuration defined for this service.")
logger.warning("The build will be performed by Azure Container Registry.")
context = service.build.context
dockerfile = "Dockerfile"
if service.build.dockerfile is not None:
dockerfile = service.build.dockerfile
image, registry, registry_username, registry_password = build_containerapp_from_compose_service(
cmd,
service_name,
context,
dockerfile,
resource_group_name,
managed_env,
location,
image,
target_port,
ingress_type,
registry,
registry_username,
registry_password,
environment)

containerapps_from_compose.append(
create_containerapp_from_service(cmd,
service_name,
resource_group_name,
image=service.image,
image=image,
container_name=service.container_name,
managed_env=managed_environment["id"],
ingress=ingress_type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ def clean_up_test_file(filename):

class ContainerappComposePreviewScenarioTest(ScenarioTest):
def setUp(self):
self.cmd("extension add --name containerapp")
self.cmd("extension add --name containerapp --upgrade --yes")
return super().setUp()
4 changes: 2 additions & 2 deletions src/containerapp-compose/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# TODO: Confirm this is the right version number you want and it matches your
# HISTORY.rst entry.
VERSION = '0.1.0'
VERSION = '0.2.0'

# The full list of classifiers is available at
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
Expand All @@ -32,7 +32,7 @@
'License :: OSI Approved :: MIT License',
]

DEPENDENCIES = ['pycomposefile>=0.0.26']
DEPENDENCIES = ['pycomposefile>=0.0.29']

with open('README.rst', 'r', encoding='utf-8') as f:
README = f.read()
Expand Down