add --validate option
This commit is contained in:
parent
8fdc1e13f3
commit
a257deb96b
|
@ -9,25 +9,18 @@ from optparse import OptionParser
|
||||||
from pystache.context import KeyNotFoundError
|
from pystache.context import KeyNotFoundError
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
logging.basicConfig(format='[%(asctime)s] [%(levelname)s] %(message)s', datefmt='%Y/%m/%d %I:%M:%S %p', level=logging.INFO)
|
def install_cornfig(config_path, template_root, output_path, write):
|
||||||
|
|
||||||
class CornfigException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def install_cornfig(config_path, template_root, output_path='/'):
|
|
||||||
config = read_config(config_path)
|
config = read_config(config_path)
|
||||||
tree = build_tree( template_paths(template_root), config )
|
tree = build_tree( template_paths(template_root), config )
|
||||||
for path, contents in tree.items():
|
if write:
|
||||||
write_file( os.path.join(output_path, strip_prefix('/', path)), contents)
|
for path, contents in tree.items():
|
||||||
|
write_file( os.path.join(output_path, strip_prefix('/', path)), contents)
|
||||||
|
|
||||||
def write_file(path, contents):
|
def write_file(path, contents):
|
||||||
logging.info("writing %s", path)
|
logging.info("writing %s", path)
|
||||||
d = os.path.dirname(path)
|
d = os.path.dirname(path)
|
||||||
if not os.path.exists(d):
|
os.path.exists(d) or os.makedirs(d)
|
||||||
os.makedirs(d)
|
with open(path, 'w') as f: f.write(contents)
|
||||||
out = open(path, 'w')
|
|
||||||
out.write(contents)
|
|
||||||
out.close()
|
|
||||||
|
|
||||||
# return a map of filenames->filecontents
|
# return a map of filenames->filecontents
|
||||||
def build_tree(templates, config):
|
def build_tree(templates, config):
|
||||||
|
@ -50,7 +43,7 @@ def render_moustache(text, config):
|
||||||
r = pystache.Renderer(missing_tags = 'strict')
|
r = pystache.Renderer(missing_tags = 'strict')
|
||||||
return r.render(text, config)
|
return r.render(text, config)
|
||||||
except KeyNotFoundError as e:
|
except KeyNotFoundError as e:
|
||||||
raise CornfigException("key '%s' does not exist metadata file." % e.key)
|
raise CornfigException("key '%s' does not exist in metadata file." % e.key)
|
||||||
|
|
||||||
def render_executable(path, config):
|
def render_executable(path, config):
|
||||||
p = Popen([path], stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
p = Popen([path], stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||||
|
@ -65,8 +58,6 @@ def read_config(path):
|
||||||
except:
|
except:
|
||||||
raise CornfigException("invalid metadata file: %s" % path)
|
raise CornfigException("invalid metadata file: %s" % path)
|
||||||
|
|
||||||
# given a root directory, return a list of tuples
|
|
||||||
# containing input and output paths
|
|
||||||
def template_paths(root):
|
def template_paths(root):
|
||||||
res = []
|
res = []
|
||||||
for cur_root, subdirs, files in os.walk(root):
|
for cur_root, subdirs, files in os.walk(root):
|
||||||
|
@ -78,27 +69,40 @@ def template_paths(root):
|
||||||
def strip_prefix(prefix, s):
|
def strip_prefix(prefix, s):
|
||||||
return s[len(prefix):] if s.startswith(prefix) else s
|
return s[len(prefix):] if s.startswith(prefix) else s
|
||||||
|
|
||||||
|
### CLI ###
|
||||||
|
|
||||||
def usage():
|
def parse_opts():
|
||||||
print "Usage:\n cornfig TEMPLATE_ROOT JSON_PATH OUTPUT_ROOT"
|
parser = OptionParser(usage="cornfig -t TEMPLATE_ROOT [-m METADATA_FILE] [-o OUT_DIR]")
|
||||||
sys.exit(1)
|
|
||||||
|
parser.add_option('-t', '--templates', dest='template_root', help='path to template root directory')
|
||||||
|
parser.add_option('-o', '--output', dest='out_root', help='root directory for output (default: /)',
|
||||||
|
default='/')
|
||||||
|
parser.add_option('-m', '--metadata', dest='metadata_path', help='path to metadata file',
|
||||||
|
default='/var/lib/cloud/cfn-init-data')
|
||||||
|
parser.add_option('-v', '--validate', dest='write', help='validate only. do not write files',
|
||||||
|
default=True, action='store_false')
|
||||||
|
(opts, args) = parser.parse_args()
|
||||||
|
|
||||||
|
if opts.template_root is None: raise CornfigException('missing option --templates')
|
||||||
|
if not os.access(opts.out_root, os.W_OK):
|
||||||
|
raise CornfigException("you don't have permission to write to '%s'" % opts.out_root)
|
||||||
|
return opts
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
try:
|
try:
|
||||||
parser = OptionParser(usage="cornfig -t TEMPLATE_ROOT [-m METADATA_FILE] [-o OUT_DIR]")
|
opts = parse_opts()
|
||||||
parser.add_option('-m', '--metadata', dest='metadata_path',
|
install_cornfig(opts.metadata_path, opts.template_root, opts.out_root, opts.write)
|
||||||
help='path to metadata file (default: /var/lib/cloud/cfn-init-data)',
|
logging.info("success")
|
||||||
default='/var/lib/cloud/cfn-init-data')
|
|
||||||
parser.add_option('-t', '--templates', dest='template_root', help='path to template root directory')
|
|
||||||
parser.add_option('-o', '--output', dest='out_root', help='root directory for output (default: /)', default='/')
|
|
||||||
(options, args) = parser.parse_args()
|
|
||||||
|
|
||||||
if options.template_root is None: raise CornfigException('missing option --templates')
|
|
||||||
|
|
||||||
install_cornfig(options.metadata_path, options.template_root, options.out_root)
|
|
||||||
except CornfigException as e:
|
except CornfigException as e:
|
||||||
logging.error(e)
|
logging.error(e)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
class CornfigException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
logging.basicConfig(format='[%(asctime)s] [%(levelname)s] %(message)s',
|
||||||
|
datefmt='%Y/%m/%d %I:%M:%S %p',
|
||||||
|
level=logging.INFO)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -8,7 +8,7 @@ config = {
|
||||||
'description': 'applies cornfiguration from cloud metadata.',
|
'description': 'applies cornfiguration from cloud metadata.',
|
||||||
'author': 'echohead',
|
'author': 'echohead',
|
||||||
'author_email': 'tim.miller.0@gmail.com',
|
'author_email': 'tim.miller.0@gmail.com',
|
||||||
'url': 'github.com/echohead/cornfig',
|
'url': 'http://github.com/echohead/cornfig',
|
||||||
'version': '0.1',
|
'version': '0.1',
|
||||||
'install_requires': ['nose'],
|
'install_requires': ['nose'],
|
||||||
'packages': ['cornfig'],
|
'packages': ['cornfig'],
|
||||||
|
|
|
@ -40,7 +40,7 @@ def test_install_cornfig():
|
||||||
t.write(json.dumps(CONFIG))
|
t.write(json.dumps(CONFIG))
|
||||||
t.flush()
|
t.flush()
|
||||||
tmpdir = tempfile.mkdtemp()
|
tmpdir = tempfile.mkdtemp()
|
||||||
install_cornfig(t.name, TEMPLATES, output_path=tmpdir)
|
install_cornfig(t.name, TEMPLATES, tmpdir, True)
|
||||||
for path, contents in OUTPUT.items():
|
for path, contents in OUTPUT.items():
|
||||||
full_path = os.path.join(tmpdir, path[1:])
|
full_path = os.path.join(tmpdir, path[1:])
|
||||||
assert os.path.exists(full_path)
|
assert os.path.exists(full_path)
|
||||||
|
|
Loading…
Reference in New Issue