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

[ACR] Fix Azure/acr#613: az acr task run: Add dockerfile to source upload if context is local directory #22802

Merged
merged 19 commits into from
Jun 30, 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
3 changes: 3 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acr/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

ACR_RUN_DEFAULT_TIMEOUT_IN_SEC = 60 * 60 # 60 minutes

ALLOWED_TASK_FILE_TYPES = ('.yaml', '.yml', '.toml', '.json', '.sh', '.bash', '.zsh', '.ps1',
'.ps', '.cmd', '.bat', '.ts', '.js', '.php', '.py', '.rb', '.lua')


def get_classic_sku(cmd):
SkuName = cmd.get_models('SkuName')
Expand Down
35 changes: 32 additions & 3 deletions src/azure-cli/azure/cli/command_modules/acr/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@
get_valid_os,
get_valid_architecture,
get_valid_variant,
ACR_NULL_CONTEXT
ACR_NULL_CONTEXT,
ALLOWED_TASK_FILE_TYPES
)
from ._client_factory import cf_acr_registries

from ._validators import validate_docker_file_path

from ._archive_utils import upload_source_code, check_remote_source_code

logger = get_logger(__name__)
Expand Down Expand Up @@ -405,21 +408,47 @@ def get_task_id_from_task_name(cli_ctx, resource_group, registry_name, task_name
)


def prepare_source_location(cmd, source_location, client_registries, registry_name, resource_group_name):
def prepare_source_location(cmd,
source_location,
client_registries,
registry_name,
resource_group_name,
docker_file_path=None):
if not source_location or source_location.lower() == ACR_NULL_CONTEXT:
source_location = None
elif os.path.exists(source_location):
if not os.path.isdir(source_location):
raise CLIError(
"Source location should be a local directory path or remote URL.")

# NOTE: If docker_file_path is not specified, the default is Dockerfile in source_location.
# Otherwise, it's based on current working directory.
if docker_file_path:
if docker_file_path.endswith(ALLOWED_TASK_FILE_TYPES) or docker_file_path == "-":
docker_file_path = ""
else:
validate_docker_file_path(os.path.join(source_location, docker_file_path))
else:
docker_file_path = os.path.join(source_location, "Dockerfile")
if os.path.isfile(docker_file_path):
logger.info("'--file or -f' is not provided. '%s' is used.", docker_file_path)
else:
docker_file_path = ""

tar_file_path = os.path.join(tempfile.gettempdir(
), 'cli_source_archive_{}.tar.gz'.format(uuid.uuid4().hex))

try:
if docker_file_path:
# NOTE: os.path.basename is unable to parse "\" in the file path
docker_file_name = os.path.basename(
docker_file_path.replace("\\", "/"))
else:
docker_file_name = ""

source_location = upload_source_code(
cmd, client_registries, registry_name, resource_group_name,
source_location, tar_file_path, "", "")
source_location, tar_file_path, docker_file_path, docker_file_name)
except Exception as err:
raise CLIError(err)
finally:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import os
from knack.util import CLIError
from knack.log import get_logger
from azure.cli.core.azclierror import InvalidArgumentValueError
from azure.cli.core.azclierror import FileOperationError, InvalidArgumentValueError

BAD_REPO_FQDN = "The positional parameter 'repo_id' must be a fully qualified repository specifier such"\
" as 'MyRegistry.azurecr.io/hello-world'."
Expand Down Expand Up @@ -140,3 +140,8 @@ def validate_repository(namespace):
if ':' in namespace.repository:
raise InvalidArgumentValueError("Parameter 'name' refers to a repository and"
" should not include a tag or digest.")


def validate_docker_file_path(docker_file_path):
if not os.path.isfile(docker_file_path):
raise FileOperationError("Unable to find '{}'.".format(docker_file_path))
14 changes: 10 additions & 4 deletions src/azure-cli/azure/cli/command_modules/acr/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
from ._constants import (
ACR_NULL_CONTEXT,
ACR_TASK_QUICKTASK,
ACR_RUN_DEFAULT_TIMEOUT_IN_SEC
ACR_RUN_DEFAULT_TIMEOUT_IN_SEC,
ALLOWED_TASK_FILE_TYPES
)

logger = get_logger(__name__)
Expand All @@ -37,8 +38,6 @@
IDENTITY_LOCAL_ID = '[system]'
IDENTITY_GLOBAL_REMOVE = '[all]'
DEFAULT_CPU = 2
ALLOWED_TASK_FILE_TYPES = ('.yaml', '.yml', '.toml', '.json', '.sh', '.bash', '.zsh', '.ps1',
'.ps', '.cmd', '.bat', '.ts', '.js', '.php', '.py', '.rb', '.lua')


def acr_task_create(cmd, # pylint: disable=too-many-locals
Expand Down Expand Up @@ -877,7 +876,14 @@ def acr_task_run(cmd, # pylint: disable=too-many-locals
update_trigger_token = base64.b64encode(update_trigger_token.encode()).decode()

task_id = get_task_id_from_task_name(cmd.cli_ctx, resource_group_name, registry_name, task_name)
context_path = prepare_source_location(cmd, context_path, client_registries, registry_name, resource_group_name)
context_path = prepare_source_location(
cmd,
context_path,
client_registries,
registry_name,
resource_group_name,
file
)

timeout = None
task_details = get_task_details_by_name(cmd.cli_ctx, resource_group_name, registry_name, task_name)
Expand Down