def mount_rootfs(self, values, settings, state): tag = values["mount"] dirname = values["dirname"] or None mount_on = values["mount-on"] or None device = state.tags.get_dev(tag) if dirname: if not mount_on: raise Exception("no mount-on tag given") if not state.tags.has_tag(mount_on): raise Exception("cannot find tag {}".format(mount_on)) mount_point = os.path.join( state.tags.get_builder_mount_point(mount_on), "./" + dirname) if not os.path.exists(mount_point): os.makedirs(mount_point) else: dirname = "/" mount_point = tempfile.mkdtemp() vmdb.runcmd(["mount", device, mount_point]) state.tags.set_builder_mount_point(tag, mount_point, cached=True) state.tags.set_target_mount_point(tag, dirname) return mount_point
def run(self, step, settings, state): part_type = step['mkpart'] device = step['device'] start = step['start'] end = step['end'] part_tag = step['part-tag'] vmdb.progress( 'Creating partition ({}) on {} ({} to {})'.format( part_type, device, start, end)) vmdb.runcmd(['parted', '-s', device, 'mkpart', part_type, start, end]) vmdb.runcmd(['kpartx', '-dsv', device]) output = vmdb.runcmd(['kpartx', '-asv', device]).decode('UTF-8') device_file = None for line in output.splitlines(): words = line.split() if words[0] == 'add': name = words[2] device_file = '/dev/mapper/{}'.format(name) assert device_file is not None parts = getattr(state, 'parts', {}) parts[part_tag] = device_file state.parts = parts
def run(self, values, settings, state): tag = values["ansible"] playbook = values["playbook"] mount_point = state.tags.get_builder_mount_point(tag) rootfs_tarball = settings["rootfs-tarball"] state.ansible_inventory = self.create_inventory(mount_point) vmdb.progress("Created {} for Ansible inventory".format( state.ansible_inventory)) vars_filename = self.create_vars(rootfs_tarball) vmdb.progress("Created {} for Ansible variables".format(vars_filename)) env = dict(os.environ) env["ANSIBLE_NOCOWS"] = "1" vmdb.runcmd( [ "ansible-playbook", "-c", "chroot", "-i", state.ansible_inventory, "-e", "@{}".format(vars_filename), playbook, ], env=env, )
def mount_rootfs(self, step, settings, state): if not hasattr(state, 'mounts'): state.mounts = {} part_tag = step['mount'] fs_tag = step['fs-tag'] 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)) if dirname: if not mount_on: raise Exception('no mount-on tag given') if mount_on not in state.mounts: raise Exception('cannot find tag {}'.format(mount_on)) mount_point = os.path.join(state.mounts[mount_on], './' + step['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 return mount_point
def run(self, step, settings, state): vgname = self.get_vg(step) physical = self.get_pv(step, state) for phys in physical: vmdb.runcmd(['pvcreate', '-ff', '--yes', phys]) vmdb.runcmd(['vgcreate', vgname] + physical)
def run(self, values, settings, state): fstype = values["mkfs"] tag = values["partition"] device = state.tags.get_dev(tag) if not isinstance(fstype, str): raise vmdb.NotString("mkfs", fstype) if not isinstance(tag, str): raise vmdb.NotString("mkfs: tag", tag) if not isinstance(device, str): raise vmdb.NotString("mkfs: device (for tag)", device) cmd = ["/sbin/mkfs", "-t", fstype] label = values["label"] or None if label: if fstype == "vfat": cmd.append("-n") elif fstype == "f2fs": cmd.append("-l") else: cmd.append("-L") cmd.append(label) options = values["options"] or None if options: for opt in options.split(' '): cmd.append(opt) cmd.append(device) vmdb.runcmd(cmd) state.tags.set_fstype(tag, fstype)
def run(self, step, settings, state): shell = step['shell'] fs_tag = step['root-fs'] env = dict(os.environ) env['ROOT'] = state.tags.get_mount_point(fs_tag) vmdb.runcmd(['sh', '-c', shell], env=env)
def mount_rootfs(self, step, settings, state): tag = step['mount'] dirname = step.get('dirname') mount_on = step.get('mount-on') device = state.tags.get_dev(tag) if dirname: if not mount_on: raise Exception('no mount-on tag given') if not state.tags.has_tag(mount_on): raise Exception('cannot find tag {}'.format(mount_on)) mount_point = os.path.join( state.tags.get_mount_point(mount_on), './' + dirname) if not os.path.exists(mount_point): os.makedirs(mount_point) else: mount_point = tempfile.mkdtemp() vmdb.runcmd(['mount', device, mount_point]) state.tags.set_mount_point(tag, mount_point) return mount_point
def run(self, values, settings, state): vgname = self.get_vg(values) physical = self.get_pv(values, state) for phys in physical: vmdb.runcmd(["pvcreate", "-ff", "--yes", phys]) vmdb.runcmd(["vgcreate", vgname] + physical)
def unmount_virtuals(self, state): logging.debug('unmounting virtuals: %r', state.virtuals) for mount_point in reversed(state.virtuals): try: vmdb.runcmd(['umount', mount_point]) except cliapp.AppException: vmdb.error('Something went wrong while unmounting. Ignoring.')
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 = {}
def unmount_rootfs(self, step, settings, state): fs_tag = step['fs-tag'] mount_point = state.mounts[fs_tag] vmdb.runcmd(['umount', mount_point]) if not step.get('mount-on'): os.rmdir(mount_point)
def install_package(self, mount_point, argv_prefix, package): env = os.environ.copy() env['DEBIAN_FRONTEND'] = 'noninteractive' vmdb.runcmd( ['chroot', mount_point] + argv_prefix + ['apt-get', '-y', '--no-show-progress', 'install', package], env=env)
def run(self, step, settings, state): shell = step['shell'] fs_tag = step['root-fs'] vmdb.progress('run shell {}'.format(' '.join(shell.split('\n')))) env = dict(os.environ) env['ROOT'] = state.mounts[fs_tag] vmdb.runcmd(['sh', '-c', shell], env=env)
def teardown(self, values, settings, state): x = state.tmp_key_file if x is not None and os.path.exists(x): os.remove(x) crypt_name = values["tag"] crypt_dev = "/dev/mapper/{}".format(crypt_name) vmdb.runcmd(["cryptsetup", "close", crypt_dev])
def run(self, step, settings, state): fs_tag = step['cache-rootfs'] rootdir = state.tags.get_mount_point(fs_tag) tar_path = settings['rootfs-tarball'] opts = step.get('options', '--one-file-system').split() if not tar_path: raise Exception('--rootfs-tarball MUST be set') if not os.path.exists(tar_path): vmdb.runcmd(['tar'] + opts + ['-C', rootdir, '-caf', tar_path, '.'])
def run(self, step, settings, state): fs_tag = step['chroot'] shell = step['shell'] mount_point = state.mounts[fs_tag] vmdb.progress('chroot {} to {}'.format(mount_point, ' '.join(shell.split('\n')))) vmdb.runcmd(['chroot', mount_point, 'sh', '-c', shell])
def mount(self, chroot, path, mount_point, state, mount_opts=None): chroot_path = self.chroot_path(chroot, mount_point) if not os.path.exists(chroot_path): os.makedirs(chroot_path) if mount_opts is None: mount_opts = [] vmdb.runcmd(['mount'] + mount_opts + [path, chroot_path]) state.grub_mounts.append(chroot_path)
def run(self, step, settings, state): suite = step['debootstrap'] tag = step['target'] target = state.tags.get_mount_point(tag) mirror = step['mirror'] variant = step.get('variant', '-') if not (suite and tag and target and mirror): raise Exception('missing arg for debootstrap step') vmdb.runcmd(['debootstrap', '--variant', variant, suite, target, mirror]) vmdb.runcmd_chroot(target, ['apt-get', 'update'])
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])
def run(self, step, settings, state): fs_tag = step['unpack-rootfs'] rootdir = state.tags.get_mount_point(fs_tag) tar_path = settings['rootfs-tarball'] if not tar_path: raise Exception('--rootfs-tarball MUST be set') if os.path.exists(tar_path): vmdb.runcmd( ['tar', '-C', rootdir, '-xf', tar_path, '--numeric-owner']) state.rootfs_unpacked = True
def run(self, step, settings, state): fs_tag = step['unpack-rootfs'] rootdir = state.mounts[fs_tag] tar_path = settings['rootfs-tarball'] if os.path.exists(tar_path): vmdb.progress('Unpacking rootfs from {} to {}'.format( tar_path, rootdir)) vmdb.runcmd( ['tar', '-C', rootdir, '-xf', tar_path, '--numeric-owner']) state.rootfs_unpacked = True
def mount_virtuals(self, rootfs, state): if not hasattr(state, 'virtuals'): state.virtuals = [] for device, mount_point, fstype in self.virtuals: path = os.path.join(rootfs, './' + mount_point) if not os.path.exists(path): os.mkdir(path) vmdb.runcmd(['mount', '-t', fstype, device, path]) state.virtuals.append(path) logging.debug('mounted virtuals: %r', state.virtuals)
def mount_virtuals(self, rootfs, state): if not hasattr(state, "virtuals"): state.virtuals = [] for device, mount_point, fstype in self.virtuals: path = os.path.join(rootfs, "./" + mount_point) if not os.path.exists(path): os.mkdir(path) vmdb.runcmd(["mount", "-t", fstype, device, path]) state.virtuals.append(path) logging.debug("mounted virtuals: %r", state.virtuals)
def run(self, values, settings, state): vgname = values["lvcreate"] lvname = values["name"] size = values["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)
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)
def run(self, step, settings, state): suite = step['debootstrap'] tag = step['target'] target = state.mounts[tag] mirror = step['mirror'] variant = step.get('variant', '-') if not (suite and tag and target and mirror): raise Exception('missing arg for debootstrap step') vmdb.progress('Debootstrap {} {} {}'.format(suite, target, mirror)) vmdb.runcmd( ['debootstrap', '--variant', variant, suite, target, mirror])
def run(self, step, settings, state): fs_tag = step['cache-rootfs'] rootdir = state.mounts[fs_tag] tar_path = settings['rootfs-tarball'] if not os.path.exists(tar_path): vmdb.progress('Caching contents of {} to {}'.format( rootdir, tar_path)) vmdb.runcmd([ 'tar', '-C', rootdir, '--one-file-system', '-caf', tar_path, '.' ])
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): vmdb.runcmd(["tar", "-C", rootdir, "-xf", tar_path, "--numeric-owner"]) self.copy_resolv_conf(rootdir) state.rootfs_unpacked = True
def run(self, values, settings, state): underlying = values["cryptsetup"] crypt_name = values["tag"] if not isinstance(underlying, str): raise vmdb.NotString("cryptsetup", underlying) if not isinstance(crypt_name, str): raise vmdb.NotString("cryptsetup: tag", crypt_name) state.tmp_key_file = None key_file = values["key-file"] or None key_cmd = values["key-cmd"] or None 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", "-ec", 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_builder_mount_point(t), ) assert 0 vmdb.runcmd(["cryptsetup", "-q", "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)