summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-09-24 09:38:23 +0300
committerLars Wirzenius <liw@liw.fi>2020-09-24 10:36:49 +0300
commit6187cb60a3a809abdb3ffa948df1a73c39cd6ceb (patch)
treecffc6e4062a1063838a0e50e4358e96547639abb
parent4beb979f545bf130caa1d7d7532f3759aa9f6e96 (diff)
downloadvmdb2-6187cb60a3a809abdb3ffa948df1a73c39cd6ceb.tar.gz
refactor: rewrite app.py to not use cliapp.Application
Also, related changes elsewhere.
-rw-r--r--vmdb/app.py158
-rw-r--r--vmdb/plugins/cache_rootfs_plugin.py6
-rw-r--r--vmdb/plugins/mkimg_plugin.py1
-rw-r--r--vmdb/plugins/unpack_rootfs_plugin.py3
-rw-r--r--yarns/100-mvp.yarn4
5 files changed, 132 insertions, 40 deletions
diff --git a/vmdb/app.py b/vmdb/app.py
index 3865bd2..ef12e51 100644
--- a/vmdb/app.py
+++ b/vmdb/app.py
@@ -16,44 +16,140 @@
# =*= License: GPL-3+ =*=
+import argparse
import logging
import os
import sys
-import cliapp
-
import vmdb
-class Vmdb2(cliapp.Application):
- def add_settings(self):
- self.settings.string(
- ["image"],
- "use existing image file/device FILE (use --output to create new file)",
- metavar="FILE",
+class Vmdb2:
+ def __init__(self, version):
+ self._version = version
+
+ def run(self):
+ args = self.parse_command_line()
+ vmdb.set_verbose_progress(args.verbose)
+ tvars = self.template_vars_from_args(args)
+
+ cmd = None
+ if args.version:
+ cmd = VersionCommand(self._version)
+ elif args.image or args.output:
+ if args.image:
+ cmd = ReuseImageCommand(args.image, args.specfile, args.rootfs_tarball)
+ else:
+ cmd = NewImageCommand(args.output, args.specfile, args.rootfs_tarball)
+ builder = cmd.builder()
+ builder.add_template_vars(tvars)
+
+ if cmd is None:
+ sys.exit("I don't know what to do, re-run with --help")
+
+ if args.log:
+ self.setup_logging(args.log)
+ self.log_startup()
+ try:
+ cmd.run()
+ except Exception as e:
+ logging.error(f"ERROR: {e}", exc_info=True)
+ sys.exit(f"ERROR: {e}\n")
+ logging.debug("Ending, all OK")
+
+ def parse_command_line(self):
+ p = argparse.ArgumentParser(
+ description="build disk images with Debian installed"
)
- self.settings.boolean(["verbose", "v"], "verbose output")
+ p.add_argument("--image", metavar="FILE")
+ p.add_argument("--output", metavar="FILE")
+ p.add_argument("--rootfs-tarball", metavar="FILE")
+ p.add_argument("-v", "--verbose", action="store_true")
+ p.add_argument("--log")
+ p.add_argument("--version", action="store_true")
+ p.add_argument("specfile")
- def setup(self):
- self.step_runners = vmdb.StepRunnerList()
- plugindir = os.path.join(os.path.dirname(vmdb.__file__), "plugins")
- for klass in vmdb.find_plugins(plugindir, "Plugin"):
- klass(self).enable()
+ return p.parse_args()
+
+ def setup_logging(self, filename):
+ fmt = "%(asctime)s %(levelname)s %(message)s"
+ datefmt = "%Y-%m-%d %H:%M:%S"
+ formatter = logging.Formatter(fmt, datefmt)
+
+ handler = logging.FileHandler(filename)
+ handler.setFormatter(formatter)
+
+ logger = logging.getLogger()
+ logger.addHandler(handler)
+ logger.setLevel(logging.DEBUG)
+
+ def log_startup(self):
+ logging.info(f"Starting vmdb2 version {self._version}")
+
+ def template_vars_from_args(self, args):
+ return {
+ "image": args.image,
+ "output": args.output,
+ "rootfs_tarball": args.rootfs_tarball,
+ }
+
+
+class Command:
+ def run(self):
+ raise NotImplementedError()
+
+
+class VersionCommand(Command):
+ def __init__(self, version):
+ self.version = version
+
+ def run(self):
+ sys.stdout.write("{}\n".format(self.version))
- def process_args(self, args):
- if len(args) != 1:
- sys.exit("No image specification was given on the command line.")
- vmdb.set_verbose_progress(self.settings["verbose"])
+class NewImageCommand(Command):
+ def __init__(self, filename, specfile, tarball):
+ self._builder = ImageBuilder(filename, specfile, tarball)
- spec = self.load_spec_file(args[0])
+ def builder(self):
+ return self._builder
+
+ def run(self):
+ # FIXME: create file
+ self._builder.build()
+
+
+class ReuseImageCommand(Command):
+ def __init__(self, filename, specfile, tarball):
+ self._builder = ImageBuilder(filename, specfile, tarball)
+
+ def builder(self):
+ return self._builder
+
+ def run(self):
+ self._builder.build()
+
+
+class ImageBuilder:
+ def __init__(self, filename, specfile, tarball):
+ self._filename = filename
+ self._specfile = specfile
+ self._tarball = tarball
+ self._tvars = {}
+
+ def add_template_vars(self, tvars):
+ self._tvars.update(tvars)
+
+ def build(self):
+ spec = self.load_spec_file(self._specfile)
state = vmdb.State()
state.tags = vmdb.Tags()
- params = self.create_template_vars(state)
- steps = spec.get_steps(params)
+ self.add_template_vars(state.as_dict())
+ steps = spec.get_steps(self._tvars)
# Check that we have step runners for each step
+ self.load_step_runners()
for step in steps:
self.step_runners.find(step)
@@ -66,7 +162,7 @@ class Vmdb2(cliapp.Application):
vmdb.progress("All went fine.")
if core_meltdown:
- logging.error("An error occurred, exiting with non-zero exit code")
+ logging.error("An error occurred, exiting")
sys.exit(1)
def load_spec_file(self, filename):
@@ -80,6 +176,12 @@ class Vmdb2(cliapp.Application):
spec.load_file(f)
return spec
+ def load_step_runners(self):
+ self.step_runners = vmdb.StepRunnerList()
+ plugindir = os.path.join(os.path.dirname(vmdb.__file__), "plugins")
+ for klass in vmdb.find_plugins(plugindir, "Plugin"):
+ klass(self).enable()
+
def run_steps(self, steps, state):
return self.run_steps_helper(steps, state, "Running step: %r", "run", False)
@@ -91,6 +193,7 @@ class Vmdb2(cliapp.Application):
def run_steps_helper(self, steps, state, msg, method_name, keep_going):
core_meltdown = False
steps_taken = []
+ settings = {"rootfs-tarball": self._tarball}
even_if_skipped = method_name + "_even_if_skipped"
for step in steps:
@@ -98,7 +201,7 @@ class Vmdb2(cliapp.Application):
logging.info(msg, step)
steps_taken.append(step)
runner = self.step_runners.find(step)
- if runner.skip(step, self.settings, state):
+ if runner.skip(step, settings, state):
logging.info("Skipping as requested by unless")
method_names = [even_if_skipped]
else:
@@ -113,7 +216,7 @@ class Vmdb2(cliapp.Application):
values = runner.get_values(step)
for method in methods:
logging.info("Calling %s", method)
- method(values, self.settings, state)
+ method(values, settings, state)
except KeyError as e:
vmdb.error("Key error: %s" % str(e))
vmdb.error(repr(e))
@@ -128,10 +231,3 @@ class Vmdb2(cliapp.Application):
break
return steps_taken, core_meltdown
-
- def create_template_vars(self, state):
- vars = dict()
- for key in self.settings:
- vars[key] = self.settings[key]
- vars.update(state.as_dict())
- return vars
diff --git a/vmdb/plugins/cache_rootfs_plugin.py b/vmdb/plugins/cache_rootfs_plugin.py
index 8dde628..c7ebb6d 100644
--- a/vmdb/plugins/cache_rootfs_plugin.py
+++ b/vmdb/plugins/cache_rootfs_plugin.py
@@ -23,12 +23,6 @@ import vmdb
class CacheRootFSPlugin(vmdb.Plugin):
def enable(self):
- self.app.settings.string(
- ["rootfs-tarball"],
- "store rootfs cache tar archives in FILE",
- metavar="FILE",
- )
-
self.app.step_runners.add(MakeCacheStepRunner())
diff --git a/vmdb/plugins/mkimg_plugin.py b/vmdb/plugins/mkimg_plugin.py
index dafffee..f33450c 100644
--- a/vmdb/plugins/mkimg_plugin.py
+++ b/vmdb/plugins/mkimg_plugin.py
@@ -22,7 +22,6 @@ import vmdb
class MkimgPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(MkimgStepRunner())
- self.app.settings.bytesize(["size"], "size of output image", default="1GiB")
class MkimgStepRunner(vmdb.StepRunnerInterface):
diff --git a/vmdb/plugins/unpack_rootfs_plugin.py b/vmdb/plugins/unpack_rootfs_plugin.py
index 5fd0d7c..ec0ae6a 100644
--- a/vmdb/plugins/unpack_rootfs_plugin.py
+++ b/vmdb/plugins/unpack_rootfs_plugin.py
@@ -16,6 +16,7 @@
# =*= License: GPL-3+ =*=
+import logging
import os
import vmdb
@@ -33,7 +34,9 @@ class UnpackCacheStepRunner(vmdb.StepRunnerInterface):
def run(self, values, settings, state):
fs_tag = values["unpack-rootfs"]
rootdir = state.tags.get_builder_mount_point(fs_tag)
+ logging.debug(f"settings: {settings}")
tar_path = settings["rootfs-tarball"]
+ logging.debug(f"tar_path: {tar_path!r}")
if not tar_path:
raise Exception("--rootfs-tarball MUST be set")
if os.path.exists(tar_path):
diff --git a/yarns/100-mvp.yarn b/yarns/100-mvp.yarn
index b66c794..9ebb650 100644
--- a/yarns/100-mvp.yarn
+++ b/yarns/100-mvp.yarn
@@ -114,7 +114,7 @@ the step mounts a filesystem, the teardown would unmount it.
... { echo: "bar", teardown: "bar_teardown" }
... ]
... }
- WHEN user runs vmdb2 -v happy.vmdb
+ WHEN user runs vmdb2 -v happy.vmdb --output happy.img
THEN exit code is 0
AND stdout contains "foo" followed by "bar"
AND stdout contains "bar" followed by "bar_teardown"
@@ -159,7 +159,7 @@ then?
... { echo: "bar_step", teardown: "bar_teardown" }
... ]
... }
- WHEN user runs vmdb2 -v unhappy.vmdb
+ WHEN user runs vmdb2 -v unhappy.vmdb --output=unhappy.img
THEN exit code is 1
AND stdout contains "foo" followed by "yikes"
AND stdout contains "yikes" followed by "WAT?!"