Skip to content
Draft
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
58 changes: 58 additions & 0 deletions src/azure-cli/azure/cli/command_modules/appservice/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -1971,6 +1971,64 @@
text: az webapp create-remote-connection --name MyWebApp --resource-group MyResourceGroup
"""

helps['webapp exec'] = """
type: command
short-summary: Open an interactive shell session or run a command in a Linux web app container.
long-summary: |
Interact with your Linux web app container in two modes:
- 'shell' (default): open an interactive shell session in your main app container.
- 'execute': fire-and-forget a command in your main app container; returns immediately, no output.

Only supported for Linux App Service plans.

'shell' mode: Open an interactive shell in your app's main container.
A session ends automatically after 3 hours of inactivity,
and may also end if the underlying instance is reimaged or platform components are updated.

'execute' mode: Fire-and-forget a command in the main app container. A 'succeeded' result means the command was accepted.
It does not confirm the command ran or completed, and no logs, output, or exit code are returned. For immediate output, use 'shell' mode.
The CLI reports failure only if the command (or the shell) could not be started.
This makes execute mode well-suited to background or long-running work.
The process runs detached and lives for the lifetime of the container (or until it finishes on its own).
Use --command to run a single program, e.g. "npm start".
Use --shell-command to run a shell command line where shell operators (|, &&, >, etc.) work, e.g. "cat log.txt | grep error > out.txt".
Check the parameters and examples below, including how to capture output to a file.
examples:
- name: Run a direct command in the container
text: >
az webapp exec -g MyResourceGroup -n MyWebapp --mode execute --command "mkdir /home/site/newdir"
- name: Run a shell command and redirect output to a file
text: >
az webapp exec -g MyResourceGroup -n MyWebapp --mode execute --shell-command "echo hello > /home/LogFiles/out.txt 2>&1"
- name: Run a command in a specific working directory
text: >
az webapp exec -g MyResourceGroup -n MyWebapp --mode execute --cwd /home/site --command "touch newfile.txt"
- name: Run a Python script in the container
text: >
az webapp exec -g MyResourceGroup -n MyWebapp --mode execute --command "python3 /home/site/wwwroot/script.py"
- name: Run a shell command with a non-default shell
text: >
az webapp exec -g MyResourceGroup -n MyWebapp --mode execute --shell /bin/sh --shell-command "echo hi | grep h"
- name: Execute a command on a specific instance
text: >
az webapp exec -g MyResourceGroup -n MyWebapp --mode execute --command "touch newfile.txt" --instance MyInstanceId
- name: Execute a command on all instances
text: >
az webapp exec -g MyResourceGroup -n MyWebapp --mode execute --command "touch newfile.txt" --instance all
- name: Execute a command on a deployment slot
text: >
az webapp exec -g MyResourceGroup -n MyWebapp -s staging --mode execute --command "touch newfile.txt"
- name: Start an interactive shell session with the web app container
text: >
az webapp exec -g MyResourceGroup -n MyWebapp --mode shell
- name: Start an interactive shell session on a specific instance
text: >
az webapp exec -g MyResourceGroup -n MyWebapp --mode shell --instance MyInstanceId
- name: Start an interactive shell session using a specific shell
text: >
az webapp exec -g MyResourceGroup -n MyWebapp --mode shell --shell /bin/sh
"""

helps['webapp delete'] = """
type: command
short-summary: Delete a web app.
Expand Down
30 changes: 30 additions & 0 deletions src/azure-cli/azure/cli/command_modules/appservice/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -1608,3 +1608,33 @@ def load_arguments(self, _):
c.argument('environment_name', help="Name of the environment of static site")
with self.argument_context('staticwebapp enterprise-edge') as c:
c.argument("no_register", help="Don't try to register the Microsoft.CDN provider. Registration can be done manually with: az provider register --wait --namespace Microsoft.CDN. For more details, please review the documentation available at https://go.microsoft.com/fwlink/?linkid=2184995 .", default=False)
with self.argument_context('webapp exec') as c:
c.argument('name', arg_type=webapp_name_arg_type, id_part=None, help='Name of the web app.')
c.argument('exec_command', options_list=['--command'],
help='[Execute mode] A command to run directly in the container, without a shell. '
'Quote the whole command (e.g. --command "python /home/site/app.py --port 8080"). '
'Shell operators (>, |, &&, etc.) are not interpreted - use --shell-command for those. '
'Mutually exclusive with --shell-command.')
c.argument('shell_command', options_list=['--shell-command'],
help='[Execute mode] A command line to run through a shell, so shell operators (|, &&, >, etc.) work '
'(e.g. --shell-command "echo hi > /home/LogFiles/out.txt"). '
'Runs as "<shell> -c <command>"; the shell defaults to '
'/bin/bash and can be overridden with --shell. Mutually exclusive with --command.')
c.argument('mode',
help="Execution mode. 'shell' (default): Starts an interactive shell session with the main "
"web app container. 'execute': Starts command execution and returns immediately without "
"returning command output.",
arg_type=get_enum_type(['shell', 'execute']), default='shell')
c.argument('working_directory', options_list=['--working-directory', '--cwd'],
help="[Execute mode] Working directory for command execution. "
"Defaults to the container's working directory.")
c.argument('instance', options_list=['--instance', '-i'],
help='Webapp instance(s) to target. Specify a comma-separated list of instance IDs '
'(use "az webapp list-instances" to get IDs) or "all" for all instances. Defaults to a random instance. '
'Specifying multiple instances (a comma-separated list or "all") is supported only in \'execute\' mode.')
c.argument('shell', options_list=['--shell'],
help="Absolute path of the shell to use (e.g. /bin/sh); defaults to /bin/bash. "
"In 'shell' mode it is the interactive shell to launch; in 'execute' mode it is "
"the shell used to run --shell-command.")
c.argument('slot', options_list=['--slot', '-s'],
help='Name of the web app slot. Default to the production slot if not specified.')
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,14 @@ def load_command_table(self, _):

logicapp_custom = CliCommandType(operations_tmpl='azure.cli.command_modules.appservice.logicapp.custom#{}')

webapp_exec_custom = CliCommandType(operations_tmpl='azure.cli.command_modules.appservice.webapp_exec#{}')

with self.command_group('webapp', webapp_sdk) as g:
g.custom_command('create', 'create_webapp', exception_handler=ex_handler_factory(), validator=validate_vnet_integration)
g.custom_command('up', 'webapp_up', exception_handler=ex_handler_factory(), validator=validate_webapp_up,
deprecate_info=g.deprecate(redirect='webapp create and webapp deploy'))
g.custom_command('ssh', 'ssh_webapp', exception_handler=ex_handler_factory(), is_preview=True)
g.custom_command('exec', 'webapp_exec', custom_command_type=webapp_exec_custom, exception_handler=ex_handler_factory(), is_preview=True)
g.custom_command('list', 'list_webapp', table_transformer=transform_web_list_output)
g.custom_show_command('show', 'show_app', table_transformer=transform_web_output)
g.custom_command('delete', 'delete_webapp')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
from azure.cli.core.azclierror import (InvalidArgumentValueError, MutuallyExclusiveArgumentError, ResourceNotFoundError,
RequiredArgumentMissingError, ValidationError, CLIInternalError,
UnclassifiedUserFault, AzureResponseError, AzureInternalError,
ArgumentUsageError, FileOperationError)
ArgumentUsageError, FileOperationError, AzureConnectionError)

from .tunnel import TunnelServer

Expand Down
Loading
Loading