We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
add timeout support in image copy command
- If the issue is to do with Azure CLI 2.0 in-particular, create an issue here at [Azure/azure-cli](https://github.com/Azure/azure-cli/issues)

### Extension name (the extension in question)
image-copy-extension

### Description of issue (in as much detail as possible)
src/image-copy/azext_imagecopy/create_target.py

at line 50:
https://github.com/Azure/azure-cli-extensions/blob/master/src/image-copy/azext_imagecopy/create_target.py#L50

we are using hardcoded SAS expiration time 1 hour
expiry = datetime.datetime.utcnow() + datetime.timedelta(hours=1)

This could cause problem as some times the copy take longer than 1 hour. Please consider to add a parameter to the image copy command to add a timeout parameter and use the specified timeout(maybe +5min) to generate the SAS token.
-----



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/image-copy/azext_imagecopy/create_target.py`
Content:
```
1 # --------------------------------------------------------------------------------------------
2 # Copyright (c) Microsoft Corporation. All rights reserved.
3 # Licensed under the MIT License. See License.txt in the project root for license information.
4 # --------------------------------------------------------------------------------------------
5 
6 import datetime
7 import time
8 from azext_imagecopy.cli_utils import run_cli_command, prepare_cli_command
9 from knack.util import CLIError
10 
11 from knack.log import get_logger
12 logger = get_logger(__name__)
13 
14 STORAGE_ACCOUNT_NAME_LENGTH = 24
15 
16 
17 # pylint: disable=too-many-locals
18 def create_target_image(location, transient_resource_group_name, source_type, source_object_name,
19                         source_os_disk_snapshot_name, source_os_disk_snapshot_url, source_os_type,
20                         target_resource_group_name, azure_pool_frequency, tags, target_name, target_subscription,
21                         timeout):
22 
23     random_string = get_random_string(STORAGE_ACCOUNT_NAME_LENGTH - len(location))
24 
25     # create the target storage account. storage account name must be lowercase.
26     logger.warn(
27         "%s - Creating target storage account (can be slow sometimes)", location)
28     target_storage_account_name = location.lower() + random_string
29     cli_cmd = prepare_cli_command(['storage', 'account', 'create',
30                                    '--name', target_storage_account_name,
31                                    '--resource-group', transient_resource_group_name,
32                                    '--location', location,
33                                    '--sku', 'Standard_LRS'],
34                                   subscription=target_subscription)
35 
36     json_output = run_cli_command(cli_cmd, return_as_json=True)
37     target_blob_endpoint = json_output['primaryEndpoints']['blob']
38 
39     # Setup the target storage account
40     cli_cmd = prepare_cli_command(['storage', 'account', 'keys', 'list',
41                                    '--account-name', target_storage_account_name,
42                                    '--resource-group', transient_resource_group_name],
43                                   subscription=target_subscription)
44 
45     json_output = run_cli_command(cli_cmd, return_as_json=True)
46 
47     target_storage_account_key = json_output[0]['value']
48     logger.debug("storage account key: %s", target_storage_account_key)
49 
50     expiry_format = "%Y-%m-%dT%H:%MZ"
51     expiry = datetime.datetime.utcnow() + datetime.timedelta(seconds=timeout)
52     logger.debug("create target storage sas using timeout seconds: %d", timeout)
53 
54     cli_cmd = prepare_cli_command(['storage', 'account', 'generate-sas',
55                                    '--account-name', target_storage_account_name,
56                                    '--account-key', target_storage_account_key,
57                                    '--expiry', expiry.strftime(expiry_format),
58                                    '--permissions', 'aclrpuw', '--resource-types',
59                                    'sco', '--services', 'b', '--https-only'],
60                                   output_as_json=False,
61                                   subscription=target_subscription)
62 
63     sas_token = run_cli_command(cli_cmd)
64     sas_token = sas_token.rstrip("\n\r")  # STRANGE
65     logger.debug("sas token: %s", sas_token)
66 
67     # create a container in the target blob storage account
68     logger.warn(
69         "%s - Creating container in the target storage account", location)
70     target_container_name = 'snapshots'
71     cli_cmd = prepare_cli_command(['storage', 'container', 'create',
72                                    '--name', target_container_name,
73                                    '--account-name', target_storage_account_name],
74                                   subscription=target_subscription)
75 
76     run_cli_command(cli_cmd)
77 
78     # Copy the snapshot to the target region using the SAS URL
79     blob_name = source_os_disk_snapshot_name + '.vhd'
80     logger.warn(
81         "%s - Copying blob to target storage account", location)
82     cli_cmd = prepare_cli_command(['storage', 'blob', 'copy', 'start',
83                                    '--source-uri', source_os_disk_snapshot_url,
84                                    '--destination-blob', blob_name,
85                                    '--destination-container', target_container_name,
86                                    '--account-name', target_storage_account_name,
87                                    '--sas-token', sas_token],
88                                   subscription=target_subscription)
89 
90     run_cli_command(cli_cmd)
91 
92     # Wait for the copy to complete
93     start_datetime = datetime.datetime.now()
94     wait_for_blob_copy_operation(blob_name, target_container_name, target_storage_account_name,
95                                  azure_pool_frequency, location, target_subscription)
96     msg = "{0} - Copy time: {1}".format(
97         location, datetime.datetime.now() - start_datetime)
98     logger.warn(msg)
99 
100     # Create the snapshot in the target region from the copied blob
101     logger.warn(
102         "%s - Creating snapshot in target region from the copied blob", location)
103     target_blob_path = target_blob_endpoint + \
104         target_container_name + '/' + blob_name
105     target_snapshot_name = source_os_disk_snapshot_name + '-' + location
106     cli_cmd = prepare_cli_command(['snapshot', 'create',
107                                    '--resource-group', transient_resource_group_name,
108                                    '--name', target_snapshot_name,
109                                    '--location', location,
110                                    '--source', target_blob_path],
111                                   subscription=target_subscription)
112 
113     json_output = run_cli_command(cli_cmd, return_as_json=True)
114     target_snapshot_id = json_output['id']
115 
116     # Create the final image
117     logger.warn("%s - Creating final image", location)
118     if target_name is None:
119         target_image_name = source_object_name
120         if source_type != 'image':
121             target_image_name += '-image'
122         target_image_name += '-' + location
123     else:
124         target_image_name = target_name
125 
126     cli_cmd = prepare_cli_command(['image', 'create',
127                                    '--resource-group', target_resource_group_name,
128                                    '--name', target_image_name,
129                                    '--location', location,
130                                    '--source', target_blob_path,
131                                    '--os-type', source_os_type,
132                                    '--source', target_snapshot_id],
133                                   tags=tags,
134                                   subscription=target_subscription)
135 
136     run_cli_command(cli_cmd)
137 
138 
139 def wait_for_blob_copy_operation(blob_name, target_container_name, target_storage_account_name,
140                                  azure_pool_frequency, location, subscription):
141     copy_status = "pending"
142     prev_progress = -1
143     while copy_status == "pending":
144         cli_cmd = prepare_cli_command(['storage', 'blob', 'show',
145                                        '--name', blob_name,
146                                        '--container-name', target_container_name,
147                                        '--account-name', target_storage_account_name],
148                                       subscription=subscription)
149 
150         json_output = run_cli_command(cli_cmd, return_as_json=True)
151         copy_status = json_output["properties"]["copy"]["status"]
152         copy_progress_1, copy_progress_2 = json_output["properties"]["copy"]["progress"].split(
153             "/")
154         current_progress = int(
155             int(copy_progress_1) / int(copy_progress_2) * 100)
156 
157         if current_progress != prev_progress:
158             msg = "{0} - Copy progress: {1}%"\
159                 .format(location, str(current_progress))
160             logger.warn(msg)
161 
162         prev_progress = current_progress
163 
164         try:
165             time.sleep(azure_pool_frequency)
166         except KeyboardInterrupt:
167             return
168 
169     if copy_status != 'success':
170         logger.error("The copy operation didn't succeed. Last status: %s", copy_status)
171         raise CLIError('Blob copy failed')
172 
173 
174 def get_random_string(length):
175     import string
176     import random
177     chars = string.ascii_lowercase + string.digits
178     return ''.join(random.choice(chars) for _ in range(length))
179
```

Path: `src/image-copy/setup.py`
Content:
```
1 #!/usr/bin/env python
2 
3 # --------------------------------------------------------------------------------------------
4 # Copyright (c) Microsoft Corporation. All rights reserved.
5 # Licensed under the MIT License. See License.txt in the project root for license information.
6 # --------------------------------------------------------------------------------------------
7 
8 from codecs import open
9 from setuptools import setup, find_packages
10 
11 VERSION = "0.0.8"
12 
13 CLASSIFIERS = [
14     'Development Status :: 4 - Beta',
15     'Intended Audience :: Developers',
16     'Intended Audience :: System Administrators',
17     'Programming Language :: Python',
18     'Programming Language :: Python :: 2',
19     'Programming Language :: Python :: 2.7',
20     'Programming Language :: Python :: 3',
21     'Programming Language :: Python :: 3.4',
22     'Programming Language :: Python :: 3.5',
23     'Programming Language :: Python :: 3.6',
24     'License :: OSI Approved :: MIT License',
25 ]
26 
27 DEPENDENCIES = []
28 
29 setup(
30     name='image-copy-extension',
31     version=VERSION,
32     description='Support for copying managed vm images between regions',
33     long_description='Support for copying managed vm images between regions',
34     license='MIT',
35     author='Tamir Kamara',
36     author_email='tamir.kamara@microsoft.com',
37     url='https://github.com/Azure/azure-cli-extensions',
38     classifiers=CLASSIFIERS,
39     package_data={'azext_imagecopy': ['azext_metadata.json']},
40     packages=find_packages(),
41     install_requires=DEPENDENCIES
42 )
43
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/image-copy/azext_imagecopy/create_target.py b/src/image-copy/azext_imagecopy/create_target.py
--- a/src/image-copy/azext_imagecopy/create_target.py
+++ b/src/image-copy/azext_imagecopy/create_target.py
@@ -168,6 +168,9 @@
 
     if copy_status != 'success':
         logger.error("The copy operation didn't succeed. Last status: %s", copy_status)
+        logger.error("Command run: %s", cli_cmd)
+        logger.error("Command output: %s", json_output)
+
         raise CLIError('Blob copy failed')
 
 
diff --git a/src/image-copy/setup.py b/src/image-copy/setup.py
--- a/src/image-copy/setup.py
+++ b/src/image-copy/setup.py
@@ -8,7 +8,7 @@
 from codecs import open
 from setuptools import setup, find_packages
 
-VERSION = "0.0.8"
+VERSION = "0.0.9"
 
 CLASSIFIERS = [
     'Development Status :: 4 - Beta',

{"golden_diff": "diff --git a/src/image-copy/azext_imagecopy/create_target.py b/src/image-copy/azext_imagecopy/create_target.py\n--- a/src/image-copy/azext_imagecopy/create_target.py\n+++ b/src/image-copy/azext_imagecopy/create_target.py\n@@ -168,6 +168,9 @@\n \n     if copy_status != 'success':\n         logger.error(\"The copy operation didn't succeed. Last status: %s\", copy_status)\n+        logger.error(\"Command run: %s\", cli_cmd)\n+        logger.error(\"Command output: %s\", json_output)\n+\n         raise CLIError('Blob copy failed')\n \n \ndiff --git a/src/image-copy/setup.py b/src/image-copy/setup.py\n--- a/src/image-copy/setup.py\n+++ b/src/image-copy/setup.py\n@@ -8,7 +8,7 @@\n from codecs import open\n from setuptools import setup, find_packages\n \n-VERSION = \"0.0.8\"\n+VERSION = \"0.0.9\"\n \n CLASSIFIERS = [\n     'Development Status :: 4 - Beta',\n", "issue": "add timeout support in image copy command\n- If the issue is to do with Azure CLI 2.0 in-particular, create an issue here at [Azure/azure-cli](https://github.com/Azure/azure-cli/issues)\r\n\r\n### Extension name (the extension in question)\r\nimage-copy-extension\r\n\r\n### Description of issue (in as much detail as possible)\r\nsrc/image-copy/azext_imagecopy/create_target.py\r\n\r\nat line 50:\r\nhttps://github.com/Azure/azure-cli-extensions/blob/master/src/image-copy/azext_imagecopy/create_target.py#L50\r\n\r\nwe are using hardcoded SAS expiration time 1 hour\r\nexpiry = datetime.datetime.utcnow() + datetime.timedelta(hours=1)\r\n\r\nThis could cause problem as some times the copy take longer than 1 hour. Please consider to add a parameter to the image copy command to add a timeout parameter and use the specified timeout(maybe +5min) to generate the SAS token.\r\n-----\r\n\r\n\n", "before_files": [{"content": "# --------------------------------------------------------------------------------------------\n# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See License.txt in the project root for license information.\n# --------------------------------------------------------------------------------------------\n\nimport datetime\nimport time\nfrom azext_imagecopy.cli_utils import run_cli_command, prepare_cli_command\nfrom knack.util import CLIError\n\nfrom knack.log import get_logger\nlogger = get_logger(__name__)\n\nSTORAGE_ACCOUNT_NAME_LENGTH = 24\n\n\n# pylint: disable=too-many-locals\ndef create_target_image(location, transient_resource_group_name, source_type, source_object_name,\n                        source_os_disk_snapshot_name, source_os_disk_snapshot_url, source_os_type,\n                        target_resource_group_name, azure_pool_frequency, tags, target_name, target_subscription,\n                        timeout):\n\n    random_string = get_random_string(STORAGE_ACCOUNT_NAME_LENGTH - len(location))\n\n    # create the target storage account. storage account name must be lowercase.\n    logger.warn(\n        \"%s - Creating target storage account (can be slow sometimes)\", location)\n    target_storage_account_name = location.lower() + random_string\n    cli_cmd = prepare_cli_command(['storage', 'account', 'create',\n                                   '--name', target_storage_account_name,\n                                   '--resource-group', transient_resource_group_name,\n                                   '--location', location,\n                                   '--sku', 'Standard_LRS'],\n                                  subscription=target_subscription)\n\n    json_output = run_cli_command(cli_cmd, return_as_json=True)\n    target_blob_endpoint = json_output['primaryEndpoints']['blob']\n\n    # Setup the target storage account\n    cli_cmd = prepare_cli_command(['storage', 'account', 'keys', 'list',\n                                   '--account-name', target_storage_account_name,\n                                   '--resource-group', transient_resource_group_name],\n                                  subscription=target_subscription)\n\n    json_output = run_cli_command(cli_cmd, return_as_json=True)\n\n    target_storage_account_key = json_output[0]['value']\n    logger.debug(\"storage account key: %s\", target_storage_account_key)\n\n    expiry_format = \"%Y-%m-%dT%H:%MZ\"\n    expiry = datetime.datetime.utcnow() + datetime.timedelta(seconds=timeout)\n    logger.debug(\"create target storage sas using timeout seconds: %d\", timeout)\n\n    cli_cmd = prepare_cli_command(['storage', 'account', 'generate-sas',\n                                   '--account-name', target_storage_account_name,\n                                   '--account-key', target_storage_account_key,\n                                   '--expiry', expiry.strftime(expiry_format),\n                                   '--permissions', 'aclrpuw', '--resource-types',\n                                   'sco', '--services', 'b', '--https-only'],\n                                  output_as_json=False,\n                                  subscription=target_subscription)\n\n    sas_token = run_cli_command(cli_cmd)\n    sas_token = sas_token.rstrip(\"\\n\\r\")  # STRANGE\n    logger.debug(\"sas token: %s\", sas_token)\n\n    # create a container in the target blob storage account\n    logger.warn(\n        \"%s - Creating container in the target storage account\", location)\n    target_container_name = 'snapshots'\n    cli_cmd = prepare_cli_command(['storage', 'container', 'create',\n                                   '--name', target_container_name,\n                                   '--account-name', target_storage_account_name],\n                                  subscription=target_subscription)\n\n    run_cli_command(cli_cmd)\n\n    # Copy the snapshot to the target region using the SAS URL\n    blob_name = source_os_disk_snapshot_name + '.vhd'\n    logger.warn(\n        \"%s - Copying blob to target storage account\", location)\n    cli_cmd = prepare_cli_command(['storage', 'blob', 'copy', 'start',\n                                   '--source-uri', source_os_disk_snapshot_url,\n                                   '--destination-blob', blob_name,\n                                   '--destination-container', target_container_name,\n                                   '--account-name', target_storage_account_name,\n                                   '--sas-token', sas_token],\n                                  subscription=target_subscription)\n\n    run_cli_command(cli_cmd)\n\n    # Wait for the copy to complete\n    start_datetime = datetime.datetime.now()\n    wait_for_blob_copy_operation(blob_name, target_container_name, target_storage_account_name,\n                                 azure_pool_frequency, location, target_subscription)\n    msg = \"{0} - Copy time: {1}\".format(\n        location, datetime.datetime.now() - start_datetime)\n    logger.warn(msg)\n\n    # Create the snapshot in the target region from the copied blob\n    logger.warn(\n        \"%s - Creating snapshot in target region from the copied blob\", location)\n    target_blob_path = target_blob_endpoint + \\\n        target_container_name + '/' + blob_name\n    target_snapshot_name = source_os_disk_snapshot_name + '-' + location\n    cli_cmd = prepare_cli_command(['snapshot', 'create',\n                                   '--resource-group', transient_resource_group_name,\n                                   '--name', target_snapshot_name,\n                                   '--location', location,\n                                   '--source', target_blob_path],\n                                  subscription=target_subscription)\n\n    json_output = run_cli_command(cli_cmd, return_as_json=True)\n    target_snapshot_id = json_output['id']\n\n    # Create the final image\n    logger.warn(\"%s - Creating final image\", location)\n    if target_name is None:\n        target_image_name = source_object_name\n        if source_type != 'image':\n            target_image_name += '-image'\n        target_image_name += '-' + location\n    else:\n        target_image_name = target_name\n\n    cli_cmd = prepare_cli_command(['image', 'create',\n                                   '--resource-group', target_resource_group_name,\n                                   '--name', target_image_name,\n                                   '--location', location,\n                                   '--source', target_blob_path,\n                                   '--os-type', source_os_type,\n                                   '--source', target_snapshot_id],\n                                  tags=tags,\n                                  subscription=target_subscription)\n\n    run_cli_command(cli_cmd)\n\n\ndef wait_for_blob_copy_operation(blob_name, target_container_name, target_storage_account_name,\n                                 azure_pool_frequency, location, subscription):\n    copy_status = \"pending\"\n    prev_progress = -1\n    while copy_status == \"pending\":\n        cli_cmd = prepare_cli_command(['storage', 'blob', 'show',\n                                       '--name', blob_name,\n                                       '--container-name', target_container_name,\n                                       '--account-name', target_storage_account_name],\n                                      subscription=subscription)\n\n        json_output = run_cli_command(cli_cmd, return_as_json=True)\n        copy_status = json_output[\"properties\"][\"copy\"][\"status\"]\n        copy_progress_1, copy_progress_2 = json_output[\"properties\"][\"copy\"][\"progress\"].split(\n            \"/\")\n        current_progress = int(\n            int(copy_progress_1) / int(copy_progress_2) * 100)\n\n        if current_progress != prev_progress:\n            msg = \"{0} - Copy progress: {1}%\"\\\n                .format(location, str(current_progress))\n            logger.warn(msg)\n\n        prev_progress = current_progress\n\n        try:\n            time.sleep(azure_pool_frequency)\n        except KeyboardInterrupt:\n            return\n\n    if copy_status != 'success':\n        logger.error(\"The copy operation didn't succeed. Last status: %s\", copy_status)\n        raise CLIError('Blob copy failed')\n\n\ndef get_random_string(length):\n    import string\n    import random\n    chars = string.ascii_lowercase + string.digits\n    return ''.join(random.choice(chars) for _ in range(length))\n", "path": "src/image-copy/azext_imagecopy/create_target.py"}, {"content": "#!/usr/bin/env python\n\n# --------------------------------------------------------------------------------------------\n# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See License.txt in the project root for license information.\n# --------------------------------------------------------------------------------------------\n\nfrom codecs import open\nfrom setuptools import setup, find_packages\n\nVERSION = \"0.0.8\"\n\nCLASSIFIERS = [\n    'Development Status :: 4 - Beta',\n    'Intended Audience :: Developers',\n    'Intended Audience :: System Administrators',\n    'Programming Language :: Python',\n    'Programming Language :: Python :: 2',\n    'Programming Language :: Python :: 2.7',\n    'Programming Language :: Python :: 3',\n    'Programming Language :: Python :: 3.4',\n    'Programming Language :: Python :: 3.5',\n    'Programming Language :: Python :: 3.6',\n    'License :: OSI Approved :: MIT License',\n]\n\nDEPENDENCIES = []\n\nsetup(\n    name='image-copy-extension',\n    version=VERSION,\n    description='Support for copying managed vm images between regions',\n    long_description='Support for copying managed vm images between regions',\n    license='MIT',\n    author='Tamir Kamara',\n    author_email='tamir.kamara@microsoft.com',\n    url='https://github.com/Azure/azure-cli-extensions',\n    classifiers=CLASSIFIERS,\n    package_data={'azext_imagecopy': ['azext_metadata.json']},\n    packages=find_packages(),\n    install_requires=DEPENDENCIES\n)\n", "path": "src/image-copy/setup.py"}], "after_files": [{"content": "# --------------------------------------------------------------------------------------------\n# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See License.txt in the project root for license information.\n# --------------------------------------------------------------------------------------------\n\nimport datetime\nimport time\nfrom azext_imagecopy.cli_utils import run_cli_command, prepare_cli_command\nfrom knack.util import CLIError\n\nfrom knack.log import get_logger\nlogger = get_logger(__name__)\n\nSTORAGE_ACCOUNT_NAME_LENGTH = 24\n\n\n# pylint: disable=too-many-locals\ndef create_target_image(location, transient_resource_group_name, source_type, source_object_name,\n                        source_os_disk_snapshot_name, source_os_disk_snapshot_url, source_os_type,\n                        target_resource_group_name, azure_pool_frequency, tags, target_name, target_subscription,\n                        timeout):\n\n    random_string = get_random_string(STORAGE_ACCOUNT_NAME_LENGTH - len(location))\n\n    # create the target storage account. storage account name must be lowercase.\n    logger.warn(\n        \"%s - Creating target storage account (can be slow sometimes)\", location)\n    target_storage_account_name = location.lower() + random_string\n    cli_cmd = prepare_cli_command(['storage', 'account', 'create',\n                                   '--name', target_storage_account_name,\n                                   '--resource-group', transient_resource_group_name,\n                                   '--location', location,\n                                   '--sku', 'Standard_LRS'],\n                                  subscription=target_subscription)\n\n    json_output = run_cli_command(cli_cmd, return_as_json=True)\n    target_blob_endpoint = json_output['primaryEndpoints']['blob']\n\n    # Setup the target storage account\n    cli_cmd = prepare_cli_command(['storage', 'account', 'keys', 'list',\n                                   '--account-name', target_storage_account_name,\n                                   '--resource-group', transient_resource_group_name],\n                                  subscription=target_subscription)\n\n    json_output = run_cli_command(cli_cmd, return_as_json=True)\n\n    target_storage_account_key = json_output[0]['value']\n    logger.debug(\"storage account key: %s\", target_storage_account_key)\n\n    expiry_format = \"%Y-%m-%dT%H:%MZ\"\n    expiry = datetime.datetime.utcnow() + datetime.timedelta(seconds=timeout)\n    logger.debug(\"create target storage sas using timeout seconds: %d\", timeout)\n\n    cli_cmd = prepare_cli_command(['storage', 'account', 'generate-sas',\n                                   '--account-name', target_storage_account_name,\n                                   '--account-key', target_storage_account_key,\n                                   '--expiry', expiry.strftime(expiry_format),\n                                   '--permissions', 'aclrpuw', '--resource-types',\n                                   'sco', '--services', 'b', '--https-only'],\n                                  output_as_json=False,\n                                  subscription=target_subscription)\n\n    sas_token = run_cli_command(cli_cmd)\n    sas_token = sas_token.rstrip(\"\\n\\r\")  # STRANGE\n    logger.debug(\"sas token: %s\", sas_token)\n\n    # create a container in the target blob storage account\n    logger.warn(\n        \"%s - Creating container in the target storage account\", location)\n    target_container_name = 'snapshots'\n    cli_cmd = prepare_cli_command(['storage', 'container', 'create',\n                                   '--name', target_container_name,\n                                   '--account-name', target_storage_account_name],\n                                  subscription=target_subscription)\n\n    run_cli_command(cli_cmd)\n\n    # Copy the snapshot to the target region using the SAS URL\n    blob_name = source_os_disk_snapshot_name + '.vhd'\n    logger.warn(\n        \"%s - Copying blob to target storage account\", location)\n    cli_cmd = prepare_cli_command(['storage', 'blob', 'copy', 'start',\n                                   '--source-uri', source_os_disk_snapshot_url,\n                                   '--destination-blob', blob_name,\n                                   '--destination-container', target_container_name,\n                                   '--account-name', target_storage_account_name,\n                                   '--sas-token', sas_token],\n                                  subscription=target_subscription)\n\n    run_cli_command(cli_cmd)\n\n    # Wait for the copy to complete\n    start_datetime = datetime.datetime.now()\n    wait_for_blob_copy_operation(blob_name, target_container_name, target_storage_account_name,\n                                 azure_pool_frequency, location, target_subscription)\n    msg = \"{0} - Copy time: {1}\".format(\n        location, datetime.datetime.now() - start_datetime)\n    logger.warn(msg)\n\n    # Create the snapshot in the target region from the copied blob\n    logger.warn(\n        \"%s - Creating snapshot in target region from the copied blob\", location)\n    target_blob_path = target_blob_endpoint + \\\n        target_container_name + '/' + blob_name\n    target_snapshot_name = source_os_disk_snapshot_name + '-' + location\n    cli_cmd = prepare_cli_command(['snapshot', 'create',\n                                   '--resource-group', transient_resource_group_name,\n                                   '--name', target_snapshot_name,\n                                   '--location', location,\n                                   '--source', target_blob_path],\n                                  subscription=target_subscription)\n\n    json_output = run_cli_command(cli_cmd, return_as_json=True)\n    target_snapshot_id = json_output['id']\n\n    # Create the final image\n    logger.warn(\"%s - Creating final image\", location)\n    if target_name is None:\n        target_image_name = source_object_name\n        if source_type != 'image':\n            target_image_name += '-image'\n        target_image_name += '-' + location\n    else:\n        target_image_name = target_name\n\n    cli_cmd = prepare_cli_command(['image', 'create',\n                                   '--resource-group', target_resource_group_name,\n                                   '--name', target_image_name,\n                                   '--location', location,\n                                   '--source', target_blob_path,\n                                   '--os-type', source_os_type,\n                                   '--source', target_snapshot_id],\n                                  tags=tags,\n                                  subscription=target_subscription)\n\n    run_cli_command(cli_cmd)\n\n\ndef wait_for_blob_copy_operation(blob_name, target_container_name, target_storage_account_name,\n                                 azure_pool_frequency, location, subscription):\n    copy_status = \"pending\"\n    prev_progress = -1\n    while copy_status == \"pending\":\n        cli_cmd = prepare_cli_command(['storage', 'blob', 'show',\n                                       '--name', blob_name,\n                                       '--container-name', target_container_name,\n                                       '--account-name', target_storage_account_name],\n                                      subscription=subscription)\n\n        json_output = run_cli_command(cli_cmd, return_as_json=True)\n        copy_status = json_output[\"properties\"][\"copy\"][\"status\"]\n        copy_progress_1, copy_progress_2 = json_output[\"properties\"][\"copy\"][\"progress\"].split(\n            \"/\")\n        current_progress = int(\n            int(copy_progress_1) / int(copy_progress_2) * 100)\n\n        if current_progress != prev_progress:\n            msg = \"{0} - Copy progress: {1}%\"\\\n                .format(location, str(current_progress))\n            logger.warn(msg)\n\n        prev_progress = current_progress\n\n        try:\n            time.sleep(azure_pool_frequency)\n        except KeyboardInterrupt:\n            return\n\n    if copy_status != 'success':\n        logger.error(\"The copy operation didn't succeed. Last status: %s\", copy_status)\n        logger.error(\"Command run: %s\", cli_cmd)\n        logger.error(\"Command output: %s\", json_output)\n\n        raise CLIError('Blob copy failed')\n\n\ndef get_random_string(length):\n    import string\n    import random\n    chars = string.ascii_lowercase + string.digits\n    return ''.join(random.choice(chars) for _ in range(length))\n", "path": "src/image-copy/azext_imagecopy/create_target.py"}, {"content": "#!/usr/bin/env python\n\n# --------------------------------------------------------------------------------------------\n# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See License.txt in the project root for license information.\n# --------------------------------------------------------------------------------------------\n\nfrom codecs import open\nfrom setuptools import setup, find_packages\n\nVERSION = \"0.0.9\"\n\nCLASSIFIERS = [\n    'Development Status :: 4 - Beta',\n    'Intended Audience :: Developers',\n    'Intended Audience :: System Administrators',\n    'Programming Language :: Python',\n    'Programming Language :: Python :: 2',\n    'Programming Language :: Python :: 2.7',\n    'Programming Language :: Python :: 3',\n    'Programming Language :: Python :: 3.4',\n    'Programming Language :: Python :: 3.5',\n    'Programming Language :: Python :: 3.6',\n    'License :: OSI Approved :: MIT License',\n]\n\nDEPENDENCIES = []\n\nsetup(\n    name='image-copy-extension',\n    version=VERSION,\n    description='Support for copying managed vm images between regions',\n    long_description='Support for copying managed vm images between regions',\n    license='MIT',\n    author='Tamir Kamara',\n    author_email='tamir.kamara@microsoft.com',\n    url='https://github.com/Azure/azure-cli-extensions',\n    classifiers=CLASSIFIERS,\n    package_data={'azext_imagecopy': ['azext_metadata.json']},\n    packages=find_packages(),\n    install_requires=DEPENDENCIES\n)\n", "path": "src/image-copy/setup.py"}]}