aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Buchholz <tomalok@gmail.com>2019-06-03 17:35:07 -0700
committerMike Crute <mike@crute.us>2019-07-05 12:51:09 -0700
commit8f563aa4f1b33651a87399e73bfcf82fef858605 (patch)
tree654c3084070771425d8d1515f0f5318cbb32916c
parentd28214fc5054199efa2046ed95c5e4e891c6b521 (diff)
downloadalpine-ec2-ami-8f563aa4f1b33651a87399e73bfcf82fef858605.tar.bz2
alpine-ec2-ami-8f563aa4f1b33651a87399e73bfcf82fef858605.tar.xz
alpine-ec2-ami-8f563aa4f1b33651a87399e73bfcf82fef858605.zip
more changes based on review...
* Makefile - improve/fix check for required make vars * resolve-profile.py.in + build a list of all regions & probe to see which ones are enabled (unknown if special subscription regions like ap-northeast-3 would show up in this list) + expand 'ami_regions' 'ALL' meta key to all enabled regions, 'ALL' key's value is preserved (that is, a value of None or False will disable all regions) + warn/remove regions in profile config that are found to be disabled. + improve checks for [None, False] values
-rw-r--r--Makefile19
-rw-r--r--profiles/alpine.conf19
-rw-r--r--profiles/test.conf4
-rw-r--r--scripts/resolve-profile.py.in48
4 files changed, 65 insertions, 25 deletions
diff --git a/Makefile b/Makefile
index 8247c9b..851ed7e 100644
--- a/Makefile
+++ b/Makefile
@@ -12,20 +12,29 @@ LEVEL :=
12PACKER := packer 12PACKER := packer
13export PACKER 13export PACKER
14 14
15require_var = $(if $(value $1),,$(error $1=... required)) 15
16check_defined = \
17 $(strip $(foreach 1,$1, \
18 $(call __check_defined,$1,$(strip $(value 2)))))
19__check_defined = \
20 $(if $(value $1),, \
21 $(error Undefined $1$(if $2, ($2))$(if $(value @), \
22 required by target `$@')))
23
16 24
17.PHONY: amis prune release-readme clean 25.PHONY: amis prune release-readme clean
18 26
19amis: build build/packer.json build/profile/$(PROFILE) build/update-release.py 27amis: build build/packer.json build/profile/$(PROFILE) build/update-release.py
20 @:$(call require_var, PROFILE) 28 @:$(call check_defined, PROFILE, target profile name)
21 build/make-amis $(PROFILE) $(BUILDS) 29 build/make-amis $(PROFILE) $(BUILDS)
22 30
23prune: build build/prune-amis.py 31prune: build build/prune-amis.py
24 @:$(call require_var, LEVEL) 32 @:$(call check_defined, LEVEL, pruning level)
25 @:$(call require_var, PROFILE) 33 @:$(call check_defined, PROFILE, target profile name)
26 build/prune-amis.py $(LEVEL) $(PROFILE) $(BUILD) 34 build/prune-amis.py $(LEVEL) $(PROFILE) $(BUILD)
27 35
28release-readme: build build/gen-release-readme.py 36release-readme: build build/gen-release-readme.py
37 @:$(call check_defined, PROFILE, target profile name)
29 @:$(call require_var, PROFILE) 38 @:$(call require_var, PROFILE)
30 build/gen-release-readme.py $(PROFILE) 39 build/gen-release-readme.py $(PROFILE)
31 40
@@ -39,7 +48,7 @@ build/packer.json: build packer.conf
39 build/.py3/bin/pyhocon -i packer.conf -f json > build/packer.json 48 build/.py3/bin/pyhocon -i packer.conf -f json > build/packer.json
40 49
41build/profile/$(PROFILE): build build/resolve-profile.py $(CORE_PROFILES) $(TARGET_PROFILES) 50build/profile/$(PROFILE): build build/resolve-profile.py $(CORE_PROFILES) $(TARGET_PROFILES)
42 @:$(call require_var, PROFILE) 51 @:$(call check_defined, PROFILE, target profile name)
43 build/resolve-profile.py $(PROFILE) 52 build/resolve-profile.py $(PROFILE)
44 53
45%.py: %.py.in build 54%.py: %.py.in build
diff --git a/profiles/alpine.conf b/profiles/alpine.conf
index 3727753..b5ada55 100644
--- a/profiles/alpine.conf
+++ b/profiles/alpine.conf
@@ -18,24 +18,7 @@ alpine {
18 all = true # these AMIs are publicly available 18 all = true # these AMIs are publicly available
19 } 19 }
20 ami_regions { 20 ami_regions {
21 #ap-east-1 = true # needs to be enabled first 21 ALL = true
22 ap-northeast-1 = true
23 ap-northeast-2 = true
24 #ap-northeast-3 = false # available by subscription only
25 ap-southeast-1 = true
26 ap-southeast-2 = true
27 ap-south-1 = true
28 ca-central-1 = true
29 eu-central-1 = true
30 eu-north-1 = true
31 eu-west-1 = true
32 eu-west-2 = true
33 eu-west-3 = true
34 sa-east-1 = true
35 us-east-1 = true
36 us-east-2 = true
37 us-west-1 = true
38 us-west-2 = true
39 } 22 }
40} 23}
41 24
diff --git a/profiles/test.conf b/profiles/test.conf
index eb7f2a3..b4ecab8 100644
--- a/profiles/test.conf
+++ b/profiles/test.conf
@@ -15,6 +15,10 @@ test {
15 ami_desc_prefix = "Alpine Test " 15 ami_desc_prefix = "Alpine Test "
16 build_region = "us-west-2" 16 build_region = "us-west-2"
17 build_subnet = "subnet-033a30d7b5220d177" 17 build_subnet = "subnet-033a30d7b5220d177"
18 ami_regions {
19 us-west-1 = true
20 ap-east-1 = true
21 }
18} 22}
19 23
20# Build definitions 24# Build definitions
diff --git a/scripts/resolve-profile.py.in b/scripts/resolve-profile.py.in
index d784cf3..5aca4d7 100644
--- a/scripts/resolve-profile.py.in
+++ b/scripts/resolve-profile.py.in
@@ -5,6 +5,8 @@ import json
5import os 5import os
6import shutil 6import shutil
7import sys 7import sys
8import boto3
9from botocore.exceptions import ClientError
8from datetime import datetime, timedelta 10from datetime import datetime, timedelta
9from pyhocon import ConfigFactory 11from pyhocon import ConfigFactory
10 12
@@ -47,13 +49,39 @@ def fold(fdict, ffmt):
47 fkey = fkey.strip('"') # complex keys may be in quotes 49 fkey = fkey.strip('"') # complex keys may be in quotes
48 if fval is True: 50 if fval is True:
49 folded += ffmt[0] + fkey 51 folded += ffmt[0] + fkey
50 elif not (fval is None or fval is False): 52 elif fval not in [None, False]:
51 folded += ffmt.format(fkey, fval) 53 folded += ffmt.format(fkey, fval)
52 return folded[1:] 54 return folded[1:]
53 55
54 56
57# list of AWS regions, and whether they're enabled
58all_regions = {}
59AWS = boto3.session.Session()
60sys.stderr.write("\n>>> Determining region availability...")
61sys.stderr.flush()
62for region in AWS.get_available_regions('ec2'):
63 ec2 = AWS.client('ec2', region_name=region)
64 try:
65 ec2.describe_regions()
66 except ClientError as e:
67 if e.response['Error']['Code'] == 'AuthFailure':
68 sys.stderr.write('-')
69 sys.stderr.flush()
70 all_regions[region] = False
71 continue
72 elif e.response['Error']['Code'] == 'UnauthorizedOperation':
73 # have access to the region, but not to ec2:DescribeRegions
74 pass
75 else:
76 raise
77 sys.stderr.write('+')
78 sys.stderr.flush()
79 all_regions[region] = True
80sys.stderr.write("\n")
81
55# parse/resolve HOCON profile's builds' config 82# parse/resolve HOCON profile's builds' config
56for build, cfg in BUILDS.items(): 83for build, cfg in BUILDS.items():
84 sys.stderr.write(f">>> Resolving configuration for '{build}'\n")
57 build_dir = os.path.join(PROFILE_DIR, build) 85 build_dir = os.path.join(PROFILE_DIR, build)
58 86
59 # make a fresh profile build directory 87 # make a fresh profile build directory
@@ -75,6 +103,22 @@ for build, cfg in BUILDS.items():
75 if cfg['revision'] == '@NOW@': 103 if cfg['revision'] == '@NOW@':
76 cfg['revision'] = NOW.strftime('%Y%m%d%H%M%S') 104 cfg['revision'] = NOW.strftime('%Y%m%d%H%M%S')
77 105
106 # 'ALL' region expansion (or retraction)
107 if 'ALL' in cfg['ami_regions']:
108 all_val = cfg['ami_regions']['ALL']
109 if all_val not in [None, False]:
110 cfg['ami_regions'] = all_regions
111 else:
112 cfg['ami_regions'] = {}
113 else:
114 # warn/remove disabled regions
115 for region, enabled in all_regions.items():
116 if enabled is not False or region not in cfg['ami_regions']:
117 continue
118 if cfg['ami_regions'][region] not in [None, False]:
119 sys.stderr.write(f"*** WARNING: skipping disabled region {region}\n")
120 cfg['ami_regions'][region] = False
121
78 # fold dict vars to scalars 122 # fold dict vars to scalars
79 for foldkey, foldfmt in FOLD_DICTS.items(): 123 for foldkey, foldfmt in FOLD_DICTS.items():
80 cfg[foldkey] = fold(cfg[foldkey], foldfmt) 124 cfg[foldkey] = fold(cfg[foldkey], foldfmt)
@@ -85,7 +129,7 @@ for build, cfg in BUILDS.items():
85 if lvl is True: 129 if lvl is True:
86 # service in default runlevel 130 # service in default runlevel
87 lvls['default'].append(svc) 131 lvls['default'].append(svc)
88 elif not (lvl is None or lvl is False): 132 elif lvl not in [None, False]:
89 # service in specified runlevel (skip svc when false/null) 133 # service in specified runlevel (skip svc when false/null)
90 if lvl not in lvls.keys(): 134 if lvl not in lvls.keys():
91 lvls[lvl] = [] 135 lvls[lvl] = []