diff options
author | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2014-11-21 11:12:18 +0000 |
---|---|---|
committer | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2014-11-21 11:12:18 +0000 |
commit | 47fb728f2432929868666afc915dbc5a64836c08 (patch) | |
tree | 39642fa9f109e1ba32cca5fe567bf95da0a25c5a | |
parent | 3190be6906eb21a1ba6878d3c8edb4bd16f925d7 (diff) | |
parent | 7e9fc9e90b9f766cdd0bf7dbd142088dd604c1a5 (diff) | |
download | tbdiff-47fb728f2432929868666afc915dbc5a64836c08.tar.gz |
Merge remote-tracking branch 'origin/baserock/james/add_boot_device'
Reviewed-By: Paul Sherwood <paul.sherwood@codethink.co.uk>
Reviewed-By: Sam Thursfield <sam.thursfield@codethink.co.uk>
-rwxr-xr-x | system-version-manager/system-version-manager | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/system-version-manager/system-version-manager b/system-version-manager/system-version-manager index dcd7b80..554e459 100755 --- a/system-version-manager/system-version-manager +++ b/system-version-manager/system-version-manager @@ -41,6 +41,7 @@ class SystemVersionManager(object): def __init__(self, args, mount_dir): self.device, self.current_system = self._get_mount_info() self.mount_dir = mount_dir + self.boot_dir = mount_dir self.device_uuid = self._get_device_uuid(self.device) # create the top-level parser @@ -99,11 +100,22 @@ class SystemVersionManager(object): if os.path.isdir(os.path.join(systems, filename)) and not os.path.islink(os.path.join(systems, filename))] + # U-boot expects extlinux.conf to be in an extlinux subfolder, so also + # check for this if /extlinux.conf isn't found + def _get_extlinux_path(self): + file_paths = ['extlinux.conf','extlinux/extlinux.conf'] + for path in file_paths: + extlinux_path = os.path.join(self.boot_dir, path) + if os.path.isfile(extlinux_path): + return extlinux_path + raise AppException( + "No extlinux.conf file found") + # To check which system is the default one, it checks the 'ontimeout' # value in the extlinux.conf file. If it's not present, then pick # the first of the present systems. def _get_default(self): - extlinux = os.path.join(self.mount_dir, 'extlinux.conf') + extlinux = os.path.join(self.boot_dir, self._get_extlinux_path()) with open(extlinux, 'r') as f: for line in f: line = line.rstrip('\n') @@ -144,8 +156,8 @@ class SystemVersionManager(object): def _rewrite_boot_menu(self, device, default, systems): # Logic copied from morphlib.SaveFile to not create # a morphlib dependency. - fd, temp_config = tempfile.mkstemp(dir=self.mount_dir) - config = os.path.join(self.mount_dir, 'extlinux.conf') + fd, temp_config = tempfile.mkstemp(dir=self.boot_dir) + config = os.path.join(self.boot_dir, self._get_extlinux_path()) with os.fdopen(fd, 'w') as f: # If theres no menu.c32 file, add a menu to the extlinux.conf file if self._check_system_syslinux(): @@ -174,8 +186,13 @@ class SystemVersionManager(object): kernel_args += deployment_config.get('KERNEL_ARGS', '') f.write('append %s\n' % kernel_args) os.rename(temp_config, config) + self._update_default_symlink(default, self.mount_dir) + # We may also need to do this for the boot partition + if self.mount_dir != self.boot_dir: + self._update_default_symlink(default, self.boot_dir) - default_path = os.path.join(self.mount_dir, 'systems', 'default') + def _update_default_symlink(self, default, mount_dir): + default_path = os.path.join(mount_dir, 'systems', 'default') if os.path.islink(default_path): self._atomic_symlink_update(default, default_path) @@ -216,6 +233,10 @@ class SystemVersionManager(object): label = self._parse_deploy_location(location) version_root = os.path.join(self.mount_dir, 'systems', label) + install_root = version_root + if self.mount_dir != self.boot_dir: + install_root = os.path.join(self.boot_dir, 'systems', label) + subprocess.call(['mkdir', '-p', install_root]) orig_dir = os.path.join(version_root, 'orig') run_dir = os.path.join(version_root, 'run') @@ -245,17 +266,17 @@ class SystemVersionManager(object): subprocess.call(['cp', '-a', os.path.join(new_var, file), shared_var]) self.status(msg="Installing the kernel") - self._install_kernel(version_root) + self._install_kernel(version_root, install_root) deployment_config = self._get_deployment_config(label) if 'INITRAMFS_PATH' in deployment_config: self.status(msg="Installing the initramfs") self._install_initramfs(deployment_config['INITRAMFS_PATH'], - version_root) + version_root, install_root) if 'DTB_PATH' in deployment_config: self.status(msg="Installing the device tree") self._install_dtb(deployment_config['DTB_PATH'], - version_root) + version_root, install_root) except Exception as e: # We are not controlling if deleting the suvolume fails @@ -265,21 +286,21 @@ class SystemVersionManager(object): self.status(msg="Rewriting boot menu") self._rewrite_boot_menu(self.device, self._get_default(), self._get_systems()) - def _install_kernel(self, version_root): + def _install_kernel(self, version_root, dest_root): '''Install the kernel outside of 'orig' or 'run' subvolumes This code is kind of duplicated in morphlib/writeexts.py. ''' image_names = ['vmlinuz', 'zImage', 'uImage'] - kernel_dest = os.path.join(version_root, 'kernel') + kernel_dest = os.path.join(dest_root, 'kernel') for name in image_names: try_path = os.path.join(version_root, 'run', 'boot', name) if os.path.exists(try_path): shutil.copy2(try_path, kernel_dest) break - def _install_dtb(self, dtb_path, version_root): + def _install_dtb(self, dtb_path, version_root, dest_root): '''Install the devicetree outside of 'orig' or 'run' subvolumes This code is kind of duplicated in morphlib/writeexts.py. @@ -287,17 +308,17 @@ class SystemVersionManager(object): ''' self.status(msg='Installing devicetree') self.status(msg='Device tree path=%s' % dtb_path) - dtb_dest = os.path.join(version_root, 'dtb') + dtb_dest = os.path.join(dest_root, 'dtb') try_path = os.path.join(version_root, 'run', dtb_path) shutil.copy2(try_path, dtb_dest) - def _install_initramfs(self, initramfs_path, version_root): + def _install_initramfs(self, initramfs_path, version_root, dest_root): '''Install the initramfs outside of 'orig' or 'run' subvolumes This code is kind of duplicated in morphlib/writeexts.py. ''' - initramfs_dest = os.path.join(version_root, 'initramfs') + initramfs_dest = os.path.join(dest_root, 'initramfs') initramfs_src = os.path.join(version_root, 'run', initramfs_path) shutil.copy2(initramfs_src, initramfs_dest) @@ -347,16 +368,16 @@ class SystemVersionManager(object): self._check_system_exists(system_name) self._rewrite_boot_menu(self.device, system_name, self._get_systems()) - def mount_fs(self): - subprocess.check_call(['mount', self.device, self.mount_dir]) + def mount_fs(self, device, mount_dir): + subprocess.check_call(['mount', device, mount_dir]) - def umount_fs(self): - subprocess.call(['umount', self.mount_dir]) + def umount_fs(self, mount_dir): + subprocess.call(['umount', mount_dir]) def _check_system_syslinux(self): # It's not essential to have a menu.c32 file, if it's not there we can # add a menu directly to the extlinux.conf file later - menu_file = os.path.join(self.mount_dir, 'menu.c32') + menu_file = os.path.join(self.boot_dir, 'menu.c32') if not os.path.isfile(menu_file): return False return True @@ -364,8 +385,13 @@ class SystemVersionManager(object): def run(self): args = self.args action = args.action + self.mount_fs(self.device, self.mount_dir) + + deployment_config = self._get_deployment_config(self.current_system) + if 'BOOT_DEVICE' in deployment_config: + self.boot_dir = tempfile.mkdtemp() + self.mount_fs(deployment_config['BOOT_DEVICE'], self.boot_dir) - self.mount_fs() try: if action == "list": self.cmd_list() @@ -385,7 +411,10 @@ class SystemVersionManager(object): sys.stderr.write("ERROR, system not compatible: %s\n" % e.args[0]) raise finally: - self.umount_fs() + self.umount_fs(self.mount_dir) + if self.mount_dir != self.boot_dir: + self.umount_fs(self.boot_dir) + os.rmdir(self.boot_dir) mount_dir = tempfile.mkdtemp() try: |