2013-06-27 00:11:09 +02:00
|
|
|
from base import Task
|
|
|
|
from common import phases
|
|
|
|
from common.exceptions import TaskError
|
2013-07-01 22:06:42 +02:00
|
|
|
from common.tools import log_check_call
|
2013-08-11 18:00:19 +02:00
|
|
|
from bootstrap import Bootstrap
|
2013-06-27 00:11:09 +02:00
|
|
|
|
|
|
|
|
|
|
|
class FormatVolume(Task):
|
|
|
|
description = 'Formatting the volume'
|
|
|
|
phase = phases.volume_preparation
|
|
|
|
|
|
|
|
def run(self, info):
|
|
|
|
dev_path = info.bootstrap_device['path']
|
|
|
|
mkfs = '/sbin/mkfs.{fs}'.format(fs=info.manifest.volume['filesystem'])
|
2013-07-01 22:21:47 +02:00
|
|
|
log_check_call([mkfs, dev_path])
|
2013-08-10 20:03:20 +02:00
|
|
|
info.bootstrap_device['partitions'] = {'root_path': info.bootstrap_device['path']}
|
2013-06-27 00:11:09 +02:00
|
|
|
|
|
|
|
|
|
|
|
class TuneVolumeFS(Task):
|
|
|
|
description = 'Tuning the bootstrap volume filesystem'
|
|
|
|
phase = phases.volume_preparation
|
|
|
|
after = [FormatVolume]
|
|
|
|
|
|
|
|
def run(self, info):
|
2013-06-27 22:00:01 +02:00
|
|
|
# Disable the time based filesystem check
|
2013-08-10 20:03:20 +02:00
|
|
|
log_check_call(['/sbin/tune2fs', '-i', '0', info.bootstrap_device['partitions']['root_path']])
|
2013-06-27 00:11:09 +02:00
|
|
|
|
|
|
|
|
|
|
|
class AddXFSProgs(Task):
|
|
|
|
description = 'Adding `xfsprogs\' to the image packages'
|
|
|
|
phase = phases.preparation
|
|
|
|
|
|
|
|
def run(self, info):
|
|
|
|
include, exclude = info.img_packages
|
|
|
|
include.add('xfsprogs')
|
2013-06-27 22:00:01 +02:00
|
|
|
|
|
|
|
|
|
|
|
class CreateMountDir(Task):
|
|
|
|
description = 'Creating mountpoint for the bootstrap volume'
|
|
|
|
phase = phases.volume_mounting
|
|
|
|
|
|
|
|
def run(self, info):
|
2013-07-01 22:06:42 +02:00
|
|
|
import os
|
2013-06-27 23:26:29 +02:00
|
|
|
mount_dir = info.manifest.bootstrapper['mount_dir']
|
2013-07-14 23:16:37 +02:00
|
|
|
info.root = '{mount_dir}/{id:x}'.format(mount_dir=mount_dir, id=info.run_id)
|
2013-06-27 22:00:01 +02:00
|
|
|
# Works recursively, fails if last part exists, which is exaclty what we want.
|
|
|
|
os.makedirs(info.root)
|
|
|
|
|
|
|
|
|
|
|
|
class MountVolume(Task):
|
2013-06-27 22:21:43 +02:00
|
|
|
description = 'Mounting the bootstrap volume'
|
2013-06-27 22:00:01 +02:00
|
|
|
phase = phases.volume_mounting
|
|
|
|
after = [CreateMountDir]
|
|
|
|
|
|
|
|
def run(self, info):
|
|
|
|
with open('/proc/mounts') as mounts:
|
|
|
|
for mount in mounts:
|
|
|
|
if info.root in mount:
|
2013-07-01 20:48:51 +02:00
|
|
|
msg = 'Something is already mounted at {root}'.format(root=info.root)
|
2013-06-27 22:00:01 +02:00
|
|
|
raise TaskError(msg)
|
|
|
|
|
2013-08-10 19:27:18 +02:00
|
|
|
log_check_call(['/bin/mount',
|
2013-08-17 15:00:53 +00:00
|
|
|
'--types', info.manifest.volume['filesystem'],
|
2013-08-10 20:03:20 +02:00
|
|
|
info.bootstrap_device['partitions']['root_path'],
|
2013-08-10 19:27:18 +02:00
|
|
|
info.root])
|
2013-06-27 22:21:43 +02:00
|
|
|
|
|
|
|
|
2013-07-01 20:48:51 +02:00
|
|
|
class MountSpecials(Task):
|
|
|
|
description = 'Mounting special block devices'
|
|
|
|
phase = phases.os_installation
|
|
|
|
after = [Bootstrap]
|
|
|
|
|
|
|
|
def run(self, info):
|
2013-07-07 19:38:34 +02:00
|
|
|
log_check_call(['/bin/mount', '--bind', '/dev', '{root}/dev'.format(root=info.root)])
|
2013-08-17 15:00:53 +00:00
|
|
|
log_check_call(['/usr/sbin/chroot', info.root, '/bin/mount', '--types', 'proc', 'none', '/proc'])
|
|
|
|
log_check_call(['/usr/sbin/chroot', info.root, '/bin/mount', '--types', 'sysfs', 'none', '/sys'])
|
|
|
|
log_check_call(['/usr/sbin/chroot', info.root, '/bin/mount', '--types', 'devpts', 'none', '/dev/pts'])
|
2013-07-01 20:48:51 +02:00
|
|
|
|
|
|
|
|
|
|
|
class UnmountSpecials(Task):
|
|
|
|
description = 'Unmunting special block devices'
|
|
|
|
phase = phases.volume_unmounting
|
|
|
|
|
|
|
|
def run(self, info):
|
2013-07-07 19:38:34 +02:00
|
|
|
log_check_call(['/usr/sbin/chroot', info.root, '/bin/umount', '/dev/pts'])
|
|
|
|
log_check_call(['/usr/sbin/chroot', info.root, '/bin/umount', '/sys'])
|
|
|
|
log_check_call(['/usr/sbin/chroot', info.root, '/bin/umount', '/proc'])
|
|
|
|
log_check_call(['/bin/umount', '{root}/dev'.format(root=info.root)])
|
2013-07-01 20:48:51 +02:00
|
|
|
|
|
|
|
|
2013-06-27 22:21:43 +02:00
|
|
|
class UnmountVolume(Task):
|
|
|
|
description = 'Unmounting the bootstrap volume'
|
|
|
|
phase = phases.volume_unmounting
|
2013-07-01 20:48:51 +02:00
|
|
|
after = [UnmountSpecials]
|
2013-06-27 22:21:43 +02:00
|
|
|
|
|
|
|
def run(self, info):
|
2013-07-07 19:38:34 +02:00
|
|
|
log_check_call(['/bin/umount', info.root])
|
2013-06-27 22:21:43 +02:00
|
|
|
|
|
|
|
|
|
|
|
class DeleteMountDir(Task):
|
|
|
|
description = 'Deleting mountpoint for the bootstrap volume'
|
|
|
|
phase = phases.volume_unmounting
|
|
|
|
after = [UnmountVolume]
|
|
|
|
|
|
|
|
def run(self, info):
|
2013-07-01 22:06:42 +02:00
|
|
|
import os
|
2013-06-27 22:21:43 +02:00
|
|
|
os.rmdir(info.root)
|
|
|
|
del info.root
|
2013-07-07 13:02:04 +02:00
|
|
|
|
|
|
|
|
|
|
|
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')
|
2013-08-10 20:03:20 +02:00
|
|
|
|
|
|
|
device = '/dev/sda1'
|
|
|
|
if info.manifest.virtualization == 'pvm':
|
|
|
|
device = '/dev/xvda1'
|
2013-07-07 13:02:04 +02:00
|
|
|
with open(fstab_path, 'a') as fstab:
|
2013-08-10 20:03:20 +02:00
|
|
|
fstab.write('{device} / {filesystem} {mount_opts} 1 1\n'
|
|
|
|
.format(device=device,
|
|
|
|
filesystem=info.manifest.volume['filesystem'].lower(),
|
|
|
|
mount_opts=','.join(mount_opts)))
|