diff --git a/src/azure-cli/azure/cli/command_modules/storage/_help.py b/src/azure-cli/azure/cli/command_modules/storage/_help.py index 300996fea6e..ad25c65ae12 100644 --- a/src/azure-cli/azure/cli/command_modules/storage/_help.py +++ b/src/azure-cli/azure/cli/command_modules/storage/_help.py @@ -1214,6 +1214,8 @@ text: az storage blob sync -c mycontainer -s "path/to/file" -d NewBlob - name: Sync a directory to a container. text: az storage blob sync -c mycontainer --account-name mystorageccount --account-key 00000000 -s "path/to/directory" + - name: Sync a directory to a container with azcopy options pass-through (in this case capping the upload bandwith to 20 MBit/s). + text: az storage blob sync -c mycontainer --account-name mystorageccount --account-key 00000000 -s "path/to/directory" -- --cap-mbps=20 """ helps['storage blob upload'] = """ diff --git a/src/azure-cli/azure/cli/command_modules/storage/_params.py b/src/azure-cli/azure/cli/command_modules/storage/_params.py index 1bc14abb5ab..b2c43a08139 100644 --- a/src/azure-cli/azure/cli/command_modules/storage/_params.py +++ b/src/azure-cli/azure/cli/command_modules/storage/_params.py @@ -1434,6 +1434,9 @@ def load_arguments(self, _): # pylint: disable=too-many-locals, too-many-statem c.argument('exclude_pattern', exclude_pattern_type) c.argument('include_pattern', include_pattern_type) c.argument('exclude_path', exclude_path_type) + c.positional('extra_options', nargs='*', is_experimental=True, default=[], + help="Other options which will be passed through to azcopy as it is. " + "Please put all the extra options after a `--`") with self.argument_context('storage container') as c: t_public_access = self.get_sdk('_models#PublicAccess', resource_type=ResourceType.DATA_STORAGE_BLOB) diff --git a/src/azure-cli/azure/cli/command_modules/storage/_params_azure_stack.py b/src/azure-cli/azure/cli/command_modules/storage/_params_azure_stack.py index de4e248f161..95690f5c662 100644 --- a/src/azure-cli/azure/cli/command_modules/storage/_params_azure_stack.py +++ b/src/azure-cli/azure/cli/command_modules/storage/_params_azure_stack.py @@ -696,6 +696,9 @@ def load_arguments(self, _): # pylint: disable=too-many-locals, too-many-statem c.argument('exclude_pattern', exclude_pattern_type) c.argument('include_pattern', include_pattern_type) c.argument('exclude_path', exclude_path_type) + c.positional('extra_options', nargs='*', is_experimental=True, default=[], + help="Other options which will be passed through to azcopy as it is. " + "Please put all the extra options after a `--`") with self.argument_context('storage container') as c: from .sdkutil import get_container_access_type_names diff --git a/src/azure-cli/azure/cli/command_modules/storage/linter_exclusions.yml b/src/azure-cli/azure/cli/command_modules/storage/linter_exclusions.yml index 9ba27511279..dc2a40dc610 100644 --- a/src/azure-cli/azure/cli/command_modules/storage/linter_exclusions.yml +++ b/src/azure-cli/azure/cli/command_modules/storage/linter_exclusions.yml @@ -20,4 +20,9 @@ storage copy: extra_options: rule_exclusions: - no_positional_parameters +storage blob sync: + parameters: + extra_options: + rule_exclusions: + - no_positional_parameters ... \ No newline at end of file diff --git a/src/azure-cli/azure/cli/command_modules/storage/operations/azcopy.py b/src/azure-cli/azure/cli/command_modules/storage/operations/azcopy.py index f32b36f9498..756f8e0fac0 100644 --- a/src/azure-cli/azure/cli/command_modules/storage/operations/azcopy.py +++ b/src/azure-cli/azure/cli/command_modules/storage/operations/azcopy.py @@ -87,7 +87,7 @@ def storage_fs_directory_copy(cmd, source, destination, recursive=None, **kwargs def storage_blob_sync(cmd, client, source, destination, delete_destination='true', exclude_pattern=None, - include_pattern=None, exclude_path=None): + include_pattern=None, exclude_path=None, extra_options=None): azcopy = _azcopy_blob_client(cmd, client) flags = [] if delete_destination is not None: @@ -98,6 +98,8 @@ def storage_blob_sync(cmd, client, source, destination, delete_destination='true flags.append('--exclude-pattern=' + exclude_pattern) if exclude_path is not None: flags.append('--exclude-path=' + exclude_path) + if extra_options is not None: + flags.extend(extra_options) sas_token = client.sas_token diff --git a/src/azure-cli/azure/cli/command_modules/storage/tests/latest/test_storage_azcopy_scenarios.py b/src/azure-cli/azure/cli/command_modules/storage/tests/latest/test_storage_azcopy_scenarios.py index 92e4dc1f4db..02b6ffa1048 100644 --- a/src/azure-cli/azure/cli/command_modules/storage/tests/latest/test_storage_azcopy_scenarios.py +++ b/src/azure-cli/azure/cli/command_modules/storage/tests/latest/test_storage_azcopy_scenarios.py @@ -112,6 +112,8 @@ def test_storage_blob_azcopy_sync_oauth(self, storage_account, test_dir): # sync directory self.oauth_cmd('storage blob sync -s "{}" -c {} --account-name {}'.format( test_dir, container, storage_account)) + self.oauth_cmd('storage blob sync -s "{}" -c {} --account-name {} -- --cap-mbps=2'.format( + test_dir, container, storage_account)) self.oauth_cmd('storage blob list -c {} --account-name {}'.format( container, storage_account), checks=JMESPathCheck('length(@)', 41))