|
1 | 1 | import json |
2 | 2 | import os |
3 | 3 | import subprocess |
| 4 | +import sys |
4 | 5 |
|
5 | 6 | from cosalib.builds import Builds |
6 | 7 | from cosalib.cmdlib import runcmd |
@@ -31,81 +32,81 @@ def deregister_aws_resource(ami, snapshot, region, credentials_file): |
31 | 32 | def aws_run_ore_replicate(build, args): |
32 | 33 | build.refresh_meta() |
33 | 34 | buildmeta = build.meta |
34 | | - buildmeta_keys = ["amis"] |
35 | | - if len(buildmeta.get(buildmeta_keys[0], [])) < 1: |
| 35 | + meta_key = "amis" |
| 36 | + # only replicate WinLI AMIs if `--winli` is used |
| 37 | + if args.winli: |
| 38 | + meta_key = "aws-winli" |
| 39 | + if len(buildmeta.get(meta_key, [])) < 1: |
36 | 40 | raise SystemExit(("buildmeta doesn't contain source AMIs." |
37 | 41 | " Run buildextend-aws --upload first")) |
38 | 42 |
|
39 | | - if len(buildmeta.get('aws-winli', [])) > 0: |
40 | | - buildmeta_keys.append("aws-winli") |
41 | | - |
42 | | - for key in buildmeta_keys: |
43 | | - # Determine which region to copy from |
44 | | - if not args.source_region: |
45 | | - args.source_region = buildmeta[key][0]['name'] |
46 | | - |
47 | | - ore_args = ['ore', 'aws', '--region', args.source_region] |
48 | | - if args.log_level: |
49 | | - ore_args.extend(['--log-level', args.log_level]) |
50 | | - if args.credentials_file: |
51 | | - ore_args.extend(['--credentials-file', args.credentials_file]) |
52 | | - |
53 | | - # If no region specified then autodetect the regions to replicate to. |
54 | | - # Specify --region=args.source_region here so ore knows to talk to |
55 | | - # a region that exists (i.e. it will talk to govcloud if copying |
56 | | - # from a govcloud region). |
57 | | - if not args.region: |
58 | | - args.region = subprocess.check_output( |
59 | | - ore_args + ['list-regions']).decode().strip().split() |
60 | | - |
61 | | - # only replicate to regions that don't already exist |
62 | | - existing_regions = [item['name'] for item in buildmeta[key]] |
63 | | - duplicates = list(set(args.region).intersection(existing_regions)) |
64 | | - if len(duplicates) > 0: |
65 | | - print((f"AMIs already exist in {duplicates} region(s), " |
66 | | - "skipping listed region(s)...")) |
67 | | - |
68 | | - region_list = list(set(args.region) - set(duplicates)) |
69 | | - if len(region_list) == 0: |
70 | | - print("no new regions detected") |
71 | | - continue |
72 | | - source_image = None |
73 | | - for a in buildmeta[key]: |
74 | | - if a['name'] == args.source_region: |
75 | | - source_image = a['hvm'] |
76 | | - break |
| 43 | + # Determine which region to copy from |
| 44 | + if not args.source_region: |
| 45 | + args.source_region = buildmeta[meta_key][0]['name'] |
| 46 | + |
| 47 | + ore_args = ['ore', 'aws', '--region', args.source_region] |
| 48 | + if args.log_level: |
| 49 | + ore_args.extend(['--log-level', args.log_level]) |
| 50 | + if args.credentials_file: |
| 51 | + ore_args.extend(['--credentials-file', args.credentials_file]) |
77 | 52 |
|
78 | | - if source_image is None: |
79 | | - raise Exception(("Unable to find AMI ID for " |
80 | | - f"{args.source_region} region")) |
81 | | - |
82 | | - ore_args.extend(['copy-image', '--image', source_image]) |
83 | | - ore_args.extend(region_list) |
84 | | - print("+ {}".format(subprocess.list2cmdline(ore_args))) |
85 | | - |
86 | | - ore_data = "" |
87 | | - try: |
88 | | - ore_data = subprocess.check_output(ore_args, encoding='utf-8') |
89 | | - except subprocess.CalledProcessError as e: |
90 | | - ore_data = e.output or "" |
91 | | - raise e |
92 | | - finally: |
93 | | - ore_data = ore_data.strip() |
94 | | - if len(ore_data) > 0: |
95 | | - for line in ore_data.split('\n'): |
96 | | - j = json.loads(line) |
97 | | - # This matches the Container Linux schema: |
98 | | - # https://stable.release.core-os.net/amd64-usr/current/coreos_production_ami_all.json |
99 | | - ami_data = [{'name': region, |
100 | | - 'hvm': vals['ami'], |
101 | | - 'snapshot': vals['snapshot']} |
102 | | - for region, vals in j.items()] |
103 | | - buildmeta[key].extend(ami_data) |
104 | | - |
105 | | - # Record the AMI's that have been replicated as they happen. |
106 | | - # When re-running the replication, we don't want to be lose |
107 | | - # what has been done. |
108 | | - build.meta_write() |
| 53 | + # If no region specified then autodetect the regions to replicate to. |
| 54 | + # Specify --region=args.source_region here so ore knows to talk to |
| 55 | + # a region that exists (i.e. it will talk to govcloud if copying |
| 56 | + # from a govcloud region). |
| 57 | + if not args.region: |
| 58 | + args.region = subprocess.check_output( |
| 59 | + ore_args + ['list-regions']).decode().strip().split() |
| 60 | + |
| 61 | + # only replicate to regions that don't already exist |
| 62 | + existing_regions = [item['name'] for item in buildmeta[meta_key]] |
| 63 | + duplicates = list(set(args.region).intersection(existing_regions)) |
| 64 | + if len(duplicates) > 0: |
| 65 | + print((f"AMIs already exist in {duplicates} region(s), " |
| 66 | + "skipping listed region(s)...")) |
| 67 | + |
| 68 | + region_list = list(set(args.region) - set(duplicates)) |
| 69 | + if len(region_list) == 0: |
| 70 | + print("no new regions detected") |
| 71 | + sys.exit(0) |
| 72 | + |
| 73 | + source_image = None |
| 74 | + for a in buildmeta[meta_key]: |
| 75 | + if a['name'] == args.source_region: |
| 76 | + source_image = a['hvm'] |
| 77 | + break |
| 78 | + |
| 79 | + if source_image is None: |
| 80 | + raise Exception(("Unable to find AMI ID for " |
| 81 | + f"{args.source_region} region")) |
| 82 | + |
| 83 | + ore_args.extend(['copy-image', '--image', source_image]) |
| 84 | + ore_args.extend(region_list) |
| 85 | + print("+ {}".format(subprocess.list2cmdline(ore_args))) |
| 86 | + |
| 87 | + ore_data = "" |
| 88 | + try: |
| 89 | + ore_data = subprocess.check_output(ore_args, encoding='utf-8') |
| 90 | + except subprocess.CalledProcessError as e: |
| 91 | + ore_data = e.output or "" |
| 92 | + raise e |
| 93 | + finally: |
| 94 | + ore_data = ore_data.strip() |
| 95 | + if len(ore_data) > 0: |
| 96 | + for line in ore_data.split('\n'): |
| 97 | + j = json.loads(line) |
| 98 | + # This matches the Container Linux schema: |
| 99 | + # https://stable.release.core-os.net/amd64-usr/current/coreos_production_ami_all.json |
| 100 | + ami_data = [{'name': region, |
| 101 | + 'hvm': vals['ami'], |
| 102 | + 'snapshot': vals['snapshot']} |
| 103 | + for region, vals in j.items()] |
| 104 | + buildmeta[meta_key].extend(ami_data) |
| 105 | + |
| 106 | + # Record the AMI's that have been replicated as they happen. |
| 107 | + # When re-running the replication, we don't want to be lose |
| 108 | + # what has been done. |
| 109 | + build.meta_write() |
109 | 110 |
|
110 | 111 |
|
111 | 112 | @retry(reraise=True, stop=stop_after_attempt(3)) |
@@ -226,6 +227,6 @@ def aws_cli(parser): |
226 | 227 | parser.add_argument("--public", action="store_true", help="Mark images as publicly available") |
227 | 228 | parser.add_argument("--tags", help="list of key=value tags to attach to the AMI", |
228 | 229 | action='append', default=[]) |
229 | | - parser.add_argument("--winli", action="store_true", help="create an AWS Windows LI Ami") |
| 230 | + parser.add_argument("--winli", action="store_true", help="create or replicate an AWS Windows LI Ami") |
230 | 231 | parser.add_argument("--winli-billing-product", help="Windows billing product code used to create a Windows LI AMI") |
231 | 232 | return parser |
0 commit comments