Remove mount_specials from FSM

It makes modelling the different states more complicated
This commit is contained in:
Anders Ingemann 2013-09-26 22:43:36 +02:00
parent fc0471f780
commit 8891a18e4b
4 changed files with 38 additions and 22 deletions

View file

@ -10,14 +10,13 @@ class Volume(FSMProxy):
events = [{'name': 'create', 'src': 'nonexistent', 'dst': 'detached'}, events = [{'name': 'create', 'src': 'nonexistent', 'dst': 'detached'},
{'name': 'attach', 'src': 'detached', 'dst': 'attached'}, {'name': 'attach', 'src': 'detached', 'dst': 'attached'},
{'name': 'mount_specials', 'src': 'attached', 'dst': 'specials_mounted'},
{'name': 'unmount_specials', 'src': 'specials_mounted', 'dst': 'attached'},
{'name': 'detach', 'src': 'attached', 'dst': 'detached'}, {'name': 'detach', 'src': 'attached', 'dst': 'detached'},
{'name': 'delete', 'src': 'detached', 'dst': 'deleted'}, {'name': 'delete', 'src': 'detached', 'dst': 'deleted'},
] ]
def __init__(self, partition_map): def __init__(self, partition_map):
self.device_path = None self.device_path = None
self.specials_mounted = False
self.partition_map = partition_map self.partition_map = partition_map
self.size = self.partition_map.get_total_size() self.size = self.partition_map.get_total_size()
@ -29,20 +28,31 @@ class Volume(FSMProxy):
cfg = {'initial': 'nonexistent', 'events': self.events, 'callbacks': callbacks} cfg = {'initial': 'nonexistent', 'events': self.events, 'callbacks': callbacks}
super(Volume, self).__init__(cfg) super(Volume, self).__init__(cfg)
def _before_mount_specials(self, e): def can_mount_specials(self):
return self.is_state('attached')
def mount_specials(self):
if self.specials_mounted:
raise VolumeError('The special devices are already mounted')
root = self.partition_map.root.mount_dir root = self.partition_map.root.mount_dir
log_check_call(['/bin/mount', '--bind', '/dev', '{root}/dev'.format(root=root)]) log_check_call(['/bin/mount', '--bind', '/dev', '{root}/dev'.format(root=root)])
log_check_call(['/usr/sbin/chroot', root, '/bin/mount', '--types', 'proc', 'none', '/proc']) log_check_call(['/usr/sbin/chroot', root, '/bin/mount', '--types', 'proc', 'none', '/proc'])
log_check_call(['/usr/sbin/chroot', root, '/bin/mount', '--types', 'sysfs', 'none', '/sys']) log_check_call(['/usr/sbin/chroot', root, '/bin/mount', '--types', 'sysfs', 'none', '/sys'])
log_check_call(['/usr/sbin/chroot', root, '/bin/mount', '--types', 'devpts', 'none', '/dev/pts']) log_check_call(['/usr/sbin/chroot', root, '/bin/mount', '--types', 'devpts', 'none', '/dev/pts'])
self.specials_mounted = True
def _before_unmount_specials(self, e): def unmount_specials(self):
if not self.specials_mounted:
raise VolumeError('The special devices are not mounted')
root = self.partition_map.root.mount_dir root = self.partition_map.root.mount_dir
log_check_call(['/usr/sbin/chroot', root, '/bin/umount', '/dev/pts']) log_check_call(['/usr/sbin/chroot', root, '/bin/umount', '/dev/pts'])
log_check_call(['/usr/sbin/chroot', root, '/bin/umount', '/sys']) log_check_call(['/usr/sbin/chroot', root, '/bin/umount', '/sys'])
log_check_call(['/usr/sbin/chroot', root, '/bin/umount', '/proc']) log_check_call(['/usr/sbin/chroot', root, '/bin/umount', '/proc'])
log_check_call(['/bin/umount', '{root}/dev'.format(root=root)]) log_check_call(['/bin/umount', '{root}/dev'.format(root=root)])
self.specials_mounted = False
def _check_blocking(self, e): def _check_blocking(self, e):
if self.partition_map.is_blocking(): if self.partition_map.is_blocking():
raise VolumeError('The partitionmap prevents the detach procedure') raise VolumeError('The partitionmap prevents the detach procedure')
if self.specials_mounted:
raise VolumeError('The special devices are mounted and prevent the detaching procedure')

View file

