Commit 6a52dda9 authored by Lars Wirzenius's avatar Lars Wirzenius

Change: systematize how tags are used

parent bbf93e52
......@@ -9,37 +9,35 @@ steps:
device: "{{ output }}"
start: 0%
end: 100%
part-tag: root-part
tag: rootfs
- mkfs: ext4
partition: root-part
partition: rootfs
label: smoke
- mount: root-part
fs-tag: root-fs
- mount: rootfs
- unpack-rootfs: root-fs
- unpack-rootfs: rootfs
- debootstrap: stretch
mirror: http://deb.debian.org/debian
target: root-fs
target: rootfs
unless: rootfs_unpacked
- apt: install
packages:
- linux-image-amd64
fs-tag: root-fs
tag: rootfs
unless: rootfs_unpacked
- cache-rootfs: root-fs
- cache-rootfs: rootfs
unless: rootfs_unpacked
- chroot: root-fs
- chroot: rootfs
shell: |
sed -i '/^root:[^:]*:/s//root::/' /etc/passwd
echo pc-vmdb2 > /etc/hostname
- grub: bios
root-fs: root-fs
root-part: root-part
tag: rootfs
console: serial
......@@ -46,6 +46,5 @@ steps:
unless: rootfs_unpacked
- grub: uefi
root-fs: root-fs
root-part: root-part
rootfs: root-fs
efi-part: efi-part
......@@ -47,6 +47,7 @@ class Vmdb2(cliapp.Application):
spec = self.load_spec_file(args[0])
state = vmdb.State()
state.tags = vmdb.Image()
params = self.create_template_vars(state)
steps = spec.get_steps(params)
......
......@@ -33,6 +33,9 @@ class Image:
def get_tags(self):
return list(self._tags.keys())
def has_tag(self, tag):
return tag in self._tags
def get_dev(self, tag):
item = self._tags.get(tag)
if item is None:
......
......@@ -28,6 +28,12 @@ class ImageTests(unittest.TestCase):
image = vmdb.Image()
self.assertEqual(image.get_tags(), [])
def test_tells_if_tag_is_used(self):
image = vmdb.Image()
self.assertFalse(image.has_tag('foo'))
image.add_partition('foo', 'bar')
self.assertTrue(image.has_tag('foo'))
def test_get_dev_raises_error_for_unknown_tag(self):
image = vmdb.Image()
with self.assertRaises(vmdb.UnknownTag):
......
......@@ -37,13 +37,9 @@ class AnsibleStepRunner(vmdb.StepRunnerInterface):
return ['ansible', 'playbook']
def run(self, step, settings, state):
fstag = step['ansible']
tag = step['ansible']
playbook = step['playbook']
mount_point = state.mounts[fstag]
vmdb.progress(
'Running ansible playbook {} on filesystem at {} ({})'.format(
playbook, mount_point, fstag))
mount_point = state.tags.get_mount_point(tag)
state.ansible_inventory = self.create_inventory(mount_point)
vmdb.progress(
......
......@@ -33,7 +33,7 @@ class AptPlugin(cliapp.Plugin):
class AptStepRunner(vmdb.StepRunnerInterface):
def get_required_keys(self):
return ['apt', 'fs-tag', 'packages']
return ['apt', 'tag', 'packages']
def run(self, step, settings, state):
operation = step['apt']
......@@ -41,8 +41,8 @@ class AptStepRunner(vmdb.StepRunnerInterface):
raise Exception('"apt" must always have value "install"')
packages = step['packages']
fstag = step['fs-tag']
mount_point = state.mounts[fstag]
tag = step['tag']
mount_point = state.tags.get_mount_point(tag)
if not self.got_eatmydata(state):
self.install_packages(mount_point, [], ['eatmydata'])
......
......@@ -40,10 +40,7 @@ class ChrootStepRunner(vmdb.StepRunnerInterface):
fs_tag = step['chroot']
shell = step['shell']
mount_point = state.mounts[fs_tag]
vmdb.progress(
'chroot {} to {}'.format(mount_point, ' '.join(shell.split('\n'))))
mount_point = state.tags.get_mount_point(fs_tag)
vmdb.runcmd_chroot(mount_point, ['sh', '-c', shell])
......@@ -59,5 +56,5 @@ class ShellStepRunner(vmdb.StepRunnerInterface):
vmdb.progress(
'run shell {}'.format(' '.join(shell.split('\n'))))
env = dict(os.environ)
env['ROOT'] = state.mounts[fs_tag]
env['ROOT'] = state.get_mount_point(fs_tag)
vmdb.runcmd(['sh', '-c', shell], env=env)
......@@ -36,7 +36,7 @@ class DebootstrapStepRunner(vmdb.StepRunnerInterface):
def run(self, step, settings, state):
suite = step['debootstrap']
tag = step['target']
target = state.mounts[tag]
target = state.get_mount_point(tag)
mirror = step['mirror']
variant = step.get('variant', '-')
if not (suite and tag and target and mirror):
......
......@@ -60,17 +60,16 @@
# root filesystem. Then install grub with a step like this:
#
# - grub: uefi
# root-fs: root-fs
# root-part: root-part
# efi-part: efi-part
# tag: root-part
# efi: efi-part
#
# Here: root-fs is the tag for the root filesystem, root-part is the
# tag for the partition with the root filesystem, and efi-part is tag
# for the EFI partition.
# Here: "tag" is the tag for the root filesystem (and corresponding
# partition), and efi is tag for the EFI partition.
#
# The grub step will take of the rest.
import logging
import os
import re
......@@ -88,9 +87,10 @@ class GrubPlugin(cliapp.Plugin):
class GrubStepRunner(vmdb.StepRunnerInterface):
def get_required_keys(self):
return ['grub', 'root-fs']
return ['grub', 'tag']
def run(self, step, settings, state):
state.grub_mounts = []
flavor = step['grub']
if flavor == 'uefi':
self.install_uefi(step, settings, state)
......@@ -100,18 +100,16 @@ class GrubStepRunner(vmdb.StepRunnerInterface):
raise Exception('Unknown GRUB flavor {}'.format(flavor))
def install_uefi(self, step, settings, state):
vmdb.progress('Installing GRUB for UEFI')
if not 'efi-part' in step:
raise Exception('"efi-part" is required in UEFI GRUB installtion')
if not 'efi' in step:
raise Exception('"efi" is required in UEFI GRUB installtion')
vmdb.progress('Installing GRUB for UEFI')
grub_package = 'grub-efi-amd64'
grub_target = 'x86_64-efi'
self.install_grub(step, settings, state, grub_package, grub_target)
def install_bios(self, step, settings, state):
vmdb.progress('Installing GRUB for BIOS')
grub_package = 'grub-pc'
grub_target = 'i386-pc'
self.install_grub(step, settings, state, grub_package, grub_target)
......@@ -119,19 +117,17 @@ class GrubStepRunner(vmdb.StepRunnerInterface):
def install_grub(self, step, settings, state, grub_package, grub_target):
console = step.get('console', None)
rootfs = step['root-fs']
chroot = state.mounts[rootfs]
root_part = step['root-part']
root_dev = state.parts[root_part]
tag = step['tag']
root_dev = state.tags.get_dev(tag)
chroot = state.tags.get_mount_point(tag)
image_dev = step.get('image-dev')
if image_dev is None:
image_dev = self.get_image_loop_device(root_dev)
if 'efi-part' in step:
efi_part = step['efi-part']
efi_dev = state.parts[efi_part]
if 'efi' in step:
efi = step['efi']
efi_dev = state.tags.get_dev(efi)
else:
efi_dev = None
......@@ -218,12 +214,7 @@ class GrubStepRunner(vmdb.StepRunnerInterface):
mount_opts = []
vmdb.runcmd(['mount'] + mount_opts + [path, chroot_path])
binds = getattr(state, 'grub_mounts', None)
if binds is None:
binds = []
binds.append(chroot_path)
state.grub_mounts = binds
state.grub_mounts.append(chroot_path)
def chroot_path(self, chroot, path):
return os.path.normpath(os.path.join(chroot, '.' + path))
......
......@@ -35,10 +35,9 @@ class MkfsStepRunner(vmdb.StepRunnerInterface):
def run(self, step, settings, state):
fstype = step['mkfs']
part_tag = step['partition']
device = state.parts[part_tag]
vmdb.progress(
'Creating {} filesystem on {}'.format(fstype, device))
tag = step['partition']
device = state.tags.get_dev(tag)
cmd = ['/sbin/mkfs', '-t', fstype]
if 'label' in step:
if fstype == 'vfat':
......
......@@ -17,6 +17,7 @@
import logging
import os
import tempfile
......@@ -34,7 +35,7 @@ class MountPlugin(cliapp.Plugin):
class MountStepRunner(vmdb.StepRunnerInterface):
def get_required_keys(self):
return ['mount', 'fs-tag']
return ['mount']
def run(self, step, settings, state):
self.mount_rootfs(step, settings, state)
......@@ -43,42 +44,37 @@ class MountStepRunner(vmdb.StepRunnerInterface):
self.unmount_rootfs(step, settings, state)
def mount_rootfs(self, step, settings, state):
if not hasattr(state, 'mounts'):
state.mounts = {}
part_tag = step['mount']
fs_tag = step['fs-tag']
tag = step['mount']
dirname = step.get('dirname')
mount_on = step.get('mount-on')
if fs_tag in state.mounts:
raise Exception('fs-tag {} already used'.format(fs_tag))
device = state.tags.get_dev(tag)
if dirname:
if not mount_on:
raise Exception('no mount-on tag given')
if mount_on not in state.mounts:
if not state.tags.has_tag(mount_on):
raise Exception('cannot find tag {}'.format(mount_on))
mount_point = os.path.join(
state.mounts[mount_on], './' + step['dirname'])
state.tags.get_mount_point(mount_on), './' + dirname)
if not os.path.exists(mount_point):
os.makedirs(mount_point)
else:
mount_point = tempfile.mkdtemp()
device = state.parts[part_tag]
vmdb.runcmd(['mount', device, mount_point])
state.mounts[fs_tag] = mount_point
state.tags.add_mount_point(tag, mount_point)
return mount_point
def unmount_rootfs(self, step, settings, state):
fs_tag = step['fs-tag']
mount_point = state.mounts[fs_tag]
tag = step['mount']
mount_point = state.tags.get_mount_point(tag)
if mount_point is None:
return
try:
vmdb.unmount(mount_point)
......
......@@ -35,28 +35,25 @@ class PartitionPlugin(cliapp.Plugin):
class MklabelStepRunner(vmdb.StepRunnerInterface):
def get_required_keys(self):
return ['mklabel']
return ['mklabel', 'device']
def run(self, step, settings, state):
label_type = step['mklabel']
device = step['device']
vmdb.progress(
'Creating partition table ({}) on {}'.format(label_type, device))
vmdb.runcmd(['parted', '-s', device, 'mklabel', label_type])
state.parts = {}
class MkpartStepRunner(vmdb.StepRunnerInterface):
def get_required_keys(self):
return ['mkpart']
return ['mkpart', 'device', 'start', 'end', 'tag']
def run(self, step, settings, state):
part_type = step['mkpart']
device = step['device']
start = step['start']
end = step['end']
part_tag = step['part-tag']
part_tag = step['tag']
fs_type = step.get('fs-type', 'ext2')
vmdb.progress(
......@@ -103,9 +100,7 @@ class MkpartStepRunner(vmdb.StepRunnerInterface):
def remember_partition(self, state, part_dev, part_tag):
print('remembering partition', part_dev, 'as', part_tag)
parts = getattr(state, 'parts', {})
parts[part_tag] = part_dev
state.parts = parts
state.tags.add_partition(part_tag, part_dev)
def create_loop_dev(self, device):
vmdb.runcmd(['kpartx', '-dsv', device])
......@@ -120,6 +115,4 @@ class MkpartStepRunner(vmdb.StepRunnerInterface):
def teardown(self, step, settings, state):
device = step['device']
vmdb.progress(
'Undoing loopback devices for partitions on {}'.format(device))
vmdb.runcmd(['kpartx', '-dsv', device])
......@@ -36,7 +36,7 @@ class QemuDebootstrapStepRunner(vmdb.StepRunnerInterface):
def run(self, step, settings, state):
suite = step['qemu-debootstrap']
tag = step['target']
target = state.mounts[tag]
target = state.get_mount_point(tag)
mirror = step['mirror']
variant = step.get('variant', '-')
arch = step['arch']
......
......@@ -43,7 +43,7 @@ class MakeCacheStepRunner(vmdb.StepRunnerInterface):
def run(self, step, settings, state):
fs_tag = step['cache-rootfs']
rootdir = state.mounts[fs_tag]
rootdir = state.get_mount_point(fs_tag)
tar_path = settings['rootfs-tarball']
opts = step.get('options', '--one-file-system').split()
if not tar_path:
......@@ -61,7 +61,7 @@ class UnpackCacheStepRunner(vmdb.StepRunnerInterface):
def run(self, step, settings, state):
fs_tag = step['unpack-rootfs']
rootdir = state.mounts[fs_tag]
rootdir = state.tags.get_mount_point(fs_tag)
tar_path = settings['rootfs-tarball']
if not tar_path:
raise Exception('--rootfs-tarball MUST be set')
......
......@@ -48,7 +48,7 @@ class VirtualFilesystemMountStepRunner(vmdb.StepRunnerInterface):
def run(self, step, settings, state):
fstag = step['mount-virtual-filesystems']
mount_point = state.mounts[fstag]
mount_point = state.get_mount_point(fstag)
self.mount_virtuals(mount_point, state)
def teardown(self, step, settings, state):
......
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