def test_copy_kernel_initramfs(self, mock_copy, mock_glob, mock_exec, mock_makedirs): global_return_hash = {'/test/path/boot/vmlinuz*': ['testfile1'], '/test/path/boot/initrd*': ['testfile2']} mock_glob.side_effect = lambda x: global_return_hash[x] bu.copy_kernel_initramfs('/test/path', '/test/dst/dir') expected_copy_calls = [ mock.call('testfile1', '/test/dst/dir/vmlinuz'), mock.call('testfile2', '/test/dst/dir/initrd.img') ] self.assertItemsEqual(expected_copy_calls, mock_copy.call_args_list)
def do_mkbootstrap(self): """Building bootstrap image Currently supports only Ubuntu-Trusty Includes the following steps 1) Allocate and configure debootstrap. 2) Install packages 3) Run user-post script(is defined) 4) populate squashfs\init\vmlinuz files 5) create metadata.yaml and pack thats all into tar.gz """ LOG.info('--- Building bootstrap image (do_mkbootstrap) ---') driver_os = self.driver.operating_system # c_dir = output container directory, where all builded files will # be stored, before packaging into archive LOG.debug('Creating bootstrap container folder') c_dir = bu.mkdtemp_smart(CONF.image_build_dir, CONF.image_build_suffix + '_container') try: chroot = bu.mkdtemp_smart( CONF.image_build_dir, CONF.image_build_suffix) self.install_base_os(chroot) bs_scheme = self.driver.bootstrap_scheme # init modules, needed for bootstrap. Currently # we support only one scheme initrd + rootfs + kernel initrd = filter(lambda x: x.name == 'initrd', bs_scheme.modules)[0] rootfs = filter(lambda x: x.name == 'rootfs', bs_scheme.modules)[0] metadata = {} metadata['os'] = driver_os.to_dict() packages = driver_os.packages metadata['packages'] = packages self._set_apt_repos( chroot, driver_os.repos, proxies=driver_os.proxies.proxies, direct_repo_addrs=driver_os.proxies.direct_repo_addr_list) self._update_metadata_with_repos( metadata, driver_os.repos) LOG.debug('Installing packages using apt-get: %s', ' '.join(packages)) # disable hosts/resolv files bu.propagate_host_resolv_conf(chroot) bu.run_apt_get(chroot, packages=packages, attempts=CONF.fetch_packages_attempts) LOG.debug('Post-install OS configuration') if hasattr(bs_scheme, 'extra_files') and bs_scheme.extra_files: for extra in bs_scheme.extra_files: bu.rsync_inject(extra, chroot) if (hasattr(bs_scheme, 'root_ssh_authorized_file') and bs_scheme.root_ssh_authorized_file): LOG.debug('Put ssh auth file %s', bs_scheme.root_ssh_authorized_file) auth_file = os.path.join(chroot, 'root/.ssh/authorized_keys') utils.makedirs_if_not_exists(os.path.dirname( auth_file), mode=0o700) shutil.copy( bs_scheme.root_ssh_authorized_file, auth_file) os.chmod(auth_file, 0o700) # Allow user to drop and run script inside chroot: if (hasattr(bs_scheme, 'post_script_file') and bs_scheme.post_script_file): bu.run_script_in_chroot( chroot, bs_scheme.post_script_file) # Save runtime_uuid into bootstrap bu.dump_runtime_uuid(bs_scheme.uuid, os.path.join(chroot, 'etc/nailgun-agent/config.yaml')) bu.do_post_inst(chroot, allow_unsigned_file=CONF.allow_unsigned_file, force_ipv4_file=CONF.force_ipv4_file) # restore disabled hosts/resolv files bu.restore_resolv_conf(chroot) metadata['all_packages'] = bu.get_installed_packages(chroot) # We need to recompress initramfs with new compression: bu.recompress_initramfs( chroot, compress=initrd.compress_format) # Bootstrap nodes load the kernel and initramfs via the network, # therefore remove the kernel and initramfs located in root # filesystem to make the image smaller (and save the network # bandwidth and the boot time) bu.copy_kernel_initramfs(chroot, c_dir, clean=True) LOG.debug('Making sure there are no running processes ' 'inside chroot before trying to umount chroot') if not bu.stop_chrooted_processes(chroot, signal=signal.SIGTERM): if not bu.stop_chrooted_processes( chroot, signal=signal.SIGKILL): raise errors.UnexpectedProcessError( 'Stopping chrooted processes failed. ' 'There are some processes running in chroot %s', chroot) bu.run_mksquashfs( chroot, os.path.join(c_dir, os.path.basename(rootfs.uri)), rootfs.compress_format) self.dump_mkbootstrap_meta(metadata, c_dir, bs_scheme) output = bu.save_bs_container(self.driver.output, c_dir, bs_scheme.container.format) LOG.info('--- Building bootstrap image END (do_mkbootstrap) ---') return output except Exception as exc: LOG.error('Failed to build bootstrap image: %s', exc) raise finally: LOG.info('Cleanup chroot') self.destroy_chroot(chroot) try: shutil.rmtree(c_dir) except OSError: LOG.debug('Finally: directory %s seems does not exist ' 'or can not be removed', c_dir)
def do_mkbootstrap(self): """Building bootstrap image Currently supports only Ubuntu-Trusty Includes the following steps 1) Allocate and configure debootstrap. 2) Install packages 3) Run user-post script(is defined) 4) populate squashfs\init\vmlinuz files 5) create metadata.yaml and pack thats all into tar.gz """ LOG.info('--- Building bootstrap image (do_mkbootstrap) ---') driver_os = self.driver.operating_system # c_dir = output container directory, where all builded files will # be stored, before packaging into archive LOG.debug('Creating bootstrap container folder') c_dir = bu.mkdtemp_smart(CONF.image_build_dir, CONF.image_build_suffix + '_container') try: chroot = bu.mkdtemp_smart( CONF.image_build_dir, CONF.image_build_suffix) self.install_base_os(chroot) bs_scheme = self.driver.bootstrap_scheme # init modules, needed for bootstrap. Currently # we support only one scheme initrd + rootfs + kernel initrd = filter(lambda x: x.name == 'initrd', bs_scheme.modules)[0] rootfs = filter(lambda x: x.name == 'rootfs', bs_scheme.modules)[0] metadata = {} metadata['os'] = driver_os.to_dict() packages = driver_os.packages metadata['packages'] = packages self._set_apt_repos( chroot, driver_os.repos, proxies=driver_os.proxies.proxies, direct_repo_addrs=driver_os.proxies.direct_repo_addr_list) self._update_metadata_with_repos( metadata, driver_os.repos) LOG.debug('Installing packages using apt-get: %s', ' '.join(packages)) # disable hosts/resolv files bu.propagate_host_resolv_conf(chroot) if hasattr(bs_scheme, 'certs') and bs_scheme.certs: bu.copy_update_certs(bs_scheme.certs, chroot) bu.run_apt_get(chroot, packages=packages, attempts=CONF.fetch_packages_attempts) LOG.debug('Post-install OS configuration') if hasattr(bs_scheme, 'extra_files') and bs_scheme.extra_files: for extra in bs_scheme.extra_files: bu.rsync_inject(extra, chroot) if (hasattr(bs_scheme, 'root_ssh_authorized_file') and bs_scheme.root_ssh_authorized_file): LOG.debug('Put ssh auth file %s', bs_scheme.root_ssh_authorized_file) auth_file = os.path.join(chroot, 'root/.ssh/authorized_keys') utils.makedirs_if_not_exists(os.path.dirname( auth_file), mode=0o700) shutil.copy( bs_scheme.root_ssh_authorized_file, auth_file) os.chmod(auth_file, 0o700) # Allow user to drop and run script inside chroot: if (hasattr(bs_scheme, 'post_script_file') and bs_scheme.post_script_file): bu.run_script_in_chroot( chroot, bs_scheme.post_script_file) # Save runtime_uuid into bootstrap bu.dump_runtime_uuid(bs_scheme.uuid, os.path.join(chroot, 'etc/nailgun-agent/config.yaml')) # NOTE(sslypushenko) Preferred names in LVM config should updated # due to point LVM to work only with /dev/mapper folder bu.override_lvm_config( chroot, {'devices': { 'preferred_names': CONF.mpath_lvm_preferred_names}}, lvm_conf_path=CONF.lvm_conf_path) root = driver_os.get_user_by_name('root') bu.do_post_inst(chroot, hashed_root_password=root.hashed_password, allow_unsigned_file=CONF.allow_unsigned_file, force_ipv4_file=CONF.force_ipv4_file, add_multipath_conf=False) # restore disabled hosts/resolv files bu.restore_resolv_conf(chroot) metadata['all_packages'] = bu.get_installed_packages(chroot) # We need to recompress initramfs with new compression: bu.recompress_initramfs( chroot, compress=initrd.compress_format) # Bootstrap nodes load the kernel and initramfs via the network, # therefore remove the kernel and initramfs located in root # filesystem to make the image smaller (and save the network # bandwidth and the boot time) bu.copy_kernel_initramfs(chroot, c_dir, clean=True) LOG.debug('Making sure there are no running processes ' 'inside chroot before trying to umount chroot') if not bu.stop_chrooted_processes(chroot, signal=signal.SIGTERM): if not bu.stop_chrooted_processes( chroot, signal=signal.SIGKILL): raise errors.UnexpectedProcessError( 'Stopping chrooted processes failed. ' 'There are some processes running in chroot %s', chroot) bu.run_mksquashfs( chroot, os.path.join(c_dir, os.path.basename(rootfs.uri)), rootfs.compress_format) self.dump_mkbootstrap_meta(metadata, c_dir, bs_scheme) output = bu.save_bs_container(self.driver.output, c_dir, bs_scheme.container.format) LOG.info('--- Building bootstrap image END (do_mkbootstrap) ---') return output except Exception as exc: LOG.error('Failed to build bootstrap image: %s', exc) raise finally: LOG.info('Cleanup chroot') self.destroy_chroot(chroot) try: shutil.rmtree(c_dir) except OSError: LOG.debug('Finally: directory %s seems does not exist ' 'or can not be removed', c_dir)