Commit ad1d9f76 authored by eric pellegrini's avatar eric pellegrini

added static typing annotations

parent 1dc9d326
......@@ -12,9 +12,11 @@ import os
import shutil
import sys
from typing import List
from packme import Packman
def clean_templates_dir(templates_base_dir):
def clean_templates_dir(templates_base_dir : str):
"""Removes all manifest.json files, packer_cache and builds directories found in
templates directory
"""
......@@ -38,8 +40,8 @@ def clean_templates_dir(templates_base_dir):
except FileNotFoundError:
pass
def parse_args():
"""Setup and run the argument parser.
def parse_args() -> argparse.Namespace:
"""Returns the argument namespace after command-line parsing.
"""
parser = argparse.ArgumentParser(description="This is packme: a program for generating and running packer configuration(s)")
......@@ -50,7 +52,6 @@ def parse_args():
parser.add_argument("--templates-base-dir", "-t", dest="templates_base_dir", required=True, help="Templates base directory")
parser.add_argument("--selected-templates", "-s", dest="selected_templates", nargs="*", default=["*"], help="run packman on selected template(s)")
parser.add_argument("--input", "-i", dest="input_file", help="YAML input file")
args = parser.parse_args()
return args
......@@ -58,14 +59,14 @@ def parse_args():
if __name__ == "__main__":
# Parse command line arguments and fetch their values
args = parse_args()
input_file = args.input_file
run = args.run
templates_base_dir = args.templates_base_dir
selected_templates = args.selected_templates
clean = args.clean
debug = args.debug
log = args.log
args : argparse.Namespace = parse_args()
input_file : str = args.input_file
run : bool = args.run
templates_base_dir : str = args.templates_base_dir
selected_templates : List[str] = args.selected_templates
clean : bool = args.clean
debug : bool= args.debug
log : bool = args.log
# If --clean option is set, cleanup the templates dir (builds, packer_cache, manifest.json files and directories)
if clean:
......
#!/usr/bin/env python3
#################################################################
# This apps allows the creation of packer json file out of
# YAML template
# One of its main feature is to handle template inheritance
# which is not covered yet natively by packer
# To run the application:
# env_var_1 env_var_2 ... env_var_n rackman.py template.yml
# where env_var_1 ... env_var_n are environment variables
# passed at the command line level and template.yml is the YAML
# which contain the packer configuration
#################################################################
import collections
import glob
import jinja2
......@@ -20,6 +6,8 @@ import os
import pprint
import yaml
from typing import List
class PackerTemplate:
"""This class implements one packer template.
Basically, a packer template is made of four sections:
......@@ -30,7 +18,9 @@ class PackerTemplate:
- processors: a list of dictionaries where each dictionary defines actions to be run after the image is built
"""
def __init__(self, name, yaml_node, packages):
def __init__(self, name: str, yaml_node: yaml.Node, packages: List[str]) -> None:
"""Constructor
"""
self._name = name
......@@ -62,99 +52,66 @@ class PackerTemplate:
self._load_packages(packages)
@property
def builders(self):
"""Property for _builders attribute.
Returns
-------
list
The list of packer builders for this PackerTemplate.
def builders(self) -> list:
"""Returns the list of packer builders of this :class:`PackerTemplate`.
"""
return self._builders
@property
def description(self):
"""Property for _description attribute.
Returns
-------
str
The description of this PackerTemplate.
def description(self) -> str:
"""Returns the description of this :class:`PackerTemplate`.
"""
return self._description
@property
def name(self):
"""Property for _name attribute.
Returns
-------
str
The name of this PackerTemplate.
def name(self) -> str:
"""Returns the name of this :class:`PackerTemplate`.
"""
return self._name
@property
def parameters(self):
"""Property for _parameters attribute.
Returns
-------
dict
The parameters that will be used by Jinja 2 when creating the template json file.
def parameters(self) -> dict:
"""Returns the parameters of this :class:`PackerTemplate`.
This dictionary will be applied to Jinja 2 templates when creating the manifest json file.
"""
return self._parameters
@property
def postprocessors(self):
"""Property for _postprocessors attribute.
Returns
-------
list
The list of packer postprocessors for this PackerTemplate.
def postprocessors(self) -> list:
"""Returns the postprocessors of this :class:`PackerTemplate`.
"""
return self._postprocessors
@property
def provisioners(self):
"""Property for _provisioners attribute.
Returns
-------
list
The list of packer provisioners for this PackerTemplate.
def provisioners(self) -> list:
"""Returns the provisioners of this :class:`PackerTemplate`.
"""
return self._provisioners
@property
def variables(self):
"""Property for _variables attribute.
Returns
-------
list
The list of packer variables for this PackerTemplate.
def variables(self) -> dict:
"""Returns the variables of this :class:`PackerTemplate`.
"""
return self._variables
def set_parent(self, parent_template):
"""Set the parent template to this PackerTemplate.
def set_parent(self, parent_template: "PackerTemplate"):
"""Set the parent template to this :class:`PackerTemplate`.
This defines a relationship for future packer run in the sense that the child template will start directly from the image of
its parent template.
Parameters
----------
parent_template: :obj: `PackerTemplate`
The PackerTemplate of the parent template to connect the child template with.
parent_template: :class:`PackerTemplate`
The :class:`PackerTemplate` of the parent template to connect the child template with.
"""
......@@ -191,13 +148,13 @@ class PackerTemplate:
builder["iso_checksum_url"] = "none"
builder["output_directory"] = os.path.join(self._templates_dir,self._name)
def _load_packages(self, packages):
"""Load the non-standard package YAML file and append them as provisioners of this PackerTemplate.
def _load_packages(self, packages: List[str]):
"""Load the non-standard package YAML file and append them as provisioners of this :class:`PackerTemplate`.
Parameters
----------
list
The list of the packages to append.
The non-standard packages to append.
"""
# If *" is in the list, fetch all the packages
......@@ -237,13 +194,13 @@ class PackerTemplate:
# Extend the current provisioners list with the ones of the selected packages
self._provisioners.extend(manifest_data)
def dump(self, output_file, **kwargs):
def dump(self, output_file: str, **kwargs):
"""Dump this PackerTemplate to a file.
Parameters
----------
output_file: str
The path to the output json file for this PackerTemplate.
The path to the output json file for this :class:`PackerTemplate`.
"""
# Get the basename and the ext of the output_file
......@@ -271,13 +228,8 @@ class PackerTemplate:
with open(output_file, "w") as fout:
json.dump(yaml.safe_load(s), fout, **kwargs)
def __str__(self):
"""Returns fancy output for this PackerTemplate.
Returns
-------
str
The string that will result from a str call to a PackerTemplate object.
def __str__(self) -> str:
"""Returns the string representation for this :class:`PackerTemplate`.
"""
d = collections.OrderedDict()
......@@ -288,6 +240,3 @@ class PackerTemplate:
d["post-processors"] = self._postprocessors
return pprint.pformat(d)
#!/usr/bin/env python3
#################################################################
# This apps allows the creation of packer json file out of
# YAML template
# One of its main feature is to handle template inheritance
# which is not covered yet natively by packer
# To run the application:
# env_var_1 env_var_2 ... env_var_n rackman.py template.yml
# where env_var_1 ... env_var_n are environment variables
# passed at the command line level and template.yml is the YAML
# which contain the packer configuration
#################################################################
import collections
import os
import shutil
import subprocess
import yaml
from typing import List, Optional
from .PackerTemplate import PackerTemplate
class Packman:
"""This class implements the Packman engine for generating packer template json files and run packer optionally .
"""
def __init__(self, input_file, templates_base_dir):
def __init__(self, input_file: str, templates_base_dir: str) -> None:
"""Constructor.
Parameters
......@@ -73,6 +61,7 @@ class Packman:
def get_template(self, template_name):
"""Return the YAML contents of a given template.
:class:`.PackerTemplate`
Parameters
----------
......@@ -87,7 +76,7 @@ class Packman:
return self._templates[template_name] if isinstance(self._templates[template_name],dict) else {}
def _build_template(self, template_name):
def _build_template(self, template_name : str) -> PackerTemplate:
"""Build a PackerTemplate object from a template name.
Parameters
......@@ -97,7 +86,7 @@ class Packman:
Returns
-------
:class:`PackerTemplate`
:class:`.PackerTemplate`
The template object used by packman to build the manifest.json file.
"""
......@@ -125,7 +114,7 @@ class Packman:
return template
def _build_template_hierarchy(self, template_name, hierarchy):
def _build_template_hierarchy(self, template_name : str, hierarchy : List[str]):
"""Build a single template hierarchy.
A template can have a parent template. In that case for packer neig able to run on those templates,
......@@ -157,7 +146,7 @@ class Packman:
else:
self._build_template_hierarchy(extends, hierarchy)
def _build_config_hierarchy(self, selected_templates=None):
def _build_config_hierarchy(self, selected_templates : Optional[List[str]] = None):
"""Build the templates hierarchy.
A template can have a parent template. In that case for packer neig able to run on those templates,
......@@ -187,13 +176,13 @@ class Packman:
return config_hierarchy
def run(self, selected_templates=None, log=False):
def run(self, selected_templates : Optional[List[str]] = None, log : Optional[bool] = False):
"""Run packer on the generated manifest.json files.
Parameters
----------
selected_templates: list, optional
List of strings corresponding to the packer templates to ru with packer.
The packer templates to run with packer.
"""
# Check first that packer program is installed somewhere
......@@ -236,7 +225,7 @@ class Packman:
# cd back to the current dir
os.chdir(current_dir)
def build(self, selected_templates=None, **kwargs):
def build(self, selected_templates : Optional[List[str]] = None, **kwargs):
"""Build packer on the generated manifest.json files.
Parameters
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment