From a85ef8ca229d26ff35787f53b30713fe774ee88a Mon Sep 17 00:00:00 2001 From: James Thomas Date: Wed, 4 Feb 2015 11:30:03 +0000 Subject: Add support for updating existing fstab files to writeexts/ssh-rsync When upgrading (using ssh-rsync) from an existing rawdisk image, there will already be an fstab. This patch adds support to update the UUID when a fstab file already exists --- morphlib/exts/ssh-rsync.write | 17 ++++++++++++++++- morphlib/writeexts.py | 19 +++++++++++++++---- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/morphlib/exts/ssh-rsync.write b/morphlib/exts/ssh-rsync.write index c4577026..81b35a7c 100755 --- a/morphlib/exts/ssh-rsync.write +++ b/morphlib/exts/ssh-rsync.write @@ -103,6 +103,13 @@ class SshRsyncWriteExtension(morphlib.writeexts.WriteExtension): location, ['btrfs', 'subvolume', 'delete', new_orig]) raise + def fstab_exists(self, temp_root): + if (os.path.isfile(os.path.join(temp_root, 'etc', 'fstab'))): + temp_fstab = os.path.abspath(os.path.join(temp_root, os.pardir, + 'fstab')) + return temp_fstab + return None + def populate_remote_orig(self, location, new_orig, temp_root): '''Populate the subvolume version_root/orig on location''' @@ -110,6 +117,10 @@ class SshRsyncWriteExtension(morphlib.writeexts.WriteExtension): cliapp.runcmd(['rsync', '-as', '--checksum', '--numeric-ids', '--delete', temp_root + os.path.sep, '%s:%s' % (location, new_orig)]) + if self.fstab_exists(temp_root): + cliapp.runcmd(['rsync', '-as', '--checksum', '--numeric-ids', + '--delete', self.fstab_exists(temp_root), + '%s:%s' % (location, new_orig+'/etc/')]) @contextlib.contextmanager def _deployed_version(self, location, version_label, @@ -132,7 +143,11 @@ class SshRsyncWriteExtension(morphlib.writeexts.WriteExtension): uuid = cliapp.ssh_runcmd(location, ['blkid', '-s', 'UUID', '-o', 'value', root_disk]).strip() - self.complete_fstab_for_btrfs_layout(temp_root, uuid) + # If we're upgrading from a rawdisk image, there may be an existing + # fstab file, we don't want to change that on the image, so create a + # temporary directory to store the new file in + temp_fstab = self.fstab_exists(temp_root) + self.complete_fstab_for_btrfs_layout(temp_root, uuid, temp_fstab) version_label = os.environ['VERSION_LABEL'] autostart = self.get_environment_boolean('AUTOSTART') diff --git a/morphlib/writeexts.py b/morphlib/writeexts.py index 6ab2dd55..6948f7f5 100644 --- a/morphlib/writeexts.py +++ b/morphlib/writeexts.py @@ -74,9 +74,11 @@ class Fstab(object): self.text += line + '\n' - def write(self): + def write(self, writepath=None): '''Rewrite the fstab file to include all new entries.''' - with morphlib.savefile.SaveFile(self.filepath, 'w') as f: + if writepath is None: + writepath = self.filepath + with morphlib.savefile.SaveFile(writepath, 'w') as f: f.write(self.text) @@ -348,7 +350,8 @@ class WriteExtension(cliapp.Application): filepath = os.path.join(existing_state_dir, filename) cliapp.runcmd(['mv', filepath, subvolume]) - def complete_fstab_for_btrfs_layout(self, system_dir, rootfs_uuid=None): + def complete_fstab_for_btrfs_layout(self, system_dir, rootfs_uuid=None, + temp_fstab=None): '''Fill in /etc/fstab entries for the default Btrfs disk layout. In the future we should move this code out of the write extension and @@ -368,9 +371,15 @@ class WriteExtension(cliapp.Application): fstab = Fstab(os.path.join(system_dir, 'etc', 'fstab')) existing_mounts = fstab.get_mounts() + old_root_device = None if '/' in existing_mounts: root_device = existing_mounts['/'] + new_root_device = (None if rootfs_uuid is None else + 'UUID=%s' % rootfs_uuid) + if new_root_device is not None and root_device is not new_root_device: + old_root_device = root_device + root_device = new_root_device else: root_device = (self.get_root_device() if rootfs_uuid is None else 'UUID=%s' % rootfs_uuid) @@ -385,7 +394,9 @@ class WriteExtension(cliapp.Application): '%s /%s btrfs subvol=%s,defaults,rw,noatime 0 2' % (root_device, state_dir, state_subvol)) - fstab.write() + if old_root_device is not None: + fstab.text = fstab.text.replace(old_root_device, root_device) + fstab.write(temp_fstab) return state_dirs_to_create def find_initramfs(self, temp_root): -- cgit v1.2.1