def run(cls, info): from bootstrapvz.common.tools import log_call, log_check_call for line in log_check_call(['chroot', info.root, 'apt-cache', 'show', info.kernel['headers_pkg']]): key, value = line.split(':') if key.strip() == 'Depends': kernel_version = value.strip().split('linux-headers-')[-1] break guest_additions_path = info.manifest.provider['guest_additions'] mount_dir = 'mnt/guest_additions' mount_path = os.path.join(info.root, mount_dir) os.mkdir(mount_path) root = info.volume.partition_map.root root.add_mount(guest_additions_path, mount_path, ['-o', 'loop']) install_script = os.path.join('/', mount_dir, 'VBoxLinuxAdditions.run') install_wrapper_name = 'install_guest_additions.sh' install_wrapper = open(os.path.join(assets, install_wrapper_name)) \ .read() \ .replace("KERNEL_VERSION", kernel_version) \ .replace("KERNEL_ARCH", info.kernel['arch']) \ .replace("INSTALL_SCRIPT", install_script) install_wrapper_path = os.path.join(info.root, install_wrapper_name) with open(install_wrapper_path, 'w') as f: f.write(install_wrapper + '\n') # Don't check the return code of the scripts here, because 1 not necessarily means they have failed log_call(['chroot', info.root, 'bash', '/' + install_wrapper_name]) # VBoxService process could be running, as it is not affected by DisableDaemonAutostart log_call(['chroot', info.root, 'service', 'vboxadd-service', 'stop']) root.remove_mount(mount_path) os.rmdir(mount_path) os.remove(install_wrapper_path)
def run(cls, info): from bootstrapvz.common.tools import log_call for i, key_path in enumerate( info.manifest.packages.get('trusted-keys', {})): if not os.path.isfile(key_path): info.manifest.validation_error( 'File not found: {}'.format(key_path), ['packages', 'trusted-keys', i]) from tempfile import mkdtemp from shutil import rmtree tempdir = mkdtemp() status, _, _ = log_call([ 'gpg', '--quiet', '--homedir', tempdir, '--keyring', key_path, '-k' ]) rmtree(tempdir) if status != 0: info.manifest.validation_error( 'Invalid GPG keyring: {}'.format(key_path), ['packages', 'trusted-keys', i])
def run(cls, info): from bootstrapvz.common.tools import log_call for i, rel_key_path in enumerate(info.manifest.packages.get('trusted-keys', {})): key_path = rel_path(info.manifest.path, rel_key_path) if not os.path.isfile(key_path): info.manifest.validation_error('File not found: {}'.format(key_path), ['packages', 'trusted-keys', i]) from tempfile import mkdtemp from shutil import rmtree tempdir = mkdtemp() status, _, _ = log_call( ['gpg', '--quiet', '--homedir', tempdir, '--keyring', key_path, '-k'] ) rmtree(tempdir) if status != 0: info.manifest.validation_error('Invalid GPG keyring: {}'.format(key_path), ['packages', 'trusted-keys', i])
def run(cls, info): import os guest_additions_path = info.manifest.provider['guest_additions'] mount_dir = 'mnt/guest_additions' mount_path = os.path.join(info.root, mount_dir) os.mkdir(mount_path) root = info.volume.partition_map.root root.add_mount(guest_additions_path, mount_path, ['-o', 'loop']) install_script = os.path.join('/', mount_dir, 'VBoxLinuxAdditions.run') # Don't check the return code of the scripts here, because 1 not necessarily means they have failed from bootstrapvz.common.tools import log_call log_call(['chroot', info.root, install_script, '--nox11']) # VBoxService process could be running, as it is not affected by DisableDaemonAutostart log_call(['chroot', info.root, 'service', 'vboxadd-service', 'stop']) root.remove_mount(mount_path) os.rmdir(mount_path)
def run(cls, info): import os guest_additions_path = info.manifest.bootstrapper["guest_additions"] mount_dir = "mnt/guest_additions" mount_path = os.path.join(info.root, mount_dir) os.mkdir(mount_path) root = info.volume.partition_map.root root.add_mount(guest_additions_path, mount_path, ["-o", "loop"]) install_script = os.path.join("/", mount_dir, "VBoxLinuxAdditions.run") # Don't check the return code of the scripts here, because 1 not necessarily means they have failed from bootstrapvz.common.tools import log_call log_call(["chroot", info.root, install_script, "--nox11"]) # VBoxService process could be running, as it is not affected by DisableDaemonAutostart log_call(["chroot", info.root, "service", "vboxadd-service", "stop"]) root.remove_mount(mount_path) os.rmdir(mount_path)
def run(cls, info): from bootstrapvz.common.tools import log_call, rel_path pubkey = info.manifest.plugins['admin_user'].get('pubkey', None) if pubkey is not None: abs_pubkey = rel_path(info.manifest.path, pubkey) if not os.path.isfile(abs_pubkey): msg = 'Could not find public key at %s' % pubkey info.manifest.validation_error(msg, ['plugins', 'admin_user', 'pubkey']) ret, _, stderr = log_call(['ssh-keygen', '-l', '-f', abs_pubkey]) if ret != 0: msg = 'Invalid public key file at %s' % pubkey info.manifest.validation_error(msg, ['plugins', 'admin_user', 'pubkey'])
def run(cls, info): from bootstrapvz.common.tools import log_call, rel_path pubkey = info.manifest.plugins['admin_user'].get('pubkey', None) if pubkey is not None: abs_pubkey = rel_path(info.manifest.path, pubkey) if not os.path.isfile(abs_pubkey): msg = 'Could not find public key at %s' % pubkey info.manifest.validation_error(msg, ['plugins', 'admin_user', 'pubkey']) ret, _, stderr = log_call('ssh-keygen -l -f ' + abs_pubkey) if ret != 0: msg = 'Invalid public key file at %s' % pubkey info.manifest.validation_error(msg, ['plugins', 'admin_user', 'pubkey'])
def validate_manifest(data, validator, error): """Validates the manifest using the base manifest :param dict data: The data of the manifest :param function validator: The function that validates the manifest given the data and a path :param function error: The function tha raises an error when the validation fails """ import os.path schema_path = os.path.normpath( os.path.join(os.path.dirname(__file__), 'manifest-schema.yml')) validator(data, schema_path) from bootstrapvz.common.releases import get_release from bootstrapvz.common.releases import squeeze release = get_release(data['system']['release']) if release < squeeze: error('Only Debian squeeze and later is supported', ['system', 'release']) # Check the bootloader/partitioning configuration. # Doing this via the schema is a pain and does not output a useful error message. if data['system']['bootloader'] == 'grub': if data['volume']['partitions']['type'] == 'none': error('Grub cannot boot from unpartitioned disks', ['system', 'bootloader']) if release == squeeze: error('Grub installation on squeeze is not supported', ['system', 'bootloader']) # Check the provided apt.conf(5) options if 'packages' in data: for name, val in data['packages'].get('apt.conf.d', {}).iteritems(): from bootstrapvz.common.tools import log_call status, _, _ = log_call(['apt-config', '-c=/dev/stdin', 'dump'], stdin=val + '\n') if status != 0: error('apt.conf(5) syntax error', ['packages', 'apt.conf.d', name])
def run(cls, info): from bootstrapvz.common.tools import log_call for i, key_path in enumerate(info.manifest.packages.get("trusted-keys", {})): if not os.path.isfile(key_path): info.manifest.validation_error("File not found: {}".format(key_path), ["packages", "trusted-keys", i]) from tempfile import mkdtemp from shutil import rmtree tempdir = mkdtemp() status, _, _ = log_call(["gpg", "--quiet", "--homedir", tempdir, "--keyring", key_path, "-k"]) rmtree(tempdir) if status != 0: info.manifest.validation_error( "Invalid GPG keyring: {}".format(key_path), ["packages", "trusted-keys", i] )
def test_log_call_output_order(): logged = setup_logger() fixture = """ 2 0.0 one\\\\n 1 0.2 two\\\\n 1 0.2 four\\\\n 2 0.2 No, three..\\\\n 1 0.2 three\\\\n """ status, stdout, stderr = log_call([subprocess_path], stdin=fixture) eq_(status, 0) eq_(stderr, ['one', 'No, three..']) eq_(stdout, ['two', 'four', 'three']) expected_order = ['one', 'two', 'four', 'No, three..', 'three', ] eq_(expected_order, logged.getvalue().split("\n")[8:-1])
def test_log_call_output_order(): logged = setup_logger() fixture = """ 2 0.0 one\\\\n 1 0.4 two\\\\n 1 0.4 four\\\\n 2 0.4 No, three..\\\\n 1 0.4 three\\\\n """ status, stdout, stderr = log_call([subprocess_path], stdin=fixture) eq_(status, 0) eq_(stderr, ['one', 'No, three..']) eq_(stdout, ['two', 'four', 'three']) expected_order = [ 'one', 'two', 'four', 'No, three..', 'three', ] eq_(expected_order, logged.getvalue().split("\n")[8:-1])
def validate_manifest(data, validator, error): """Validates the manifest using the base manifest :param dict data: The data of the manifest :param function validator: The function that validates the manifest given the data and a path :param function error: The function tha raises an error when the validation fails """ import os.path schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml')) validator(data, schema_path) from bootstrapvz.common.releases import get_release from bootstrapvz.common.releases import squeeze release = get_release(data['system']['release']) if release < squeeze: error('Only Debian squeeze and later is supported', ['system', 'release']) # Check the bootloader/partitioning configuration. # Doing this via the schema is a pain and does not output a useful error message. if data['system']['bootloader'] == 'grub': if data['volume']['partitions']['type'] == 'none': error('Grub cannot boot from unpartitioned disks', ['system', 'bootloader']) if release == squeeze: error('Grub installation on squeeze is not supported', ['system', 'bootloader']) # Check the provided apt.conf(5) options if 'packages' in data: for name, val in data['packages'].get('apt.conf.d', {}).iteritems(): from bootstrapvz.common.tools import log_call status, _, _ = log_call(['apt-config', '-c=/dev/stdin', 'dump'], stdin=val + '\n') if status != 0: error('apt.conf(5) syntax error', ['packages', 'apt.conf.d', name])