X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=source%2Fsteps%2FInstallBootstrapFS.py;h=044209725b56775cc6612c57f7f4ddd10b81fcc3;hb=81695f5ec3f62b1fb7610388bed4825640d9c770;hp=06f9807d4ab0af1648b85c7ad4aa4a53a4eb6ef0;hpb=1e11592251ab599965bb7dc88b631d14e9be1a60;p=bootmanager.git diff --git a/source/steps/InstallBootstrapFS.py b/source/steps/InstallBootstrapFS.py index 06f9807..0442097 100644 --- a/source/steps/InstallBootstrapFS.py +++ b/source/steps/InstallBootstrapFS.py @@ -15,13 +15,21 @@ import time from Exceptions import * import utils +import systeminfo import BootServerRequest import BootAPI -def Run(vars, log): +def Run(vars, upgrade, log): """ Download core + extensions bootstrapfs tarballs and install on the hard drive + + the upgrade boolean is True when we are upgrading a node root install while + preserving its slice contents; in that case we just perform extra cleanup + before unwrapping the bootstrapfs + this is because the running system may have extraneous files + that is to say, files that are *not* present in the bootstrapfs + and that can impact/clobber the resulting upgrade Expect the following variables from the store: SYSIMG_PATH the path where the system image will be mounted @@ -36,7 +44,7 @@ def Run(vars, log): are mounted. """ - log.write("\n\nStep: Install: bootstrapfs tarball.\n") + log.write("\n\nStep: Install: bootstrapfs tarball (upgrade={}).\n".format(upgrade)) # make sure we have the variables we need try: @@ -71,6 +79,19 @@ def Run(vars, log): bs_request = BootServerRequest.BootServerRequest(vars) + # in upgrade mode, since we skip InstallPartitionDisks + # we need to run this + if upgrade: + log.write("Upgrade mode init : Scanning for devices\n") + systeminfo.get_block_devices_dict(vars, log) + utils.sysexec_noerr("vgscan --mknodes", log) + utils.sysexec_noerr("vgchange -ay", log) + + # debugging info - show in either mode + utils.display_disks_status(PARTITIONS, "In InstallBootstrapFS", log) + + utils.breakpoint("we need to make /dev/mapper/* appear") + log.write("turning on swap space\n") utils.sysexec("swapon {}".format(PARTITIONS["swap"]), log) @@ -101,6 +122,13 @@ def Run(vars, log): # this is now retrieved in GetAndUpdateNodeDetails nodefamily = vars['nodefamily'] extensions = vars['extensions'] + + # in upgrade mode: we need to cleanup the disk to make + # it safe to just untar the new bootstrapfs tarball again + # on top of the hard drive + if upgrade: + CleanupSysimgBeforeUpgrade(SYSIMG_PATH, nodefamily, log) + # the 'plain' option is for tests mostly plain = vars['plain'] if plain: @@ -165,7 +193,7 @@ def Run(vars, log): raise BootManagerException( "FATAL: Unable to download main tarball {} from server."\ .format(source_file)) - # for extensions, just print a warning + # for extensions, just issue a warning else: log.write("WARNING: tarball for extension {} not found\n".format(name)) @@ -214,7 +242,64 @@ def Run(vars, log): now = time.strftime("%Y-%b-%d @ %H:%M %Z", time.gmtime()) stamp.write("Hard drive installed by BootManager {}\n".format(VERSION)) stamp.write("Finished extraction of bootstrapfs on {}\n".format(now)) + # do not modify this, the upgrade code uses this line for checking compatibility stamp.write("Using nodefamily {}\n".format(nodefamily)) stamp.close() return 1 + +# the upgrade hook +def CleanupSysimgBeforeUpgrade(sysimg, target_nodefamily, log): + + areas_to_cleanup = [ + '/boot', + '/usr', + '/var', + '/etc', + '/run', + '/vsys', + ] + + target_pldistro, target_fcdistro, target_arch = target_nodefamily.split('-') + + # minimal check : not all configurations are possible... + + installed_pldistro, installed_fcdistro, installed_arch = None, None, None + installed_virt = None + prefix = "Using nodefamily " + try: + with open("{}/bm-install.txt".format(sysimg)) as infile: + for line in infile: + if line.startswith(prefix): + installed_nodefamily = line.replace(prefix,"").strip() + installed_pldistro, installed_fcdistro, installed_arch = installed_nodefamily.split('-') + # do not break here, bm-install is additive, we want the last one.. + with open("{}/etc/planetlab/virt".format(sysimg)) as infile: + installed_virt = infile.read().strip() + except Exception as e: + print_exc() + raise BootManagerException("Could not retrieve data about previous installation - cannot upgrade") + + # moving from vservers to lxc also means another filesystem + # so plain reinstall is the only option + if installed_virt != 'lxc': + message = """Can only upgrade nodes already running lxc containers +a node running vservers has its /vservers/ partition formatted as ext3 +and we need btrfs to move to containers +your only option here is reinstall""" + raise BootManagerException(message) + + # changing arch is not reasonable either + if target_arch != installed_arch: + raise BootManagerException("Cannot upgrade from arch={} to arch={}" + .format(installed_arch, target_arch)) + + if target_pldistro != installed_pldistro: + log.write("\nWARNING: upgrading across pldistros {} to {} - might not work well..\n" + .format(installed_pldistro, target_pldistro)) + + # otherwise at this point we do not do any more advanced checking + log.write("\n\nPseudo step CleanupSysimgBeforeUpgrade : cleaning up hard drive\n") + + for area in areas_to_cleanup: + utils.sysexec("rm -rf {}/{}".format(sysimg, area))