X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=source%2Fsteps%2FValidateNodeInstall.py;h=a39ee3020e4b6c2313851e3c261abd80ed2917ae;hb=f52080486db907ba6557d1047730c638c4562790;hp=2e807144de77600201f55fa8049383754d44e60d;hpb=bb5fbc8ba39ef808bff8f2ec5c2eda7c11b5304e;p=bootmanager.git diff --git a/source/steps/ValidateNodeInstall.py b/source/steps/ValidateNodeInstall.py index 2e80714..a39ee30 100644 --- a/source/steps/ValidateNodeInstall.py +++ b/source/steps/ValidateNodeInstall.py @@ -1,22 +1,28 @@ +#!/usr/bin/python +# +# Copyright (c) 2003 Intel Corporation +# All rights reserved. +# +# Copyright (c) 2004-2006 The Trustees of Princeton University +# All rights reserved. + import os from Exceptions import * import utils -from systeminfo import systeminfo -import compatibility +import systeminfo import ModelOptions -def Run( vars, log ): +def Run(vars, log): """ See if a node installation is valid. More checks should certainly be done in the future, but for now, make sure that the sym links kernel-boot - and initrd-boot exist in /boot + exist in /boot Expect the following variables to be set: SYSIMG_PATH the path where the system image will be mounted (always starts with TEMP_PATH) - BOOT_CD_VERSION A tuple of the current bootcd version ROOT_MOUNTED the node root file system is mounted NODE_ID The db node_id for this machine PLCONF_DIR The directory to store the configuration file in @@ -25,104 +31,166 @@ def Run( vars, log ): ROOT_MOUNTED the node root file system is mounted """ - log.write( "\n\nStep: Validating node installation.\n" ) + log.write("\n\nStep: Validating node installation.\n") # make sure we have the variables we need try: - BOOT_CD_VERSION= vars["BOOT_CD_VERSION"] - if BOOT_CD_VERSION == "": - raise ValueError, "BOOT_CD_VERSION" - - SYSIMG_PATH= vars["SYSIMG_PATH"] + SYSIMG_PATH = vars["SYSIMG_PATH"] if SYSIMG_PATH == "": - raise ValueError, "SYSIMG_PATH" + raise ValueError("SYSIMG_PATH") - NODE_ID= vars["NODE_ID"] + NODE_ID = vars["NODE_ID"] if NODE_ID == "": - raise ValueError, "NODE_ID" + raise ValueError("NODE_ID") - PLCONF_DIR= vars["PLCONF_DIR"] + PLCONF_DIR = vars["PLCONF_DIR"] if PLCONF_DIR == "": - raise ValueError, "PLCONF_DIR" + raise ValueError("PLCONF_DIR") - NODE_MODEL_OPTIONS= vars["NODE_MODEL_OPTIONS"] + NODE_MODEL_OPTIONS = vars["NODE_MODEL_OPTIONS"] - except KeyError, var: - raise BootManagerException, "Missing variable in vars: %s\n" % var - except ValueError, var: - raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var + PARTITIONS = vars["PARTITIONS"] + if PARTITIONS == None: + raise ValueError("PARTITIONS") + except KeyError as var: + raise BootManagerException("Missing variable in vars: {}\n".format(var)) + except ValueError as var: + raise BootManagerException("Variable in vars, shouldn't be: {}\n".format(var)) - ROOT_MOUNTED= 0 - if 'ROOT_MOUNTED' in vars.keys(): - ROOT_MOUNTED= vars['ROOT_MOUNTED'] + + ROOT_MOUNTED = 0 + if vars.has_key('ROOT_MOUNTED'): + ROOT_MOUNTED = vars['ROOT_MOUNTED'] # mount the root system image if we haven't already. # capture BootManagerExceptions during the vgscan/change and mount # calls, so we can return 0 instead if ROOT_MOUNTED == 0: - # old cds need extra utilities to run lvm - if BOOT_CD_VERSION[0] == 2: - compatibility.setup_lvm_2x_cd( vars, log ) # simply creating an instance of this class and listing the system # block devices will make them show up so vgscan can find the planetlab # volume group - systeminfo().get_block_device_list() + systeminfo.get_block_device_list(vars, log) try: - utils.sysexec( "vgscan", log ) - utils.sysexec( "vgchange -ay planetlab", log ) - except BootManagerException, e: - log.write( "BootManagerException during vgscan/vgchange: %s\n" % - str(e) ) + utils.sysexec("vgscan", log) + utils.sysexec("vgchange -ay planetlab", log) + except BootManagerException as e: + log.write("BootManagerException during vgscan/vgchange: {}\n"\ + .format(str(e))) return 0 - utils.makedirs( SYSIMG_PATH ) + utils.makedirs(SYSIMG_PATH) + + # xxx - TODO - need to fsck the btrfs partition + if vars['virt'] == 'vs': + filesystems_tocheck = ['root', 'vservers'] + else: + filesystems_tocheck = ['root'] + + for filesystem in filesystems_tocheck: + try: + # first run fsck to prevent fs corruption from hanging mount... + log.write("fsck {} file system\n".format(filesystem)) + utils.sysexec("e2fsck -v -p {}".format(PARTITIONS[filesystem]), log, fsck=True) + except BootManagerException as e: + log.write("BootManagerException during fsck of {} ({}) filesystem : {}\n"\ + .format(filesystem, PARTITIONS[filesystem], str(e))) + try: + log.write("Trying to recover filesystem errors on {}\n".format(filesystem)) + utils.sysexec("e2fsck -v -y {}".format(PARTITIONS[filesystem]), log, fsck=True) + except BootManagerException as e: + log.write("BootManagerException while trying to recover" + "filesystem errors on {} ({}) filesystem : {}\n" + .format(filesystem, PARTITIONS[filesystem], str(e))) + return -1 + else: + # disable time/count based filesystems checks + utils.sysexec_noerr("tune2fs -c -1 -i 0 {}".format(PARTITIONS[filesystem]), log) try: - utils.sysexec( "mount /dev/planetlab/root %s" % SYSIMG_PATH, log ) - utils.sysexec( "mount /dev/planetlab/vservers %s/vservers" % - SYSIMG_PATH, log ) - utils.sysexec( "mount -t proc none %s/proc" % SYSIMG_PATH, log ) - except BootManagerException, e: - log.write( "BootManagerException during vgscan/vgchange: %s\n" % - str(e) ) - return 0 - - ROOT_MOUNTED= 1 - vars['ROOT_MOUNTED']= 1 + # then attempt to mount them + log.write("mounting root file system\n") + utils.sysexec("mount -t ext3 {} {}".format(PARTITIONS["root"], SYSIMG_PATH),log) + except BootManagerException as e: + log.write("BootManagerException during mount of /root: {}\n".format(str(e))) + return -2 + + try: + PROC_PATH = "{}/proc".format(SYSIMG_PATH) + utils.makedirs(PROC_PATH) + log.write("mounting /proc\n") + utils.sysexec("mount -t proc none {}".format(PROC_PATH), log) + except BootManagerException as e: + log.write("BootManagerException during mount of /proc: {}\n".format(str(e))) + return -2 + + + one_partition = vars['ONE_PARTITION']=='1' + + if (not one_partition): + try: + VSERVERS_PATH = "{}/vservers".format(SYSIMG_PATH) + utils.makedirs(VSERVERS_PATH) + log.write("mounting vservers partition in root file system\n") + if vars['virt'] == 'vs': + utils.sysexec("mount -t ext3 {} {}".format(PARTITIONS["vservers"], VSERVERS_PATH), log) + else: + utils.sysexec("mount -t btrfs {} {}".format(PARTITIONS["vservers"], VSERVERS_PATH), log) + except BootManagerException as e: + log.write("BootManagerException while mounting /vservers: {}\n".format(str(e))) + return -2 + + ROOT_MOUNTED = 1 + vars['ROOT_MOUNTED'] = 1 - - # get the kernel version + # check if the base kernel is installed + # these 2 links are created by our kernel's post-install scriplet + log.write("Checking for a custom kernel\n") + try: + if vars['virt'] == 'vs': + os.stat("{}/boot/kernel-boot".format(SYSIMG_PATH)) + else: + try: + kversion = os.popen("chroot {} rpm -qa kernel | tail -1 | cut -c 8-"\ + .format(SYSIMG_PATH)).read().rstrip() + os.stat("{}/boot/vmlinuz-{}".format(SYSIMG_PATH, kversion)) + major_version = int(kversion[0]) # Check if the string looks like a kernel version + except: + kversion = os.popen("ls -lrt {}/lib/modules | tail -1 | awk '{print $9;}'"\ + .format(SYSIMG_PATH)).read().rstrip() + except OSError as e: + log.write("Couldn't locate base kernel (you might be using the stock kernel).\n") + return -3 + + # check if the model specified kernel is installed option = '' if NODE_MODEL_OPTIONS & ModelOptions.SMP: option = 'smp' - - files = ("kernel-boot%s" % option, "initrd-boot%s" % option) - valid= 1 - for filepath in files: - if not os.access("%s/boot/%s"%(SYSIMG_PATH,filepath),os.F_OK|os.R_OK): - log.write( "Node not properly installed:\n") - log.write( "\tmissing file /boot/%s\n" % filepath ) - valid= 0 - - if not valid: - return 0 - + try: + os.stat("{}/boot/kernel-boot{}".format(SYSIMG_PATH, option)) + except OSError as e: + # smp kernel is not there; remove option from modeloptions + # such that the rest of the code base thinks we are just + # using the base kernel. + NODE_MODEL_OPTIONS = NODE_MODEL_OPTIONS & ~ModelOptions.SMP + vars["NODE_MODEL_OPTIONS"] = NODE_MODEL_OPTIONS + log.write("WARNING: Couldn't locate smp kernel.\n") + # write out the node id to /etc/planetlab/node_id. if this fails, return # 0, indicating the node isn't a valid install. try: - node_id_file_path= "%s/%s/node_id" % (SYSIMG_PATH,PLCONF_DIR) - node_id_file= file( node_id_file_path, "w" ) - node_id_file.write( str(NODE_ID) ) + node_id_file_path = "{}/{}/node_id".format(SYSIMG_PATH, PLCONF_DIR) + node_id_file = file(node_id_file_path, "w") + node_id_file.write(str(NODE_ID)) node_id_file.close() - node_id_file= None - log.write( "Updated /etc/planetlab/node_id" ) - except IOError, e: - log.write( "Unable to write out /etc/planetlab/node_id" ) + node_id_file = None + log.write("Updated /etc/planetlab/node_id\n") + except IOError as e: + log.write("Unable to write out /etc/planetlab/node_id\n") return 0 - log.write( "Everything appears to be ok\n" ) + log.write("Node installation appears to be ok\n") return 1