bootstrap-vz/bootstrapvz/common/tasks/bootstrap.py
Anders Ingemann f62c8ade99 Convert indentation from tabs to spaces (4)
Up until now I didn't see the point of using spaces for indentation.
However, the previous commit (a18bec3) was quite eye opening.
Given that python is an indentation aware language, the amount of
mistakes that went unnoticed because tabs and spaces were used
at the same time (tabs for indentation and spaces for alignment)
were unacceptable.

E101,W191 have been re-enable in the tox flake8 checker and
the documentation has been modified accordingly.

The following files have been left as-is:
* bootstrapvz/common/assets/extlinux/extlinux.conf
* bootstrapvz/common/assets/init.d/expand-root
* bootstrapvz/common/assets/init.d/generate-ssh-hostkeys
* bootstrapvz/common/assets/init.d/squeeze/generate-ssh-hostkeys
* bootstrapvz/plugins/docker_daemon/assets/init.d/docker
* bootstrapvz/providers/ec2/assets/bin/growpart
* bootstrapvz/providers/ec2/assets/grub.d/40_custom
* bootstrapvz/providers/ec2/assets/init.d/ec2-get-credentials
* bootstrapvz/providers/ec2/assets/init.d/ec2-run-user-data
* docs/_static/taskoverview.coffee
* docs/_static/taskoverview.less
* tests/unit/subprocess.sh
2016-06-04 11:38:16 +02:00

114 lines
4.3 KiB
Python

from bootstrapvz.base import Task
from .. import phases
from ..exceptions import TaskError
import host
import logging
import os.path
log = logging.getLogger(__name__)
class AddRequiredCommands(Task):
description = 'Adding commands required for bootstrapping Debian'
phase = phases.preparation
successors = [host.CheckExternalCommands]
@classmethod
def run(cls, info):
info.host_dependencies['debootstrap'] = 'debootstrap'
def get_bootstrap_args(info):
executable = ['debootstrap']
arch = info.manifest.system.get('userspace_architecture', info.manifest.system.get('architecture'))
options = ['--arch=' + arch]
if 'variant' in info.manifest.bootstrapper:
options.append('--variant=' + info.manifest.bootstrapper['variant'])
if len(info.include_packages) > 0:
options.append('--include=' + ','.join(info.include_packages))
if len(info.exclude_packages) > 0:
options.append('--exclude=' + ','.join(info.exclude_packages))
mirror = info.manifest.bootstrapper.get('mirror', info.apt_mirror)
arguments = [info.manifest.system['release'], info.root, mirror]
return executable, options, arguments
def get_tarball_filename(info):
from hashlib import sha1
executable, options, arguments = get_bootstrap_args(info)
# Filter info.root which points at /target/volume-id, we won't ever hit anything with that in there.
hash_args = [arg for arg in arguments if arg != info.root]
tarball_id = sha1(repr(frozenset(options + hash_args))).hexdigest()[0:8]
tarball_filename = 'debootstrap-' + tarball_id + '.tar'
return os.path.join(info.manifest.bootstrapper['workspace'], tarball_filename)
class MakeTarball(Task):
description = 'Creating bootstrap tarball'
phase = phases.os_installation
@classmethod
def run(cls, info):
executable, options, arguments = get_bootstrap_args(info)
tarball = get_tarball_filename(info)
if os.path.isfile(tarball):
log.debug('Found matching tarball, skipping creation')
else:
from ..tools import log_call
status, out, err = log_call(executable + options + ['--make-tarball=' + tarball] + arguments)
if status not in [0, 1]: # variant=minbase exits with 0
msg = 'debootstrap exited with status {status}, it should exit with status 0 or 1'.format(status=status)
raise TaskError(msg)
class Bootstrap(Task):
description = 'Installing Debian'
phase = phases.os_installation
predecessors = [MakeTarball]
@classmethod
def run(cls, info):
executable, options, arguments = get_bootstrap_args(info)
tarball = get_tarball_filename(info)
if os.path.isfile(tarball):
if not info.manifest.bootstrapper.get('tarball', False):
# Only shows this message if it hasn't tried to create the tarball
log.debug('Found matching tarball, skipping download')
options.extend(['--unpack-tarball=' + tarball])
if info.bootstrap_script is not None:
# Optional bootstrapping script to modify the bootstrapping process
arguments.append(info.bootstrap_script)
try:
from ..tools import log_check_call
log_check_call(executable + options + arguments)
except KeyboardInterrupt:
# Sometimes ../root/sys and ../root/proc are still mounted when
# quitting debootstrap prematurely. This break the cleanup process,
# so we unmount manually (ignore the exit code, the dirs may not be mounted).
from ..tools import log_call
log_call(['umount', os.path.join(info.root, 'sys')])
log_call(['umount', os.path.join(info.root, 'proc')])
raise
class IncludePackagesInBootstrap(Task):
description = 'Add packages in the bootstrap phase'
phase = phases.preparation
@classmethod
def run(cls, info):
info.include_packages.update(
set(info.manifest.bootstrapper['include_packages'])
)
class ExcludePackagesInBootstrap(Task):
description = 'Remove packages from bootstrap phase'
phase = phases.preparation
@classmethod
def run(cls, info):
info.exclude_packages.update(
set(info.manifest.bootstrapper['exclude_packages'])
)