from bootstrapvz.base import Task from bootstrapvz.common import phases from bootstrapvz.common.tasks import bootstrap from bootstrapvz.common.tasks import workspace from bootstrapvz.common.tools import sed_i import os import shutil from . import assets class CreateBootstrapFilterScripts(Task): description = 'Creating the bootstrapping locales filter script' phase = phases.os_installation successors = [bootstrap.Bootstrap] # Inspired by: # https://github.com/docker/docker/blob/1d775a54cc67e27f755c7338c3ee938498e845d7/contrib/mkimage/debootstrap @classmethod def run(cls, info): if info.bootstrap_script is not None: from bootstrapvz.common.exceptions import TaskError raise TaskError('info.bootstrap_script seems to already be set ' 'and is conflicting with this task') bootstrap_script = os.path.join(info.workspace, 'bootstrap_script.sh') filter_script = os.path.join(info.workspace, 'bootstrap_files_filter.sh') shutil.copy(os.path.join(assets, 'bootstrap-script.sh'), bootstrap_script) shutil.copy(os.path.join(assets, 'bootstrap-files-filter.sh'), filter_script) sed_i(bootstrap_script, r'BOOTSTRAP_FILES_FILTER_PATH', filter_script) sed_i(filter_script, r'EXCLUDE_PATTERN', "./usr/share/locale/.\+\|./usr/share/man/.\+") keep_files = ['./usr/share/locale/locale.alias', './usr/share/man/man1', './usr/share/man/man2', './usr/share/man/man3', './usr/share/man/man4', './usr/share/man/man5', './usr/share/man/man6', './usr/share/man/man7', './usr/share/man/man8', './usr/share/man/man9', ] locales = info.manifest.plugins['minimize_size']['apt']['locales'] keep_files.extend(map(lambda l: './usr/share/locale/' + l + '/', locales)) keep_files.extend(map(lambda l: './usr/share/man/' + l + '/', locales)) sed_i(filter_script, r'INCLUDE_PATHS', "\n".join(keep_files)) os.chmod(filter_script, 0755) info.bootstrap_script = bootstrap_script info._minimize_size['filter_script'] = filter_script class DeleteBootstrapFilterScripts(Task): description = 'Deleting the bootstrapping locales filter script' phase = phases.cleaning successors = [workspace.DeleteWorkspace] @classmethod def run(cls, info): os.remove(info._minimize_size['filter_script']) del info._minimize_size['filter_script'] os.remove(info.bootstrap_script) class FilterLocales(Task): description = 'Configuring dpkg to only include specific locales/manpages when installing packages' phase = phases.os_installation successors = [bootstrap.Bootstrap] # Snatched from: # https://github.com/docker/docker/blob/1d775a54cc67e27f755c7338c3ee938498e845d7/contrib/mkimage/debootstrap # and # https://raphaelhertzog.com/2010/11/15/save-disk-space-by-excluding-useless-files-with-dpkg/ @classmethod def run(cls, info): # This is before we start bootstrapping, so we create dpkg.cfg.d manually os.makedirs(os.path.join(info.root, 'etc/dpkg/dpkg.cfg.d')) locale_lines = ['path-exclude=/usr/share/locale/*', 'path-include=/usr/share/locale/locale.alias'] manpages_lines = ['path-exclude=/usr/share/man/*', 'path-include=/usr/share/man/man[1-9]'] locales = info.manifest.plugins['minimize_size']['apt']['locales'] locale_lines.extend(map(lambda l: 'path-include=/usr/share/locale/' + l + '/*', locales)) manpages_lines.extend(map(lambda l: 'path-include=/usr/share/man/' + l + '/*', locales)) locales_path = os.path.join(info.root, 'etc/dpkg/dpkg.cfg.d/10filter-locales') manpages_path = os.path.join(info.root, 'etc/dpkg/dpkg.cfg.d/10filter-manpages') with open(locales_path, 'w') as locale_filter: locale_filter.write('\n'.join(locale_lines) + '\n') with open(manpages_path, 'w') as manpages_filter: manpages_filter.write('\n'.join(manpages_lines) + '\n')