Skip to content

Instantly share code, notes, and snippets.

@freyes
Created August 10, 2020 21:44
Show Gist options
  • Save freyes/1c613e7254955078fb579558cb13d83a to your computer and use it in GitHub Desktop.
Save freyes/1c613e7254955078fb579558cb13d83a to your computer and use it in GitHub Desktop.
$ python3 parse-script.py test_script.sh
------
results:
{}
------
parameters:
{}
------
parsed_yaml:
{'description': 'This is something.',
'destructive': False,
'for_hardware': 'pci:1028:0757',
'hardware_type': 'node',
'may_reboot': True,
'name': 'something',
'recommission': True,
'script_type': 'commissioning',
'tags': 'commissioning',
'title': 'Something',
'type': 'commissioning'}
#!/usr/bin/python3
import re
import sys
import yaml
from pprint import pprint
def set_form_error(self, *args):
print("error: " + " ".join(args))
def _read_script(script):
"""Read embedded YAML configuration in a script.
Search for supported MAAS script metadata in the script and
read the values. Leading '#' are ignored. If the values are
fields they will be entered in the form.
"""
yaml_delim = re.compile(
r"\s*#\s*-+\s*(Start|End) MAAS (?P<version>\d+\.\d+) "
r"script metadata\s+-+",
re.I,
)
found_version = None
yaml_content = ""
script_splitlines = script.splitlines()
if len(script_splitlines) >= 1 and not script_splitlines[0].startswith(
"#!/"
):
set_form_error(self, "script", "Must start with shebang.")
for line in script_splitlines[1:]:
m = yaml_delim.search(line)
if m is not None:
if found_version is None and m.group("version") == "1.0":
# Found the start of the embedded YAML
found_version = m.group("version")
continue
elif found_version == m.group("version"):
# Found the end of the embedded YAML
break
elif found_version is not None and line.strip() != "":
# Capture all lines inbetween the deliminator
if "#" not in line:
set_form_error(self, "script", 'Missing "#" on YAML line.')
return
yaml_content += "%s\n" % line.split("#", 1)[1]
try:
parsed_yaml = yaml.safe_load(yaml_content)
except yaml.YAMLError as err:
set_form_error(self, "script", "Invalid YAML: %s" % err)
return
if not isinstance(parsed_yaml, dict):
return
results = parsed_yaml.pop("results", {})
parameters = parsed_yaml.pop("parameters", {})
return (results, parameters, parsed_yaml)
with open(sys.argv[1]) as f:
(results, parameters, parsed_yaml) = _read_script(f.read())
print('------\nresults:')
pprint(results)
print('------\nparameters:')
pprint(parameters)
print('------\nparsed_yaml:')
pprint(parsed_yaml)
#!/bin/bash
# --- Start MAAS 1.0 script metadata ---
# name: something
# title: Something
# description: This is something.
# type: commissioning
# script_type: commissioning
# tags: commissioning
# recommission: True
# destructive: False
# hardware_type: node
# for_hardware: pci:1028:0757
# may_reboot: True
# --- End MAAS 1.0 script metadata ---
echo "hi"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment