Created
February 22, 2014 17:28
-
-
Save jjongsma/9158547 to your computer and use it in GitHub Desktop.
Packer build wrapper for generating JSON from a more flexible YAML config syntax
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# | |
# "packer build" wrapper that sets up a consistent build environment for image building. | |
# | |
# - Use common .packer_cache directory in this root directory | |
# - Generate JSON templates from YAML (if exists) to allow comments and includes | |
import sys | |
import os | |
import subprocess | |
import yaml | |
import json | |
import tempfile | |
import code | |
class IncludeLoader(yaml.Loader): | |
def __init__(self, stream): | |
self._root = os.path.split(stream.name)[0] | |
super(IncludeLoader, self).__init__(stream) | |
def include(self, node): | |
filename = os.path.join(self._root, self.construct_scalar(node)) | |
with open(filename, 'r') as f: | |
return yaml.load(f, IncludeLoader) | |
IncludeLoader.add_constructor('!include', IncludeLoader.include) | |
def build_image(path): | |
if path and path[-1:] == '/': | |
path = path[:-1] | |
if not os.path.exists(path): | |
print "[ERROR] Unable to build image %s: no templates found" % path | |
sys.exit(1) | |
name = os.path.basename(path) | |
yaml_template = "%s/%s.yaml" % (path, name) | |
json_template = "%s/%s.json" % (path, name) | |
remove_json = False | |
if os.path.exists(yaml_template): | |
if os.path.exists(json_template): | |
print "[WARNING] %s: Found both JSON and YAML templates, using YAML" % path | |
with open(yaml_template, 'r') as infile: | |
template = yaml.load(infile, IncludeLoader) | |
# Flatten provisioners so we can include multiple steps in each include | |
if 'provisioners' in template: | |
prov = template['provisioners'] | |
flat = [] | |
for p in prov: | |
if isinstance(p, list): | |
flat.extend(p) | |
else: | |
flat.append(p) | |
template['provisioners'] = flat | |
(outfile, json_template) = tempfile.mkstemp('.json', 'packer') | |
remove_json = True | |
with open(json_template, 'w') as outfile: | |
json.dump(template, outfile) | |
if os.path.exists(json_template): | |
cwd = os.getcwd() | |
packer_env = os.environ.copy() | |
packer_env['PACKER_CACHE_DIR'] = '%s/.packer_cache' % cwd | |
p = subprocess.Popen(['packer', 'build', '-force', json_template], env=packer_env) | |
try: | |
p.wait() | |
except KeyboardInterrupt: | |
p.wait() | |
finally: | |
if remove_json: | |
os.unlink(json_template) | |
else: | |
print "[ERROR] Unable to build image %s: no templates found" % path | |
sys.exit(1) | |
if __name__ == "__main__": | |
for path in sys.argv[1:]: | |
build_image(path) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment