from base import Task from common import phases from common.exceptions import TaskError from common.tools import log_check_call from common.filesystem import filesystem class FormatVolume(Task): description = 'Formatting the volume' phase = phases.volume_preparation def run(self, info): mkmount = ['/usr/bin/qemu-img', 'create', '-f', 'raw', info.manifest.bootstrapper['image_file'], str(info.manifest.volume['size'])+'M'] log_check_call(mkmount) loopcmd = ['/sbin/losetup', '/dev/loop0', info.manifest.bootstrapper['image_file']] log_check_call(loopcmd) # parted log_check_call(['parted', '-a', 'optimal', '-s', '/dev/loop0', "mklabel", "msdos"]) log_check_call(['parted', '-a', 'optimal', '-s', '/dev/loop0', "--", "mkpart", "primary", "ext4", "32k", "-1"]) log_check_call(['parted', '-s', '/dev/loop0', "--", "set", "1", "boot", "on"]) log_check_call(['kpartx', '-a', '-v', '/dev/loop0']) mkfs = ['/sbin/mkfs.{fs}'.format(fs=info.manifest.volume['filesystem']), '-m', '1', '-v', '/dev/mapper/loop0p1'] log_check_call(mkfs) class TuneVolumeFS(Task): description = 'Tuning the bootstrap volume filesystem' phase = phases.volume_preparation after = [FormatVolume] def run(self, info): dev_path = '/dev/mapper/loop0p1' # Disable the time based filesystem check log_check_call(['/sbin/tune2fs', '-i', '0', dev_path]) class MountVolume(Task): description = 'Mounting the bootstrap volume' phase = phases.volume_mounting after = [filesystem.CreateMountDir] def run(self, info): with open('/proc/mounts') as mounts: for mount in mounts: if info.root in mount: msg = 'Something is already mounted at {root}'.format(root=info.root) raise TaskError(msg) log_check_call(['/bin/mount', '-t', info.manifest.volume['filesystem'], '/dev/mapper/loop0p1', info.root]) class UnmountVolume(Task): description = 'Unmounting the bootstrap volume' phase = phases.volume_unmounting after = [filesystem.UnmountSpecials] def run(self, info): log_check_call(['/bin/umount', info.root]) log_check_call(['kpartx', '-d', info.manifest.bootstrapper['image_file']]) class ModifyFstab(Task): description = 'Adding root volume to the fstab' phase = phases.system_modification def run(self, info): import os.path mount_opts = ['defaults'] if info.manifest.volume['filesystem'].lower() in ['ext2', 'ext3', 'ext4']: mount_opts.append('barrier=0') if info.manifest.volume['filesystem'].lower() == 'xfs': mount_opts.append('nobarrier') fstab_path = os.path.join(info.root, 'etc/fstab') with open(fstab_path, 'a') as fstab: device = '/dev/sda1' if info.manifest.virtualization == 'virtio': device = '/dev/vda1' fstab.write('{device} / {filesystem} {mount_opts} 1 1\n' .format(device=device, filesystem=info.manifest.volume['filesystem'].lower(), mount_opts=','.join(mount_opts)))