diff options
author | Lars Wirzenius <liw@liw.fi> | 2018-08-29 16:02:55 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2018-08-29 19:44:52 +0300 |
commit | 1dfe146d026ec59c25e6f3daf52ba680e0ffb529 (patch) | |
tree | 2ab14896fec59c819943d9865016273676119feb | |
parent | 62d0a8b089bf58c88811b2a668543f2bf88983d1 (diff) | |
download | vmdb2-1dfe146d026ec59c25e6f3daf52ba680e0ffb529.tar.gz |
Add: lvm2, luks plugins
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | lvm2.lukskey | 1 | ||||
-rw-r--r-- | lvm2.vmdb | 69 | ||||
-rw-r--r-- | vmdb/plugins/grub_plugin.py | 6 | ||||
-rw-r--r-- | vmdb/plugins/luks_plugin.py | 87 | ||||
-rw-r--r-- | vmdb/plugins/lvm2_plugin.py | 80 | ||||
-rw-r--r-- | without-tests | 1 |
7 files changed, 246 insertions, 0 deletions
@@ -28,6 +28,8 @@ Version 0.13.2+git, not yet released chroot, overwriting what the tarball has. This allows vmdb2 to work with a tarball generated in a different network location. +* Add plugins for doing full-disk encryption via cryptsetup, and LVM2. + Version 0.13.2, released 2018-05-06 ------------------------------------ diff --git a/lvm2.lukskey b/lvm2.lukskey new file mode 100644 index 0000000..9f592eb --- /dev/null +++ b/lvm2.lukskey @@ -0,0 +1 @@ +hunter2 diff --git a/lvm2.vmdb b/lvm2.vmdb new file mode 100644 index 0000000..284117b --- /dev/null +++ b/lvm2.vmdb @@ -0,0 +1,69 @@ +# This is a sample VMDB2 input file to specify a simple +# system that boots on a PC with BIOS. Uses LVM2. + +steps: + - mkimg: "{{ image }}" + size: 4G + + - mklabel: msdos + device: "{{ image }}" + + - mkpart: primary + device: "{{ image }}" + start: 1M + end: 100M + tag: /boot + + - mkpart: primary + device: "{{ image }}" + start: 100M + end: 2G + tag: /rootpv + + - cryptsetup: /rootpv + tag: rootpv_crypt + key-cmd: echo lvm2.lukskey + + - vgcreate: rootvg + physical: + - rootpv_crypt + + - lvcreate: rootvg + name: rootfs + size: 1G + + - mkfs: ext2 + partition: /boot + + - mkfs: ext4 + partition: rootfs + + - mount: /boot + + - mount: rootfs + + - unpack-rootfs: rootfs + + - debootstrap: stretch + mirror: http://deb.debian.org/debian + target: rootfs + unless: rootfs_unpacked + + - apt: install + packages: + - linux-image-amd64 + tag: rootfs + unless: rootfs_unpacked + + - cache-rootfs: rootfs + unless: rootfs_unpacked + + - chroot: rootfs + shell: | + sed -i '/^root:[^:]*:/s//root::/' /etc/passwd + echo pc-vmdb2 > /etc/hostname + + - grub: bios + tag: rootfs + image-dev: "{{ image }}" + console: serial diff --git a/vmdb/plugins/grub_plugin.py b/vmdb/plugins/grub_plugin.py index d5ffd3c..0025011 100644 --- a/vmdb/plugins/grub_plugin.py +++ b/vmdb/plugins/grub_plugin.py @@ -161,6 +161,7 @@ class GrubStepRunner(vmdb.StepRunnerInterface): ]) self.set_grub_cmdline_config(chroot, kernel_params) + self.add_grub_crypto_disk(chroot) if console == 'serial': self.add_grub_serial_console(chroot) @@ -255,3 +256,8 @@ class GrubStepRunner(vmdb.StepRunnerInterface): f.write('GRUB_TERMINAL=serial\n') f.write('GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 ' '--word=8 --parity=no --stop=1"\n') + + def add_grub_crypto_disk(self, chroot): + filename = self.chroot_path(chroot, '/etc/default/grub') + with open(filename, 'a') as f: + f.write('GRUB_ENABLE_CRYPTODISK=y\n') diff --git a/vmdb/plugins/luks_plugin.py b/vmdb/plugins/luks_plugin.py new file mode 100644 index 0000000..7d8ed3f --- /dev/null +++ b/vmdb/plugins/luks_plugin.py @@ -0,0 +1,87 @@ +# Copyright 2018 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 logging +import os +import tempfile + +import cliapp + +import vmdb + + +class LuksPlugin(cliapp.Plugin): + + def enable(self): + self.app.step_runners.add(CryptsetupStepRunner()) + + +class CryptsetupStepRunner(vmdb.StepRunnerInterface): + + def get_required_keys(self): + return ['cryptsetup'] + + def run(self, step, settings, state): + underlying = step['cryptsetup'] + crypt_name = step['tag'] + + state.tmp_key_file = None + key_file = step.get('key-file') + key_cmd = step.get('key-cmd') + if key_file is None and key_cmd is None: + raise Exception( + 'cryptsetup step MUST define one of key-file or key-cmd') + + if key_file is None: + output = vmdb.runcmd(['sh', '-c', key_cmd]) + output = output.decode('UTF-8') + key = output.splitlines()[0] + fd, key_file = tempfile.mkstemp() + state.tmp_key_file = key_file + os.close(fd) + open(key_file, 'w').write(key) + + dev = state.tags.get_dev(underlying) + if dev is None: + for t in state.tags.get_tags(): + logging.debug( + 'tag %r dev %r mp %r', t, state.tags.get_dev(t), + state.tags.get_mount_point(t)) + assert 0 + + vmdb.runcmd(['cryptsetup', 'luksFormat', dev, key_file]) + vmdb.runcmd( + ['cryptsetup', 'open', '--type', 'luks', '--key-file', key_file, dev, + crypt_name]) + + crypt_dev = '/dev/mapper/{}'.format(crypt_name) + assert os.path.exists(crypt_dev) + state.tags.append(crypt_name) + state.tags.set_dev(crypt_name, crypt_dev) + + def teardown(self, step, settings, state): + x = state.tmp_key_file + if x is not None and os.path.exists(x): + os.remove(x) + + underlying = step['cryptsetup'] + crypt_name = step['tag'] + + crypt_dev = '/dev/mapper/{}'.format(crypt_name) + vmdb.runcmd(['cryptsetup', 'close', crypt_dev]) diff --git a/vmdb/plugins/lvm2_plugin.py b/vmdb/plugins/lvm2_plugin.py new file mode 100644 index 0000000..405398c --- /dev/null +++ b/vmdb/plugins/lvm2_plugin.py @@ -0,0 +1,80 @@ +# Copyright 2018 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 cliapp + +import vmdb + + +class Lvm2Plugin(cliapp.Plugin): + + def enable(self): + self.app.step_runners.add(VgcreateStepRunner()) + self.app.step_runners.add(LvcreateStepRunner()) + + +class VgcreateStepRunner(vmdb.StepRunnerInterface): + + def get_required_keys(self): + return ['vgcreate', 'physical'] + + def run(self, step, settings, state): + vgname = self.get_vg(step) + physical = self.get_pv(step, state) + + for phys in physical: + vmdb.runcmd(['pvcreate', phys]) + vmdb.runcmd(['vgcreate', vgname] + physical) + + def teardown(self, step, settings, state): + vgname = self.get_vg(step) + physical = self.get_pv(step, state) + + vmdb.runcmd(['vgremove', '--force', vgname]) + for phys in physical: + vmdb.runcmd(['pvremove', phys]) + + def get_vg(self, step): + return step['vgcreate'] + + def get_pv(self, step, state): + return [ + state.tags.get_dev(tag) + for tag in step['physical'] + ] + + +class LvcreateStepRunner(vmdb.StepRunnerInterface): + + def get_required_keys(self): + return ['lvcreate'] + + def run(self, step, settings, state): + vgname = step['lvcreate'] + lvname = step['name'] + size = step['size'] + + vmdb.runcmd(['lvcreate', '--name', lvname, '--size', size, vgname]) + + lvdev = '/dev/{}/{}'.format(vgname, lvname) + assert os.path.exists(lvdev) + state.tags.append(lvname) + state.tags.set_dev(lvname, lvdev) diff --git a/without-tests b/without-tests index 49d0e5d..ce34a61 100644 --- a/without-tests +++ b/without-tests @@ -13,6 +13,7 @@ vmdb/plugins/echo_plugin.py vmdb/plugins/error_plugin.py vmdb/plugins/grub_plugin.py vmdb/plugins/kernel_plugin.py +vmdb/plugins/lvm2_plugin.py vmdb/plugins/mkfs_plugin.py vmdb/plugins/mkimg_plugin.py vmdb/plugins/mount_plugin.py |