summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-09-04 09:44:41 +0300
committerLars Wirzenius <liw@liw.fi>2020-09-05 08:23:02 +0300
commit9eb39c1db5e1327c5c22b0c02010512b178aaf28 (patch)
treeb8b2aa0d1d0ccba32575fc0e2c0bba26b790b23b
parent4b6435b398cebf102b87e3c545a24b89bf3977cb (diff)
downloadvmdb2-9eb39c1db5e1327c5c22b0c02010512b178aaf28.tar.gz
refactor(plugins): replace cliapp's plugin infra with a custom one
Previously, we were using the plugin system in the cliapp library. However, as we want to drop depenendency on cliapp, we can't do that in the future. This commit adds a new plugin system. Because all the plugins (vmdb/plugins/*.py) need to be changed for the new system, the diff is pretty long, but most of it is just obvious mechanical changes.
-rw-r--r--vmdb/__init__.py1
-rw-r--r--vmdb/app.py3
-rw-r--r--vmdb/plugin.py56
-rw-r--r--vmdb/plugin_tests.py62
-rw-r--r--vmdb/plugins/__init__.py2
-rw-r--r--vmdb/plugins/ansible_plugin.py7
-rw-r--r--vmdb/plugins/apt_plugin.py7
-rw-r--r--vmdb/plugins/cache_rootfs_plugin.py4
-rw-r--r--vmdb/plugins/chroot_plugin.py6
-rw-r--r--vmdb/plugins/copy_file_plugin.py3
-rw-r--r--vmdb/plugins/create_dir_plugin.py3
-rw-r--r--vmdb/plugins/create_file_plugin.py3
-rw-r--r--vmdb/plugins/debootstrap_plugin.py4
-rw-r--r--vmdb/plugins/echo_plugin.py4
-rw-r--r--vmdb/plugins/error_plugin.py4
-rw-r--r--vmdb/plugins/fstab_plugin.py4
-rw-r--r--vmdb/plugins/grub_plugin.py5
-rw-r--r--vmdb/plugins/kpartx_plugin.py7
-rw-r--r--vmdb/plugins/luks_plugin.py4
-rw-r--r--vmdb/plugins/lvcreate_plugin.py4
-rw-r--r--vmdb/plugins/mkfs_plugin.py4
-rw-r--r--vmdb/plugins/mkimg_plugin.py4
-rw-r--r--vmdb/plugins/mklabel_plugin.py7
-rw-r--r--vmdb/plugins/mkpart_plugin.py6
-rw-r--r--vmdb/plugins/mount_plugin.py4
-rw-r--r--vmdb/plugins/qemudebootstrap_plugin.py4
-rw-r--r--vmdb/plugins/shell_plugin.py4
-rw-r--r--vmdb/plugins/unpack_rootfs_plugin.py4
-rw-r--r--vmdb/plugins/vgcreate_plugin.py6
-rw-r--r--vmdb/plugins/virtualfs_plugin.py4
30 files changed, 146 insertions, 94 deletions
diff --git a/vmdb/__init__.py b/vmdb/__init__.py
index b4a9582..418d9f6 100644
--- a/vmdb/__init__.py
+++ b/vmdb/__init__.py
@@ -41,4 +41,5 @@ from .tags import (
)
from .unmount import unmount, NotMounted
from .spec import Spec, expand_templates
+from .plugin import Plugin, find_plugins
from .app import Vmdb2
diff --git a/vmdb/app.py b/vmdb/app.py
index 2376116..dac62b7 100644
--- a/vmdb/app.py
+++ b/vmdb/app.py
@@ -17,6 +17,7 @@
import logging
+import os
import sys
import cliapp
@@ -36,6 +37,8 @@ class Vmdb2(cliapp.Application):
def setup(self):
self.step_runners = vmdb.StepRunnerList()
+ plugindir = os.path.join(os.path.dirname(vmdb.__file__), "plugins")
+ plugins = [klass(self).enable() for klass in vmdb.find_plugins(plugindir, "Plugin")]
def process_args(self, args):
if len(args) != 1:
diff --git a/vmdb/plugin.py b/vmdb/plugin.py
new file mode 100644
index 0000000..7eb7109
--- /dev/null
+++ b/vmdb/plugin.py
@@ -0,0 +1,56 @@
+# Copyright 2020 Lars Wirzenius
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# =*= License: GPL-3+ =*=
+
+
+import importlib.util
+import os
+
+
+class Plugin:
+ def __init__(self, app):
+ self.app = app
+
+
+def find_plugins(dirname, namesuffix):
+ suffix = "_plugin.py"
+ filenames = _find_suffixed_files(dirname, suffix)
+ plugins = []
+ for filename in filenames:
+ for c in _classes_in_file(filename, namesuffix):
+ plugins.append(c)
+
+ return plugins
+
+
+def _find_suffixed_files(dirname, suffix):
+ return [
+ os.path.join(dirname, basename)
+ for basename in os.listdir(dirname)
+ if basename.endswith(suffix)
+ ]
+
+
+def _classes_in_file(filename, namesuffix):
+ module_name = os.path.basename(filename)[: -len(".py")]
+ spec = importlib.util.spec_from_file_location(module_name, filename)
+ module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(module)
+ classes = []
+ for name in dir(module):
+ if name.endswith(namesuffix):
+ classes.append(module.__getattribute__(name))
+ return classes
diff --git a/vmdb/plugin_tests.py b/vmdb/plugin_tests.py
new file mode 100644
index 0000000..1a70ca7
--- /dev/null
+++ b/vmdb/plugin_tests.py
@@ -0,0 +1,62 @@
+# Copyright 2020 Lars Wirzenius
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# =*= License: GPL-3+ =*=
+
+
+import os
+import shutil
+import tempfile
+import unittest
+
+
+import vmdb
+
+
+class PluginTests(unittest.TestCase):
+ def test_sets_app(self):
+ plugin = vmdb.Plugin("foo")
+ self.assertEqual(plugin.app, "foo")
+
+
+class FindPluginsTests(unittest.TestCase):
+ def setUp(self):
+ self.dirname = tempfile.mkdtemp()
+
+ def tearDown(self):
+ shutil.rmtree(self.dirname)
+
+ def tests_finds_no_plugins_in_empty_directory(self):
+ self.assertEqual(vmdb.find_plugins(self.dirname, ""), [])
+
+ def tests_finds_no_plugins_when_there_are_other_files(self):
+ open(os.path.join(self.dirname, "file.py"), "w").close()
+ self.assertEqual(vmdb.find_plugins(self.dirname, ""), [])
+
+ def tests_finds_no_plugin_when_file_has_none(self):
+ open(os.path.join(self.dirname, "foo_plugin.py"), "w").close()
+ self.assertEqual(vmdb.find_plugins(self.dirname, "Plugin"), [])
+
+ def tests_finds_plugin_when_there_is_one(self):
+ with open(os.path.join(self.dirname, "foo_plugin.py"), "w") as f:
+ f.write(
+ """
+class FooPlugin:
+ pass
+"""
+ )
+
+ plugins = vmdb.find_plugins(self.dirname, "Plugin")
+ self.assertEqual(len(plugins), 1)
diff --git a/vmdb/plugins/__init__.py b/vmdb/plugins/__init__.py
deleted file mode 100644
index 5cb230b..0000000
--- a/vmdb/plugins/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# This file exists to make vmdb.plugins be a Python package, so it can
-# be installed by setup.py.
diff --git a/vmdb/plugins/ansible_plugin.py b/vmdb/plugins/ansible_plugin.py
index 867a554..fa50698 100644
--- a/vmdb/plugins/ansible_plugin.py
+++ b/vmdb/plugins/ansible_plugin.py
@@ -19,16 +19,9 @@
import os
import tempfile
-import cliapp
-
import vmdb
-class AnsiblePlugin(cliapp.Plugin):
- def enable(self):
- self.app.step_runners.add(AnsibleStepRunner())
-
-
class AnsibleStepRunner(vmdb.StepRunnerInterface):
def get_key_spec(self):
return {"ansible": str, "playbook": str}
diff --git a/vmdb/plugins/apt_plugin.py b/vmdb/plugins/apt_plugin.py
index f2547c7..56d40a5 100644
--- a/vmdb/plugins/apt_plugin.py
+++ b/vmdb/plugins/apt_plugin.py
@@ -18,16 +18,9 @@
import os
-import cliapp
-
import vmdb
-class AptPlugin(cliapp.Plugin):
- def enable(self):
- self.app.step_runners.add(AptStepRunner())
-
-
class AptStepRunner(vmdb.StepRunnerInterface):
def get_key_spec(self):
return {"apt": str, "packages": [], "tag": "", "fs-tag": "", "clean": True}
diff --git a/vmdb/plugins/cache_rootfs_plugin.py b/vmdb/plugins/cache_rootfs_plugin.py
index 316de8b..8dde628 100644
--- a/vmdb/plugins/cache_rootfs_plugin.py
+++ b/vmdb/plugins/cache_rootfs_plugin.py
@@ -18,12 +18,10 @@
import os
-import cliapp
-
import vmdb
-class CacheRootFSPlugin(cliapp.Plugin):
+class CacheRootFSPlugin(vmdb.Plugin):
def enable(self):
self.app.settings.string(
["rootfs-tarball"],
diff --git a/vmdb/plugins/chroot_plugin.py b/vmdb/plugins/chroot_plugin.py
index 7aab1aa..df0c555 100644
--- a/vmdb/plugins/chroot_plugin.py
+++ b/vmdb/plugins/chroot_plugin.py
@@ -16,14 +16,10 @@
# =*= License: GPL-3+ =*=
-import os
-
-import cliapp
-
import vmdb
-class ChrootPlugin(cliapp.Plugin):
+class ChrootPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(ChrootStepRunner())
diff --git a/vmdb/plugins/copy_file_plugin.py b/vmdb/plugins/copy_file_plugin.py
index 3c3d0e5..280cb47 100644
--- a/vmdb/plugins/copy_file_plugin.py
+++ b/vmdb/plugins/copy_file_plugin.py
@@ -15,13 +15,12 @@
#
# =*= License: GPL-3+ =*=
-import cliapp
import vmdb
import os
import logging
-class CopyFilePlugin(cliapp.Plugin):
+class CopyFilePlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(CopyFileStepRunner())
diff --git a/vmdb/plugins/create_dir_plugin.py b/vmdb/plugins/create_dir_plugin.py
index 51f22a3..8cc5df3 100644
--- a/vmdb/plugins/create_dir_plugin.py
+++ b/vmdb/plugins/create_dir_plugin.py
@@ -15,13 +15,12 @@
#
# =*= License: GPL-3+ =*=
-import cliapp
import vmdb
import os
import logging
-class CreateDirPlugin(cliapp.Plugin):
+class CreateDirPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(CreateDirStepRunner())
diff --git a/vmdb/plugins/create_file_plugin.py b/vmdb/plugins/create_file_plugin.py
index b332e64..243156a 100644
--- a/vmdb/plugins/create_file_plugin.py
+++ b/vmdb/plugins/create_file_plugin.py
@@ -15,13 +15,12 @@
#
# =*= License: GPL-3+ =*=
-import cliapp
import vmdb
import os
import logging
-class CreateFilePlugin(cliapp.Plugin):
+class CreateFilePlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(CreateFileStepRunner())
diff --git a/vmdb/plugins/debootstrap_plugin.py b/vmdb/plugins/debootstrap_plugin.py
index a0db6e1..63579e5 100644
--- a/vmdb/plugins/debootstrap_plugin.py
+++ b/vmdb/plugins/debootstrap_plugin.py
@@ -16,12 +16,10 @@
# =*= License: GPL-3+ =*=
-import cliapp
-
import vmdb
-class DebootstrapPlugin(cliapp.Plugin):
+class DebootstrapPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(DebootstrapStepRunner())
diff --git a/vmdb/plugins/echo_plugin.py b/vmdb/plugins/echo_plugin.py
index 312a5d7..bc2adb3 100644
--- a/vmdb/plugins/echo_plugin.py
+++ b/vmdb/plugins/echo_plugin.py
@@ -18,12 +18,10 @@
import logging
-import cliapp
-
import vmdb
-class EchoPlugin(cliapp.Plugin):
+class EchoPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(EchoStepRunner())
diff --git a/vmdb/plugins/error_plugin.py b/vmdb/plugins/error_plugin.py
index f90d8c0..71f3a6f 100644
--- a/vmdb/plugins/error_plugin.py
+++ b/vmdb/plugins/error_plugin.py
@@ -16,12 +16,10 @@
# =*= License: GPL-3+ =*=
-import cliapp
-
import vmdb
-class ErrorPlugin(cliapp.Plugin):
+class ErrorPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(ErrorStepRunner())
diff --git a/vmdb/plugins/fstab_plugin.py b/vmdb/plugins/fstab_plugin.py
index 974fc56..de21ed7 100644
--- a/vmdb/plugins/fstab_plugin.py
+++ b/vmdb/plugins/fstab_plugin.py
@@ -17,12 +17,10 @@
import os
-import cliapp
-
import vmdb
-class FstabPlugin(cliapp.Plugin):
+class FstabPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(FstabStepRunner())
diff --git a/vmdb/plugins/grub_plugin.py b/vmdb/plugins/grub_plugin.py
index 29af435..b081098 100644
--- a/vmdb/plugins/grub_plugin.py
+++ b/vmdb/plugins/grub_plugin.py
@@ -73,12 +73,10 @@ import logging
import os
import re
-import cliapp
-
import vmdb
-class GrubPlugin(cliapp.Plugin):
+class GrubPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(GrubStepRunner())
@@ -87,7 +85,6 @@ class GrubStepRunner(vmdb.StepRunnerInterface):
def get_key_spec(self):
return {
"grub": str,
- "tag": str,
"root-fs": "",
"efi": "",
"efi-part": "",
diff --git a/vmdb/plugins/kpartx_plugin.py b/vmdb/plugins/kpartx_plugin.py
index d1f4840..6303552 100644
--- a/vmdb/plugins/kpartx_plugin.py
+++ b/vmdb/plugins/kpartx_plugin.py
@@ -16,15 +16,10 @@
# =*= License: GPL-3+ =*=
-import os
-import stat
-
-import cliapp
-
import vmdb
-class KpartxPlugin(cliapp.Plugin):
+class KpartxPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(KpartxStepRunner())
diff --git a/vmdb/plugins/luks_plugin.py b/vmdb/plugins/luks_plugin.py
index 946893e..a28c296 100644
--- a/vmdb/plugins/luks_plugin.py
+++ b/vmdb/plugins/luks_plugin.py
@@ -20,12 +20,10 @@ import logging
import os
import tempfile
-import cliapp
-
import vmdb
-class LuksPlugin(cliapp.Plugin):
+class LuksPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(CryptsetupStepRunner())
diff --git a/vmdb/plugins/lvcreate_plugin.py b/vmdb/plugins/lvcreate_plugin.py
index 1d3de33..8eee9f4 100644
--- a/vmdb/plugins/lvcreate_plugin.py
+++ b/vmdb/plugins/lvcreate_plugin.py
@@ -18,12 +18,10 @@
import os
-import cliapp
-
import vmdb
-class LvcreatePlugin(cliapp.Plugin):
+class LvcreatePlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(LvcreateStepRunner())
diff --git a/vmdb/plugins/mkfs_plugin.py b/vmdb/plugins/mkfs_plugin.py
index 17bf88e..e204fa6 100644
--- a/vmdb/plugins/mkfs_plugin.py
+++ b/vmdb/plugins/mkfs_plugin.py
@@ -16,12 +16,10 @@
# =*= License: GPL-3+ =*=
-import cliapp
-
import vmdb
-class MkfsPlugin(cliapp.Plugin):
+class MkfsPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(MkfsStepRunner())
diff --git a/vmdb/plugins/mkimg_plugin.py b/vmdb/plugins/mkimg_plugin.py
index 75d00ed..dafffee 100644
--- a/vmdb/plugins/mkimg_plugin.py
+++ b/vmdb/plugins/mkimg_plugin.py
@@ -16,12 +16,10 @@
# =*= License: GPL-3+ =*=
-import cliapp
-
import vmdb
-class MkimgPlugin(cliapp.Plugin):
+class MkimgPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(MkimgStepRunner())
self.app.settings.bytesize(["size"], "size of output image", default="1GiB")
diff --git a/vmdb/plugins/mklabel_plugin.py b/vmdb/plugins/mklabel_plugin.py
index c455394..99ef0a9 100644
--- a/vmdb/plugins/mklabel_plugin.py
+++ b/vmdb/plugins/mklabel_plugin.py
@@ -16,15 +16,10 @@
# =*= License: GPL-3+ =*=
-import os
-import stat
-
-import cliapp
-
import vmdb
-class MklabelPlugin(cliapp.Plugin):
+class MklabelPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(MklabelStepRunner())
diff --git a/vmdb/plugins/mkpart_plugin.py b/vmdb/plugins/mkpart_plugin.py
index 787bd05..30305da 100644
--- a/vmdb/plugins/mkpart_plugin.py
+++ b/vmdb/plugins/mkpart_plugin.py
@@ -20,12 +20,10 @@ import os
import stat
import time
-import cliapp
-
import vmdb
-class MkpartPlugin(cliapp.Plugin):
+class MkpartPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(MkpartStepRunner())
@@ -99,7 +97,7 @@ class MkpartStepRunner(vmdb.StepRunnerInterface):
time.sleep(1)
-class MkpartError(cliapp.AppException):
+class MkpartError(Exception):
pass
diff --git a/vmdb/plugins/mount_plugin.py b/vmdb/plugins/mount_plugin.py
index f50de11..b8102a6 100644
--- a/vmdb/plugins/mount_plugin.py
+++ b/vmdb/plugins/mount_plugin.py
@@ -20,12 +20,10 @@ import logging
import os
import tempfile
-import cliapp
-
import vmdb
-class MountPlugin(cliapp.Plugin):
+class MountPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(MountStepRunner())
diff --git a/vmdb/plugins/qemudebootstrap_plugin.py b/vmdb/plugins/qemudebootstrap_plugin.py
index 01184a3..2915cc8 100644
--- a/vmdb/plugins/qemudebootstrap_plugin.py
+++ b/vmdb/plugins/qemudebootstrap_plugin.py
@@ -16,12 +16,10 @@
# =*= License: GPL-3+ =*=
-import cliapp
-
import vmdb
-class QemuDebootstrapPlugin(cliapp.Plugin):
+class QemuDebootstrapPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(QemuDebootstrapStepRunner())
diff --git a/vmdb/plugins/shell_plugin.py b/vmdb/plugins/shell_plugin.py
index b9e516a..51dce4b 100644
--- a/vmdb/plugins/shell_plugin.py
+++ b/vmdb/plugins/shell_plugin.py
@@ -18,12 +18,10 @@
import os
-import cliapp
-
import vmdb
-class ShellPlugin(cliapp.Plugin):
+class ShellPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(ShellStepRunner())
diff --git a/vmdb/plugins/unpack_rootfs_plugin.py b/vmdb/plugins/unpack_rootfs_plugin.py
index c8b7649..5fd0d7c 100644
--- a/vmdb/plugins/unpack_rootfs_plugin.py
+++ b/vmdb/plugins/unpack_rootfs_plugin.py
@@ -18,12 +18,10 @@
import os
-import cliapp
-
import vmdb
-class UnpackRootFSPlugin(cliapp.Plugin):
+class UnpackRootFSPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(UnpackCacheStepRunner())
diff --git a/vmdb/plugins/vgcreate_plugin.py b/vmdb/plugins/vgcreate_plugin.py
index d979918..ebcd27d 100644
--- a/vmdb/plugins/vgcreate_plugin.py
+++ b/vmdb/plugins/vgcreate_plugin.py
@@ -16,14 +16,10 @@
# =*= License: GPL-3+ =*=
-import os
-
-import cliapp
-
import vmdb
-class VgcreatePlugin(cliapp.Plugin):
+class VgcreatePlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(VgcreateStepRunner())
diff --git a/vmdb/plugins/virtualfs_plugin.py b/vmdb/plugins/virtualfs_plugin.py
index 7693d5c..9f440f8 100644
--- a/vmdb/plugins/virtualfs_plugin.py
+++ b/vmdb/plugins/virtualfs_plugin.py
@@ -19,12 +19,10 @@
import logging
import os
-import cliapp
-
import vmdb
-class VirtualFilesystemMountPlugin(cliapp.Plugin):
+class VirtualFilesystemMountPlugin(vmdb.Plugin):
def enable(self):
self.app.step_runners.add(VirtualFilesystemMountStepRunner())