@ -12,18 +12,16 @@ class LoopbackVolume(Volume):
events = [{'name': 'create', 'src': 'nonexistent', 'dst': 'detached'}, events = [{'name': 'create', 'src': 'nonexistent', 'dst': 'detached'},
{'name': 'attach', 'src': 'detached', 'dst': 'attached'}, {'name': 'attach', 'src': 'detached', 'dst': 'attached'},
{'name': 'link_dm_node', 'src': 'attached', 'dst': 'linked'}, {'name': 'link_dm_node', 'src': 'attached', 'dst': 'linked'},
{'name': 'mount_specials', 'src': 'linked', 'dst': 'lnk_specials_mounted'},
{'name': 'unmount_specials', 'src': 'lnk_specials_mounted', 'dst': 'linked'},
{'name': 'unlink_dm_node', 'src': 'linked', 'dst': 'attached'}, {'name': 'unlink_dm_node', 'src': 'linked', 'dst': 'attached'},
{'name': 'detach', 'src': 'attached', 'dst': 'detached'}, {'name': 'detach', 'src': 'attached', 'dst': 'detached'},
{'name': 'delete', 'src': 'detached', 'dst': 'deleted'}, {'name': 'delete', 'src': 'detached', 'dst': 'deleted'},
{'name': 'mount_specials', 'src': 'linked', 'dst': 'specials_mounted'},
{'name': 'unmount_specials', 'src': 'specials_mounted', 'dst': 'linked'},
] ]
extension = 'raw' extension = 'raw'
def can_mount_specials(self):
return self.is_state('attached') or self.is_state('linked')
def create(self, image_path): def create(self, image_path):
self.fsm.create(image_path=image_path) self.fsm.create(image_path=image_path)

View file

@ -34,12 +34,7 @@ class CreateFromSnapshot(Task):
time.sleep(5) time.sleep(5)
info.volume.update() info.volume.update()
info.volume.force_state('detached_fmt') set_fs_states(info.volume)
partitions_state = 'formatted'
if 'partitions' in info.manifest.volume:
partitions_state = 'unmapped_fmt'
for partition in info.volume.partition_map.partitions:
partition.force_state(partitions_state)
class CopyImage(Task): class CopyImage(Task):
@ -68,10 +63,20 @@ class CreateFromImage(Task):
info.volume.image_path = os.path.join(info.workspace, 'volume.{ext}'.format(ext=info.volume.extension)) info.volume.image_path = os.path.join(info.workspace, 'volume.{ext}'.format(ext=info.volume.extension))
loopback_backup_path = info.manifest.plugins['prebootstrapped']['image'] loopback_backup_path = info.manifest.plugins['prebootstrapped']['image']
copyfile(loopback_backup_path, info.volume.image_path) copyfile(loopback_backup_path, info.volume.image_path)
set_fs_states(info.volume)
info.volume.force_state('detached_fmt')
partitions_state = 'formatted' def set_fs_states(volume):
if 'partitions' in info.manifest.volume: volume.set_state('detached')
p_map = volume.partition_map
partitions_state = 'attached'
from base.fs.partitionmaps.none import NoPartitions
if isinstance(p_map, NoPartitions):
p_map.set_state('created')
partitions_state = 'formatted'
else:
p_map.set_state('unmapped')
partitions_state = 'unmapped_fmt' partitions_state = 'unmapped_fmt'
for partition in info.volume.partition_map.partitions: for partition in p_map.partitions:
partition.force_state(partitions_state) partition.set_state(partitions_state)

View file

@ -16,7 +16,7 @@ class ConfigureGrub(Task):
boot_dir = os.path.join(info.root, 'boot') boot_dir = os.path.join(info.root, 'boot')
grub_dir = os.path.join(boot_dir, 'grub') grub_dir = os.path.join(boot_dir, 'grub')
from partitionmaps.none import NoPartitions from base.fs.partitionmaps.none import NoPartitions
def remount(volume, fn): def remount(volume, fn):
# GRUB cannot deal with installing to loopback devices # GRUB cannot deal with installing to loopback devices
@ -28,10 +28,13 @@ class ConfigureGrub(Task):
boot_dir = p_map.boot.mount_dir boot_dir = p_map.boot.mount_dir
p_map.boot.unmount() p_map.boot.unmount()
p_map.root.unmount() p_map.root.unmount()
if isinstance(self.partition_map, NoPartitions): if not isinstance(p_map, NoPartitions):
p_map.unmap() p_map.unmap()
fn() fn()
p_map.map() p_map.map()
else:
fn()
p_map.root.device_path = volume.device_path
p_map.root.mount(info.root) p_map.root.mount(info.root)
if hasattr(p_map, 'boot'): if hasattr(p_map, 'boot'):
p_map.boot.mount(boot_dir) p_map.boot.mount(boot_dir)