diff options
author | Lars Wirzenius <liw@liw.fi> | 2020-09-04 09:44:41 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2020-09-05 08:23:02 +0300 |
commit | 9eb39c1db5e1327c5c22b0c02010512b178aaf28 (patch) | |
tree | b8b2aa0d1d0ccba32575fc0e2c0bba26b790b23b | |
parent | 4b6435b398cebf102b87e3c545a24b89bf3977cb (diff) | |
download | vmdb2-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.
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()) |