from bootstrapvz.base import Task from .. import phases from ..tools import log_check_call import bootstrap import host import volume class AddRequiredCommands(Task): description = 'Adding commands required for formatting' phase = phases.preparation successors = [host.CheckExternalCommands] @classmethod def run(cls, info): if 'xfs' in (p.filesystem for p in info.volume.partition_map.partitions): info.host_dependencies['mkfs.xfs'] = 'xfsprogs' class Format(Task): description = 'Formatting the volume' phase = phases.volume_preparation @classmethod def run(cls, info): from bootstrapvz.base.fs.partitions.unformatted import UnformattedPartition for partition in info.volume.partition_map.partitions: if isinstance(partition, UnformattedPartition): continue partition.format() class TuneVolumeFS(Task): description = 'Tuning the bootstrap volume filesystem' phase = phases.volume_preparation predecessors = [Format] @classmethod def run(cls, info): from bootstrapvz.base.fs.partitions.unformatted import UnformattedPartition import re # Disable the time based filesystem check for partition in info.volume.partition_map.partitions: if isinstance(partition, UnformattedPartition): continue if re.match('^ext[2-4]$', partition.filesystem) is not None: log_check_call(['tune2fs', '-i', '0', partition.device_path]) class AddXFSProgs(Task): description = 'Adding `xfsprogs\' to the image packages' phase = phases.preparation @classmethod def run(cls, info): info.packages.add('xfsprogs') class CreateMountDir(Task): description = 'Creating mountpoint for the root partition' phase = phases.volume_mounting @classmethod def run(cls, info): import os info.root = os.path.join(info.workspace, 'root') os.makedirs(info.root) class MountRoot(Task): description = 'Mounting the root partition' phase = phases.volume_mounting predecessors = [CreateMountDir] @classmethod def run(cls, info): info.volume.partition_map.root.mount(destination=info.root) class CreateBootMountDir(Task): description = 'Creating mountpoint for the boot partition' phase = phases.volume_mounting predecessors = [MountRoot] @classmethod def run(cls, info): import os.path os.makedirs(os.path.join(info.root, 'boot')) class MountBoot(Task): description = 'Mounting the boot partition' phase = phases.volume_mounting predecessors = [CreateBootMountDir] @classmethod def run(cls, info): p_map = info.volume.partition_map p_map.root.add_mount(p_map.boot, 'boot') class MountSpecials(Task): description = 'Mounting special block devices' phase = phases.os_installation predecessors = [bootstrap.Bootstrap] @classmethod def run(cls, info): root = info.volume.partition_map.root root.add_mount('/dev', 'dev', ['--bind']) root.add_mount('none', 'proc', ['--types', 'proc']) root.add_mount('none', 'sys', ['--types', 'sysfs']) root.add_mount('none', 'dev/pts', ['--types', 'devpts']) class CopyMountTable(Task): description = 'Copying mtab from host system' phase = phases.os_installation predecessors = [MountSpecials] @classmethod def run(cls, info): import shutil import os.path shutil.copy('/proc/mounts', os.path.join(info.root, 'etc/mtab')) class UnmountRoot(Task): description = 'Unmounting the bootstrap volume' phase = phases.volume_unmounting successors = [volume.Detach] @classmethod def run(cls, info): info.volume.partition_map.root.unmount() class RemoveMountTable(Task): description = 'Removing mtab' phase = phases.volume_unmounting successors = [UnmountRoot] @classmethod def run(cls, info): import os os.remove(os.path.join(info.root, 'etc/mtab')) class DeleteMountDir(Task): description = 'Deleting mountpoint for the bootstrap volume' phase = phases.volume_unmounting predecessors = [UnmountRoot] @classmethod def run(cls, info): import os os.rmdir(info.root) del info.root class FStab(Task): description = 'Adding partitions to the fstab' phase = phases.system_modification @classmethod def run(cls, info): import os.path p_map = info.volume.partition_map mount_points = [{'path': '/', 'partition': p_map.root, 'dump': '1', 'pass_num': '1', }] if hasattr(p_map, 'boot'): mount_points.append({'path': '/boot', 'partition': p_map.boot, 'dump': '1', 'pass_num': '2', }) if hasattr(p_map, 'swap'): mount_points.append({'path': 'none', 'partition': p_map.swap, 'dump': '1', 'pass_num': '0', }) fstab_lines = [] for mount_point in mount_points: partition = mount_point['partition'] mount_opts = ['defaults'] fstab_lines.append('UUID={uuid} {mountpoint} {filesystem} {mount_opts} {dump} {pass_num}' .format(uuid=partition.get_uuid(), mountpoint=mount_point['path'], filesystem=partition.filesystem, mount_opts=','.join(mount_opts), dump=mount_point['dump'], pass_num=mount_point['pass_num'])) fstab_path = os.path.join(info.root, 'etc/fstab') with open(fstab_path, 'w') as fstab: fstab.write('\n'.join(fstab_lines)) fstab.write('\n')