From 094a91004df52c1db9cbdd65abe8bff6dbccd99c Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Mon, 17 Nov 2008 14:07:59 +0000 Subject: [PATCH] * improve availability - reliability : start a fallback sshd very early in the bm logic * bm log upload (formerly known as alpina-logs) is avail. back again (requires nodeconfig-5.0-2) * code cleanup : remove support for bootCD-2.x see http://svn.planet-lab.org/ticket/427 --- Makefile | 2 +- source/BootManager.py | 115 +++++---- source/compatibility.py | 226 ------------------ .../{sshd_config_v3 => sshd_config} | 0 source/debug_files/sshd_config_v2 | 93 ------- source/steps/ChainBootNode.py | 17 +- source/steps/CheckForNewDisks.py | 38 +-- source/steps/CheckHardwareRequirements.py | 11 - source/steps/GetAndUpdateNodeDetails.py | 5 - source/steps/InitializeBootManager.py | 18 -- source/steps/InstallBootstrapFS.py | 2 +- source/steps/InstallPartitionDisks.py | 100 ++------ source/steps/InstallWriteConfig.py | 6 - source/steps/ReadNodeConfiguration.py | 164 ++++++------- source/steps/StartDebug.py | 116 ++++----- source/steps/ValidateNodeInstall.py | 11 +- source/utils.py | 109 +++++---- 17 files changed, 270 insertions(+), 763 deletions(-) delete mode 100644 source/compatibility.py rename source/debug_files/{sshd_config_v3 => sshd_config} (100%) delete mode 100644 source/debug_files/sshd_config_v2 diff --git a/Makefile b/Makefile index 241c8bf..7cb8a65 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ PLCSSH:=root@$(PLCHOST):/vservers/$(VSERVER) endif endif -LOCAL_RSYNC_EXCLUDES := --exclude '*.pyc' +LOCAL_RSYNC_EXCLUDES := --exclude '*.pyc' --exclude debug_root_ssh_key RSYNC_EXCLUDES := --exclude .svn --exclude CVS --exclude '*~' --exclude TAGS $(LOCAL_RSYNC_EXCLUDES) RSYNC_COND_DRY_RUN := $(if $(findstring n,$(MAKEFLAGS)),--dry-run,) RSYNC := rsync -a -v $(RSYNC_COND_DRY_RUN) $(RSYNC_EXCLUDES) diff --git a/source/BootManager.py b/source/BootManager.py index f2462bc..46b5759 100755 --- a/source/BootManager.py +++ b/source/BootManager.py @@ -17,35 +17,29 @@ import notify_messages import BootServerRequest # all output is written to this file -LOG_FILE= "/tmp/bm.log" -UPLOAD_LOG_PATH = "/alpina-logs/upload.php" +BM_NODE_LOG= "/tmp/bm.log" +UPLOAD_LOG_SCRIPT = "/boot/upload-bmlog.php" # the new contents of PATH when the boot manager is running BIN_PATH= ('/usr/local/bin', '/usr/local/sbin', - '/bin', - '/sbin', '/usr/bin', '/usr/sbin', - '/usr/local/planetlab/bin') + '/bin', + '/sbin') - -# the set of valid node run states -NodeRunStates = {} - +############################## class log: format="%H:%M:%S(%Z) " def __init__( self, OutputFilePath= None ): - if OutputFilePath: - try: - self.OutputFilePath= OutputFilePath - self.OutputFile= gzip.GzipFile( OutputFilePath, "w", 9 ) - except: - print( "Unable to open output file for log, continuing" ) - self.OutputFile= None - + try: + self.OutputFile= open( OutputFilePath, "w") + self.OutputFilePath= OutputFilePath + except: + print( "bootmanager log : Unable to open output file %r, continuing"%OutputFilePath ) + self.OutputFile= None def LogEntry( self, str, inc_newline= 1, display_screen= 1 ): now=time.strftime(log.format, time.localtime()) @@ -63,46 +57,46 @@ class log: if self.OutputFile: self.OutputFile.flush() - - def write( self, str ): """ make log behave like a writable file object (for traceback prints) """ self.LogEntry( str, 0, 1 ) - - + # bm log uploading is available back again, as of nodeconfig-5.0-2 def Upload( self ): """ upload the contents of the log to the server """ - if self.OutputFile is not None: - self.LogEntry( "NOTE: upload logs is known to be broken (beg)") - self.LogEntry( "Uploading logs to %s" % UPLOAD_LOG_PATH ) + self.OutputFile.flush() + + self.LogEntry( "Uploading logs to %s" % UPLOAD_LOG_SCRIPT ) self.OutputFile.close() self.OutputFile= None bs_request = BootServerRequest.BootServerRequest() - bs_request.MakeRequest(PartialPath = UPLOAD_LOG_PATH, + bs_request.MakeRequest(PartialPath = UPLOAD_LOG_SCRIPT, GetVars = None, PostVars = None, FormData = ["log=@" + self.OutputFilePath], DoSSL = True, DoCertCheck = True) - self.LogEntry( "NOTE: upload logs is known to be broken (end)") - - - - - +############################## class BootManager: # file containing initial variables/constants VARS_FILE = "configuration" + # the set of valid node run states + NodeRunStates = {'install':None, + 'reinstall':None, + 'boot':None, + 'failboot':None, + 'safeboot':None, + 'disabled':None, + } def __init__(self, log, forceState): # override machine's current state from the command line @@ -151,8 +145,7 @@ class BootManager: # we know will work with all the boot cds os.environ['PATH']= string.join(BIN_PATH,":") - # this contains a set of information used and updated - # by each step + # this contains a set of information used and updated by each step self.VARS= vars self.CAN_RUN= 1 @@ -193,6 +186,14 @@ class BootManager: # checking whether someone added or changed disks, and # then finally chain boots. + # starting the fallback/debug ssh daemon for safety: + # if the node install somehow hangs, or if it simply takes ages, + # we can still enter and investigate + try: + StartDebug.Run(self.VARS, self.LOG, last_resort = False) + except: + pass + InstallInit.Run( self.VARS, self.LOG ) if ValidateNodeInstall.Run( self.VARS, self.LOG ): WriteModprobeConfig.Run( self.VARS, self.LOG ) @@ -205,6 +206,15 @@ class BootManager: _nodeNotInstalled() def _reinstallRun(): + + # starting the fallback/debug ssh daemon for safety: + # if the node install somehow hangs, or if it simply takes ages, + # we can still enter and investigate + try: + StartDebug.Run(self.VARS, self.LOG, last_resort = False) + except: + pass + # implements the reinstall logic, which will check whether # the min. hardware requirements are met, install the # software, and upon correct installation will switch too @@ -226,7 +236,7 @@ class BootManager: UpdateBootStateWithPLC.Run( self.VARS, self.LOG ) _bootRun() - def _newRun(): + def _installRun(): # implements the new install logic, which will first check # with the user whether it is ok to install on this # machine, switch to 'reinstall' state and then invoke the reinstall @@ -239,25 +249,23 @@ class BootManager: _reinstallRun() def _debugRun(state='failboot'): - # implements debug logic, which just starts the sshd - # and just waits around + # implements debug logic, which starts the sshd and just waits around self.VARS['BOOT_STATE']=state UpdateBootStateWithPLC.Run( self.VARS, self.LOG ) StartDebug.Run( self.VARS, self.LOG ) - def _badRun(): + def _badstateRun(): # should never happen; log event self.LOG.write( "\nInvalid BOOT_STATE = %s\n" % self.VARS['BOOT_STATE']) _debugRun() - global NodeRunStates # setup state -> function hash table - NodeRunStates['install'] = _newRun - NodeRunStates['reinstall'] = _reinstallRun - NodeRunStates['boot'] = _bootRun - NodeRunStates['failboot'] = _bootRun # should always try to boot. - NodeRunStates['safeboot'] = lambda : _debugRun('safeboot') - NodeRunStates['disabled'] = lambda : _debugRun('disabled') + BootManager.NodeRunStates['install'] = _installRun + BootManager.NodeRunStates['reinstall'] = _reinstallRun + BootManager.NodeRunStates['boot'] = _bootRun + BootManager.NodeRunStates['failboot'] = _bootRun # should always try to boot. + BootManager.NodeRunStates['safeboot'] = lambda : _debugRun('safeboot') + BootManager.NodeRunStates['disabled'] = lambda : _debugRun('disabled') success = 0 try: @@ -271,7 +279,7 @@ class BootManager: self.VARS['BOOT_STATE']= self.forceState UpdateBootStateWithPLC.Run( self.VARS, self.LOG ) - stateRun = NodeRunStates.get(self.VARS['BOOT_STATE'],_badRun) + stateRun = BootManager.NodeRunStates.get(self.VARS['BOOT_STATE'],_badstateRun) stateRun() success = 1 @@ -302,22 +310,14 @@ def main(argv): import utils utils.prompt_for_breakpoint_mode() - #utils.breakpoint ("Entering BootManager::main") + utils.breakpoint ("Entering BootManager::main") - global NodeRunStates - NodeRunStates = {'install':None, - 'reinstall':None, - 'boot':None, - 'safeboot':None, - 'failboot':None, - 'disabled':None, } - # set to 1 if error occurred error= 0 # all output goes through this class so we can save it and post # the data back to PlanetLab central - LOG= log( LOG_FILE ) + LOG= log( BM_NODE_LOG ) LOG.LogEntry( "BootManager started at: %s" % \ time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) ) @@ -326,7 +326,7 @@ def main(argv): forceState = None if len(argv) == 2: fState = argv[1] - if NodeRunStates.has_key(fState): + if BootManager.NodeRunStates.has_key(fState): forceState = fState else: LOG.LogEntry("FATAL: cannot force node run state to=%s" % fState) @@ -346,8 +346,7 @@ def main(argv): if bm.CAN_RUN == 0: LOG.LogEntry( "Unable to initialize BootManager." ) else: - LOG.LogEntry( "Running version %s of BootManager." % - bm.VARS['VERSION'] ) + LOG.LogEntry( "Running version %s of BootManager." % bm.VARS['VERSION'] ) success= bm.Run() if success: LOG.LogEntry( "\nDone!" ); diff --git a/source/compatibility.py b/source/compatibility.py deleted file mode 100644 index 07c3597..0000000 --- a/source/compatibility.py +++ /dev/null @@ -1,226 +0,0 @@ -#!/usr/bin/python - -# Copyright (c) 2003 Intel Corporation -# All rights reserved. -# -# Copyright (c) 2004-2006 The Trustees of Princeton University -# All rights reserved. - - -""" -Various functions that are used to allow the boot manager to run on various -different cds are included here -""" - -import string -import os, sys - -from Exceptions import * -import utils -import BootServerRequest - - -def setup_lvm_2x_cd( vars, log ): - """ - make available a set of lvm utilities for 2.x cds that don't have them - on the cd. - - Expect the following variables to be set: - TEMP_PATH somewhere to store what we need to run - BOOT_CD_VERSION A tuple of the current bootcd version - SUPPORT_FILE_DIR directory on the boot servers containing - scripts and support files - LVM_SETUP_2X_CD indicates if lvm is downloaded and setup for 2.x cds - - Set the following variables upon successfully running: - LVM_SETUP_2X_CD indicates if lvm is downloaded and setup for 2.x cds - """ - - # make sure we have the variables we need - try: - TEMP_PATH= vars["TEMP_PATH"] - if TEMP_PATH == "": - raise ValueError, "TEMP_PATH" - - BOOT_CD_VERSION= vars["BOOT_CD_VERSION"] - if BOOT_CD_VERSION == "": - raise ValueError, "BOOT_CD_VERSION" - - SUPPORT_FILE_DIR= vars["SUPPORT_FILE_DIR"] - if SUPPORT_FILE_DIR == None: - raise ValueError, "SUPPORT_FILE_DIR" - - 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 - - - if BOOT_CD_VERSION[0] != 2: - log.write( "Only 2.x boot cds need lvm setup manually.\n" ) - return 1 - - LVM_SETUP_2X_CD= 0 - if 'LVM_SETUP_2X_CD' in vars.keys(): - LVM_SETUP_2X_CD= vars['LVM_SETUP_2X_CD'] - - if LVM_SETUP_2X_CD: - log.write( "LVM already downloaded and setup\n" ) - return 1 - - log.write( "Downloading additional libraries for lvm\n" ) - - bs_request= BootServerRequest.BootServerRequest() - - utils.makedirs(TEMP_PATH) - - # download and extract support tarball for this step, - # which has everything we need to successfully run - step_support_file= "alpina-BootLVM.tar.gz" - source_file= "%s/%s" % (SUPPORT_FILE_DIR,step_support_file) - dest_file= "%s/%s" % (TEMP_PATH, step_support_file) - - log.write( "Downloading support file for this step\n" ) - result= bs_request.DownloadFile( source_file, None, None, - 1, 1, dest_file ) - if not result: - raise BootManagerException, "Download failed." - - log.write( "Extracting support files\n" ) - old_wd= os.getcwd() - utils.chdir( TEMP_PATH ) - utils.sysexec( "tar -C / -xzf %s" % step_support_file, log ) - utils.removefile( dest_file ) - utils.chdir( old_wd ) - - utils.sysexec( "ldconfig", log ) - - # load lvm-mod - log.write( "Loading lvm module\n" ) - utils.sysexec( "modprobe lvm-mod", log ) - - # take note that we have lvm setup - LVM_SETUP_2X_CD= 1 - vars['LVM_SETUP_2X_CD']= LVM_SETUP_2X_CD - - return 1 - - - -def setup_partdisks_2x_cd( vars, log ): - """ - download necessary files to handle partitioning disks on 2.x cds - - Expect the following variables to be set: - TEMP_PATH somewhere to store what we need to run - BOOT_CD_VERSION A tuple of the current bootcd version - SUPPORT_FILE_DIR directory on the boot servers containing - scripts and support files - PARTDISKS_SETUP_2X_CD indicates if lvm is downloaded and setup for 2.x cds - - Set the following variables upon successfully running: - PARTDISKS_SETUP_2X_CD indicates if lvm is downloaded and setup for 2.x cds - """ - - # make sure we have the variables we need - try: - TEMP_PATH= vars["TEMP_PATH"] - if TEMP_PATH == "": - raise ValueError, "TEMP_PATH" - - BOOT_CD_VERSION= vars["BOOT_CD_VERSION"] - if BOOT_CD_VERSION == "": - raise ValueError, "BOOT_CD_VERSION" - - SUPPORT_FILE_DIR= vars["SUPPORT_FILE_DIR"] - if SUPPORT_FILE_DIR == None: - raise ValueError, "SUPPORT_FILE_DIR" - - 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 - - - if BOOT_CD_VERSION[0] != 2: - log.write( "Only 2.x boot cds need partition disk tools setup manually.\n" ) - return 1 - - PARTDISKS_SETUP_2X_CD= 0 - if 'PARTDISKS_SETUP_2X_CD' in vars.keys(): - PARTDISKS_SETUP_2X_CD= vars['PARTDISKS_SETUP_2X_CD'] - - if PARTDISKS_SETUP_2X_CD: - log.write( "Partition disk tools already downloaded and setup\n" ) - return 1 - - log.write( "Downloading additional libraries for partitioning disks\n" ) - - bs_request= BootServerRequest.BootServerRequest() - - # download and extract support tarball for this step, - # which has everything we need to successfully run - step_support_file= "alpina-PartDisks.tar.gz" - source_file= "%s/%s" % (SUPPORT_FILE_DIR,step_support_file) - dest_file= "%s/%s" % (TEMP_PATH, step_support_file) - - log.write( "Downloading support file for this step\n" ) - result= bs_request.DownloadFile( source_file, None, None, - 1, 1, dest_file ) - if not result: - raise BootManagerException, "Download failed." - - log.write( "Extracting support files\n" ) - old_wd= os.getcwd() - utils.chdir( TEMP_PATH ) - utils.sysexec( "tar -xzf %s" % step_support_file, log ) - utils.removefile( dest_file ) - utils.chdir( old_wd ) - - # also included in the support package was a list of extra - # paths (lib-paths) for /etc/ld.so.conf. - # so add those, and rerun ldconfig - # so we can make our newly downloaded libraries available - - ldconf_file= file("/etc/ld.so.conf","a+") - lib_paths_file= file( TEMP_PATH + "/lib-paths","r") - - for line in lib_paths_file: - path= string.strip(line) - if path != "": - ldconf_file.write( "%s/%s\n" % (TEMP_PATH,path) ) - ldconf_file.close() - lib_paths_file.close() - - utils.sysexec( "ldconfig", log ) - - # update the PYTHONPATH to include the python modules in - # the support package - sys.path.append( TEMP_PATH + "/usr/lib/python2.2" ) - sys.path.append( TEMP_PATH + "/usr/lib/python2.2/site-packages" ) - - # update the environment variable PATH to include - # TEMP_PATH/sbin and others there - new_paths= ('%s/sbin'% TEMP_PATH, - '%s/bin'% TEMP_PATH, - '%s/user/sbin'% TEMP_PATH, - '%s/user/bin'% TEMP_PATH) - - old_path= os.environ['PATH'] - os.environ['PATH']= old_path + ":" + string.join(new_paths,":") - - # everything should be setup to import parted. this - # import is just to make sure it'll work when this step - # is being run - log.write( "Imported parted\n" ) - try: - import parted - except ImportError: - raise BootManagerException, "Unable to import parted." - - # take note that we have part disks setup - PARTDISKS_SETUP_2X_CD= 1 - vars['PARTDISKS_SETUP_2X_CD']= PARTDISKS_SETUP_2X_CD - - - diff --git a/source/debug_files/sshd_config_v3 b/source/debug_files/sshd_config similarity index 100% rename from source/debug_files/sshd_config_v3 rename to source/debug_files/sshd_config diff --git a/source/debug_files/sshd_config_v2 b/source/debug_files/sshd_config_v2 deleted file mode 100644 index 76e0092..0000000 --- a/source/debug_files/sshd_config_v2 +++ /dev/null @@ -1,93 +0,0 @@ -# boot cd version 3.x sshd configuration file for debug mode - -#Port 22 -Protocol 2 -#ListenAddress 0.0.0.0 -#ListenAddress :: - -# HostKey for protocol version 1 -#HostKey /etc/ssh/ssh_host_key -# HostKeys for protocol version 2 -#HostKey /etc/ssh/ssh_host_rsa_key -#HostKey /etc/ssh/ssh_host_dsa_key - -# Lifetime and size of ephemeral version 1 server key -#KeyRegenerationInterval 1h -#ServerKeyBits 768 - -# Logging -#obsoletes QuietMode and FascistLogging -#SyslogFacility AUTH -SyslogFacility AUTHPRIV -#LogLevel INFO - -# Authentication: - -#LoginGraceTime 2m -#PermitRootLogin yes -#StrictModes yes -#MaxAuthTries 6 - -#RSAAuthentication yes -#PubkeyAuthentication yes -#AuthorizedKeysFile .ssh/authorized_keys - -# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts -#RhostsRSAAuthentication no -# similar for protocol version 2 -#HostbasedAuthentication no -# Change to yes if you don't trust ~/.ssh/known_hosts for -# RhostsRSAAuthentication and HostbasedAuthentication -#IgnoreUserKnownHosts no -# Don't read the user's ~/.rhosts and ~/.shosts files -#IgnoreRhosts yes - -# To disable tunneled clear text passwords, change to no here! -#PermitEmptyPasswords no -PasswordAuthentication no - -# Change to no to disable s/key passwords -#ChallengeResponseAuthentication yes -ChallengeResponseAuthentication no - -# Kerberos options -#KerberosAuthentication no -#KerberosOrLocalPasswd yes -#KerberosTicketCleanup yes -#KerberosGetAFSToken no - -# Set this to 'yes' to enable PAM authentication, account processing, -# and session processing. If this is enabled, PAM authentication will -# be allowed through the ChallengeResponseAuthentication mechanism. -# Depending on your PAM configuration, this may bypass the setting of -# PasswordAuthentication, PermitEmptyPasswords, and -# "PermitRootLogin without-password". If you just want the PAM account and -# session checks to run without PAM authentication, then enable this but set -# ChallengeResponseAuthentication=no -PAMAuthenticationViaKbdInt no - -#AllowTcpForwarding yes -#GatewayPorts no -#X11Forwarding no -X11Forwarding yes -#X11DisplayOffset 10 -#X11UseLocalhost yes -#PrintMotd yes -#PrintLastLog yes -#TCPKeepAlive yes -#UseLogin no -#UsePrivilegeSeparation yes -#PermitUserEnvironment no -#Compression yes -#ClientAliveInterval 0 -#ClientAliveCountMax 3 -#UseDNS yes -#PidFile /var/run/sshd.pid -#MaxStartups 10 -#ShowPatchLevel no - -# no default banner path -#Banner /some/path - -# override default of no subsystems -Subsystem sftp /usr/libexec/openssh/sftp-server diff --git a/source/steps/ChainBootNode.py b/source/steps/ChainBootNode.py index 7edcf12..08a31ac 100644 --- a/source/steps/ChainBootNode.py +++ b/source/steps/ChainBootNode.py @@ -15,7 +15,6 @@ import UpdateBootStateWithPLC import UpdateNodeConfiguration from Exceptions import * import utils -import compatibility import systeminfo import BootAPI import notify_messages @@ -31,7 +30,6 @@ def Run( vars, log ): booting has occurred. Expect the following variables: - BOOT_CD_VERSION A tuple of the current bootcd version SYSIMG_PATH the path where the system image will be mounted (always starts with TEMP_PATH) ROOT_MOUNTED the node root file system is mounted @@ -47,10 +45,6 @@ def Run( vars, log ): # 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"] if SYSIMG_PATH == "": raise ValueError, "SYSIMG_PATH" @@ -74,16 +68,12 @@ def Run( vars, log ): raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var ROOT_MOUNTED= 0 - if 'ROOT_MOUNTED' in vars.keys(): + if vars.has_key('ROOT_MOUNTED'): ROOT_MOUNTED= vars['ROOT_MOUNTED'] if ROOT_MOUNTED == 0: log.write( "Mounting node partitions\n" ) - # 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 @@ -194,10 +184,7 @@ def Run( vars, log ): utils.sysexec_noerr( "ifconfig eth0 down", log ) - if BOOT_CD_VERSION[0] == 2: - utils.sysexec_noerr( "killall dhcpcd", log ) - elif BOOT_CD_VERSION[0] >= 3: - utils.sysexec_noerr( "killall dhclient", log ) + utils.sysexec_noerr( "killall dhclient", log ) utils.sysexec_noerr( "umount -a -r -t ext2,ext3", log ) utils.sysexec_noerr( "modprobe -r lvm-mod", log ) diff --git a/source/steps/CheckForNewDisks.py b/source/steps/CheckForNewDisks.py index 71fb867..1e368d5 100644 --- a/source/steps/CheckForNewDisks.py +++ b/source/steps/CheckForNewDisks.py @@ -11,7 +11,6 @@ import string import InstallPartitionDisks from Exceptions import * import systeminfo -import compatibility import utils import os @@ -22,7 +21,6 @@ def Run( vars, log ): Expect the following variables to be set: SYSIMG_PATH the path where the system image will be mounted - BOOT_CD_VERSION A tuple of the current bootcd version MINIMUM_DISK_SIZE any disks smaller than this size, in GB, are not used Set the following variables upon successfully running: @@ -33,10 +31,6 @@ def Run( vars, log ): # 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"] if SYSIMG_PATH == "": raise ValueError, "SYSIMG_PATH" @@ -54,11 +48,6 @@ def Run( vars, log ): all_devices= systeminfo.get_block_device_list(vars, log) - # find out if there are unused disks in all_devices that are greater - # than old cds need extra utilities to run lvm - if BOOT_CD_VERSION[0] == 2: - compatibility.setup_lvm_2x_cd( vars, log ) - # will contain the new devices to add to the volume group new_devices= [] @@ -172,21 +161,18 @@ def Run( vars, log ): break log.write( "making the ext3 filesystem match new logical volume size.\n" ) - if BOOT_CD_VERSION[0] == 2: - cmd = "resize2fs %s" % PARTITIONS["vservers"] - resize = utils.sysexec_noerr(cmd,log) - elif BOOT_CD_VERSION[0] >= 3: - vars['ROOT_MOUNTED']= 1 - cmd = "mount %s %s" % (PARTITIONS["root"],SYSIMG_PATH) - utils.sysexec_noerr( cmd, log ) - cmd = "mount %s %s/vservers" % \ - (PARTITIONS["vservers"],SYSIMG_PATH) - utils.sysexec_noerr( cmd, log ) - cmd = "ext2online %s/vservers" % SYSIMG_PATH - resize = utils.sysexec_noerr(cmd,log) - utils.sysexec_noerr( "umount %s/vservers" % SYSIMG_PATH, log ) - utils.sysexec_noerr( "umount %s" % SYSIMG_PATH, log ) - vars['ROOT_MOUNTED']= 0 + + vars['ROOT_MOUNTED']= 1 + cmd = "mount %s %s" % (PARTITIONS["root"],SYSIMG_PATH) + utils.sysexec_noerr( cmd, log ) + cmd = "mount %s %s/vservers" % \ + (PARTITIONS["vservers"],SYSIMG_PATH) + utils.sysexec_noerr( cmd, log ) + cmd = "ext2online %s/vservers" % SYSIMG_PATH + resize = utils.sysexec_noerr(cmd,log) + utils.sysexec_noerr( "umount %s/vservers" % SYSIMG_PATH, log ) + utils.sysexec_noerr( "umount %s" % SYSIMG_PATH, log ) + vars['ROOT_MOUNTED']= 0 utils.sysexec( "vgchange -an", log ) diff --git a/source/steps/CheckHardwareRequirements.py b/source/steps/CheckHardwareRequirements.py index d3c9a88..0c3e582 100644 --- a/source/steps/CheckHardwareRequirements.py +++ b/source/steps/CheckHardwareRequirements.py @@ -40,7 +40,6 @@ def Run( vars, log ): this node to be usable after install SKIP_HARDWARE_REQUIREMENT_CHECK If set, don't check if minimum requirements are met - BOOT_CD_VERSION A tuple of the current bootcd version Sets the following variables: INSTALL_BLOCK_DEVICES list of block devices to install onto """ @@ -64,10 +63,6 @@ def Run( vars, log ): SKIP_HARDWARE_REQUIREMENT_CHECK= \ int(vars["SKIP_HARDWARE_REQUIREMENT_CHECK"]) - BOOT_CD_VERSION= vars["BOOT_CD_VERSION"] - if BOOT_CD_VERSION == "": - raise ValueError, "BOOT_CD_VERSION" - except KeyError, var: raise BootManagerException, \ "Missing variable in install store: %s" % var @@ -249,10 +244,4 @@ def Run( vars, log ): log.write( "Total size for all usable block devices: %4.2f GB\n" % total_size ) - # turn off UDMA for all block devices on 2.x cds (2.4 kernel) - if BOOT_CD_VERSION[0] == 2: - for device in install_devices: - log.write( "Disabling UDMA on %s\n" % device ) - utils.sysexec_noerr( "/sbin/hdparm -d0 %s" % device, log ) - return 1 diff --git a/source/steps/GetAndUpdateNodeDetails.py b/source/steps/GetAndUpdateNodeDetails.py index 68aae8f..594683a 100644 --- a/source/steps/GetAndUpdateNodeDetails.py +++ b/source/steps/GetAndUpdateNodeDetails.py @@ -23,7 +23,6 @@ def Run( vars, log ): broadcast, netmask, dns1/2, and the hostname/domainname. Expect the following keys to be set: - BOOT_CD_VERSION A tuple of the current bootcd version SKIP_HARDWARE_REQUIREMENT_CHECK Whether or not we should skip hardware requirement checks @@ -48,10 +47,6 @@ def Run( vars, log ): # 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" - SKIP_HARDWARE_REQUIREMENT_CHECK= vars["SKIP_HARDWARE_REQUIREMENT_CHECK"] if SKIP_HARDWARE_REQUIREMENT_CHECK == "": raise ValueError, "SKIP_HARDWARE_REQUIREMENT_CHECK" diff --git a/source/steps/InitializeBootManager.py b/source/steps/InitializeBootManager.py index c037a0e..58a51d2 100644 --- a/source/steps/InitializeBootManager.py +++ b/source/steps/InitializeBootManager.py @@ -68,24 +68,6 @@ def Run( vars, log ): BOOT_CD_VERSION= vars['BOOT_CD_VERSION'] - # old cds need extra modules loaded for compaq smart array - if BOOT_CD_VERSION[0] == 2: - - has_smartarray= utils.sysexec_noerr( - 'lspci | egrep "0e11:b178|0e11:4070|0e11:4080|0e11:4082|0e11:4083"') - - if has_smartarray: - log.write( "Loading support for Compaq smart array\n" ) - utils.sysexec_noerr( "modprobe cciss", log ) - _create_cciss_dev_entries() - - - has_fusion= utils.sysexec_noerr('lspci | egrep "1000:0030"') - - if has_fusion: - log.write( "Loading support for Fusion MPT SCSI controllers\n" ) - utils.sysexec_noerr( "modprobe mptscsih", log ) - # for anything that needs to know we are running under the boot cd and # not the runtime os os.environ['PL_BOOTCD']= "1" diff --git a/source/steps/InstallBootstrapFS.py b/source/steps/InstallBootstrapFS.py index b36e601..11db5b9 100644 --- a/source/steps/InstallBootstrapFS.py +++ b/source/steps/InstallBootstrapFS.py @@ -97,7 +97,7 @@ def Run( vars, log ): extensions = extension_tag.split() except: - log.write("WARNING : Failed to query the extension tag - installing only core software\n") + log.write("WARNING : Failed to query tag 'extensions' - installing only core software\n") extensions = [] # see also GetBootMedium in PLCAPI that does similar things diff --git a/source/steps/InstallPartitionDisks.py b/source/steps/InstallPartitionDisks.py index 014fcd7..77bc9d4 100644 --- a/source/steps/InstallPartitionDisks.py +++ b/source/steps/InstallPartitionDisks.py @@ -15,7 +15,6 @@ import popen2 from Exceptions import * import utils import BootServerRequest -import compatibility import ModelOptions @@ -28,7 +27,6 @@ def Run( vars, log ): TEMP_PATH somewhere to store what we need to run ROOT_SIZE the size of the root logical volume SWAP_SIZE the size of the swap partition - BOOT_CD_VERSION A tuple of the current bootcd version """ log.write( "\n\nStep: Install: partitioning disks.\n" ) @@ -51,10 +49,6 @@ def Run( vars, log ): if SWAP_SIZE == "" or SWAP_SIZE == 0: raise ValueError, "SWAP_SIZE invalid" - BOOT_CD_VERSION= vars["BOOT_CD_VERSION"] - if BOOT_CD_VERSION == "": - raise ValueError, "BOOT_CD_VERSION" - NODE_MODEL_OPTIONS= vars["NODE_MODEL_OPTIONS"] PARTITIONS= vars["PARTITIONS"] @@ -69,10 +63,6 @@ def Run( vars, log ): bs_request= BootServerRequest.BootServerRequest() - # old cds need extra utilities to partition disks and setup lvm - if BOOT_CD_VERSION[0] == 2: - compatibility.setup_partdisks_2x_cd( vars, log ) - # disable swap if its on utils.sysexec_noerr( "swapoff %s" % PARTITIONS["swap"], log ) @@ -171,10 +161,6 @@ def single_partition_device( device, vars, log ): return 1 if sucessful, 0 otherwise """ - BOOT_CD_VERSION= vars["BOOT_CD_VERSION"] - if BOOT_CD_VERSION[0] == 2: - compatibility.setup_partdisks_2x_cd( vars, log ) - import parted lvm_flag= parted.partition_flag_get_by_name('lvm') @@ -186,63 +172,27 @@ def single_partition_device( device, vars, log ): # get the device dev= parted.PedDevice.get(device) - # 2.x cds have different libparted that 3.x cds, and they have - # different interfaces - if BOOT_CD_VERSION[0] >= 3: - - # create a new partition table - disk= dev.disk_new_fresh(parted.disk_type_get("msdos")) - - # create one big partition on each block device - constraint= dev.constraint_any() - - new_part= disk.partition_new( - parted.PARTITION_PRIMARY, - parted.file_system_type_get("ext2"), - 0, 1 ) - - # make it an lvm partition - new_part.set_flag(lvm_flag,1) - - # actually add the partition to the disk - disk.add_partition(new_part, constraint) + # create a new partition table + disk= dev.disk_new_fresh(parted.disk_type_get("msdos")) - disk.maximize_partition(new_part,constraint) + # create one big partition on each block device + constraint= dev.constraint_any() - disk.commit() - del disk - else: - # create a new partition table - dev.disk_create(parted.disk_type_get("msdos")) - - # get the disk - disk= parted.PedDisk.open(dev) - - # create one big partition on each block device - part= disk.next_partition() - while part: - if part.type == parted.PARTITION_FREESPACE: - new_part= disk.partition_new( - parted.PARTITION_PRIMARY, - parted.file_system_type_get("ext2"), - part.geom.start, - part.geom.end ) - - constraint = disk.constraint_any() + new_part= disk.partition_new( + parted.PARTITION_PRIMARY, + parted.file_system_type_get("ext2"), + 0, 1 ) - # make it an lvm partition - new_part.set_flag(lvm_flag,1) + # make it an lvm partition + new_part.set_flag(lvm_flag,1) - # actually add the partition to the disk - disk.add_partition(new_part, constraint) + # actually add the partition to the disk + disk.add_partition(new_part, constraint) - break + disk.maximize_partition(new_part,constraint) - part= disk.next_partition(part) - - disk.write() - disk.close() - del disk + disk.commit() + del disk except BootManagerException, e: log.write( "BootManagerException while running: %s\n" % str(e) ) @@ -283,24 +233,12 @@ def get_partition_path_from_device( device, vars, log ): given a device, return the path of the first partition on the device """ - BOOT_CD_VERSION= vars["BOOT_CD_VERSION"] - # those who wrote the cciss driver just had to make it difficult - if BOOT_CD_VERSION[0] >= 3: - cciss_test= "/dev/cciss" - if device[:len(cciss_test)] == cciss_test: - part_path= device + "p1" - else: - part_path= device + "1" + cciss_test= "/dev/cciss" + if device[:len(cciss_test)] == cciss_test: + part_path= device + "p1" else: - # if device ends in /disc, we need to make it end in - # /part1 to indicate the first partition (for devfs based 2.x cds) - dev_parts= string.split(device,"/") - if dev_parts[-1] == "disc": - dev_parts[-1]= "part1" - part_path= string.join(dev_parts,"/") - else: - part_path= device + "1" + part_path= device + "1" return part_path diff --git a/source/steps/InstallWriteConfig.py b/source/steps/InstallWriteConfig.py index 88b89ab..c755d56 100644 --- a/source/steps/InstallWriteConfig.py +++ b/source/steps/InstallWriteConfig.py @@ -34,8 +34,6 @@ def Run( vars, log ): PLCONF_DIR The directory to store the configuration file in INTERFACE_SETTINGS A dictionary of the values from the network configuration file - BOOT_CD_VERSION A tuple of the current bootcd version - Sets the following variables: None @@ -65,10 +63,6 @@ def Run( vars, log ): if INTERFACE_SETTINGS == "": raise ValueError, "INTERFACE_SETTINGS" - BOOT_CD_VERSION= vars["BOOT_CD_VERSION"] - if BOOT_CD_VERSION == "": - raise ValueError, "BOOT_CD_VERSION" - except KeyError, var: raise BootManagerException, "Missing variable in vars: %s\n" % var except ValueError, var: diff --git a/source/steps/ReadNodeConfiguration.py b/source/steps/ReadNodeConfiguration.py index 5337aa5..370f5c5 100644 --- a/source/steps/ReadNodeConfiguration.py +++ b/source/steps/ReadNodeConfiguration.py @@ -50,7 +50,6 @@ def Run( vars, log ): and read, return 1. Expect the following variables from the store: - BOOT_CD_VERSION A tuple of the current bootcd version SUPPORT_FILE_DIR directory on the boot servers containing scripts and support files @@ -85,10 +84,6 @@ def Run( vars, log ): # 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" - SUPPORT_FILE_DIR= vars["SUPPORT_FILE_DIR"] if SUPPORT_FILE_DIR == None: raise ValueError, "SUPPORT_FILE_DIR" @@ -176,94 +171,91 @@ def Run( vars, log ): utils.sysexec_noerr( "umount %s" % mount_point, log ) + # 2. check flash devices on 3.0 based cds + log.write( "Checking flash devices for plnode.txt file.\n" ) + # this is done the same way the 3.0 cds do it, by attempting + # to mount and sd*1 devices that are removable + devices= os.listdir("/sys/block/") - if BOOT_CD_VERSION[0] >= 3: - # 2. check flash devices on 3.0 based cds - log.write( "Checking flash devices for plnode.txt file.\n" ) + for device in devices: + if device[:2] != "sd": + log.write( "Skipping non-scsi device %s\n" % device ) + continue - # this is done the same way the 3.0 cds do it, by attempting - # to mount and sd*1 devices that are removable - devices= os.listdir("/sys/block/") + # test removable + removable_file_path= "/sys/block/%s/removable" % device + try: + removable= int(file(removable_file_path,"r").read().strip()) + except ValueError, e: + continue + except IOError, e: + continue - for device in devices: - if device[:2] != "sd": - log.write( "Skipping non-scsi device %s\n" % device ) - continue + if not removable: + log.write( "Skipping non-removable device %s\n" % device ) + continue - # test removable - removable_file_path= "/sys/block/%s/removable" % device - try: - removable= int(file(removable_file_path,"r").read().strip()) - except ValueError, e: - continue - except IOError, e: - continue + log.write( "Checking removable device %s\n" % device ) - if not removable: - log.write( "Skipping non-removable device %s\n" % device ) + partitions= file("/proc/partitions", "r") + for line in partitions: + found_file= 0 + parsed_file= 0 + + if not re.search("%s[0-9]*$" % device, line): continue - log.write( "Checking removable device %s\n" % device ) + try: + # major minor #blocks name + parts= string.split(line) - partitions= file("/proc/partitions", "r") - for line in partitions: - found_file= 0 - parsed_file= 0 - - if not re.search("%s[0-9]*$" % device, line): - continue + # ok, try to mount it and see if we have a conf file. + full_device= "/dev/%s" % parts[3] + except IndexError, e: + log.write( "Incorrect /proc/partitions line:\n%s\n" % line ) + continue - try: - # major minor #blocks name - parts= string.split(line) + log.write( "Mounting %s on %s\n" % (full_device,mount_point) ) + try: + utils.sysexec( "mount -o ro -t ext2,msdos %s %s" \ + % (full_device,mount_point), log ) + except BootManagerException, e: + log.write( "Unable to mount, trying next partition\n" ) + continue - # ok, try to mount it and see if we have a conf file. - full_device= "/dev/%s" % parts[3] - except IndexError, e: - log.write( "Incorrect /proc/partitions line:\n%s\n" % line ) - continue + conf_file_path= "%s/%s" % (mount_point,NEW_CONF_FILE_NAME) - log.write( "Mounting %s on %s\n" % (full_device,mount_point) ) + log.write( "Checking for existence of %s\n" % conf_file_path ) + if os.access( conf_file_path, os.R_OK ): try: - utils.sysexec( "mount -o ro -t ext2,msdos %s %s" \ - % (full_device,mount_point), log ) - except BootManagerException, e: - log.write( "Unable to mount, trying next partition\n" ) - continue - - conf_file_path= "%s/%s" % (mount_point,NEW_CONF_FILE_NAME) - - log.write( "Checking for existence of %s\n" % conf_file_path ) - if os.access( conf_file_path, os.R_OK ): - try: - conf_file= file(conf_file_path,"r") - conf_file_contents= conf_file.read() - conf_file.close() - found_file= 1 - log.write( "Read in contents of file %s\n" % \ - conf_file_path ) - - if __parse_configuration_file( vars, log, \ - conf_file_contents): - parsed_file= 1 - except IOError, e: - log.write( "Unable to read file %s\n" % conf_file_path ) - - utils.sysexec_noerr( "umount %s" % mount_point, log ) - if found_file: - if parsed_file: - return 1 - else: - raise BootManagerException( \ - "Found configuration file plnode.txt " \ - "on floppy, but was unable to parse it.") + conf_file= file(conf_file_path,"r") + conf_file_contents= conf_file.read() + conf_file.close() + found_file= 1 + log.write( "Read in contents of file %s\n" % \ + conf_file_path ) + + if __parse_configuration_file( vars, log, \ + conf_file_contents): + parsed_file= 1 + except IOError, e: + log.write( "Unable to read file %s\n" % conf_file_path ) + + utils.sysexec_noerr( "umount %s" % mount_point, log ) + if found_file: + if parsed_file: + return 1 + else: + raise BootManagerException( \ + "Found configuration file plnode.txt " \ + "on floppy, but was unable to parse it.") # 3. check standard floppy disk for old file name planet.cnf log.write( "Checking standard floppy disk for planet.cnf file " \ - "(from earlier.\n" ) + "(for legacy nodes).\n" ) if old_conf_file_contents: if __parse_configuration_file( vars, log, old_conf_file_contents): @@ -356,7 +348,6 @@ def __parse_configuration_file( vars, log, file_contents ): of the configuration file is completed. """ - BOOT_CD_VERSION= vars["BOOT_CD_VERSION"] SUPPORT_FILE_DIR= vars["SUPPORT_FILE_DIR"] INTERFACE_SETTINGS= vars["INTERFACE_SETTINGS"] @@ -539,10 +530,7 @@ def __parse_configuration_file( vars, log, file_contents ): # but in binary form, so we need to convert it to ascii the same # way the old boot scripts did so it matches whats in the db # (php uses bin2hex, - if BOOT_CD_VERSION[0] == 2: - read_mode= "rb" - else: - read_mode= "r" + read_mode= "r" try: nonce_file= file("/tmp/nonce",read_mode) @@ -552,21 +540,7 @@ def __parse_configuration_file( vars, log, file_contents ): log.write( "Unable to read nonce from /tmp/nonce\n" ) return 0 - if BOOT_CD_VERSION[0] == 2: - nonce= nonce.encode('hex') - - # there is this nice bug in the php that currently accepts the - # nonce for the old scripts, in that if the nonce contains - # null chars (2.x cds sent as binary), then - # the nonce is truncated. so, do the same here, truncate the nonce - # at the first null ('00'). This could leave us with an empty string. - nonce_len= len(nonce) - for byte_index in range(0,nonce_len,2): - if nonce[byte_index:byte_index+2] == '00': - nonce= nonce[:byte_index] - break - else: - nonce= string.strip(nonce) + nonce= string.strip(nonce) log.write( "Read nonce, using as key.\n" ) vars['NODE_KEY']= nonce diff --git a/source/steps/StartDebug.py b/source/steps/StartDebug.py index 2f47509..62a94a1 100644 --- a/source/steps/StartDebug.py +++ b/source/steps/StartDebug.py @@ -10,10 +10,9 @@ import os from Exceptions import * import utils -import compatibility -message= \ +warning_message= \ """ --------------------------------------------------------- This machine has entered a temporary debug state, so @@ -27,8 +26,13 @@ Thank you. --------------------------------------------------------- """ +# this can be invoked +# either at the end of the bm logic, because something failed (last_resort = True) +# and/or it can be invoked as a fallback very early in the bootmanager logic, +# so we can reach the node regardless of what happens (e.g. bm sometimes hangs) + +def Run( vars, log, last_resort = True): -def Run( vars, log ): """ Bring up sshd inside the boot cd environment for debug purposes. @@ -37,11 +41,16 @@ def Run( vars, log ): Expect the following variables in vars to be set: BM_SOURCE_DIR The source dir for the boot manager sources that - we are currently running from - BOOT_CD_VERSION A tuple of the current bootcd version + we are currently running from """ - log.write( "\n\nStep: Starting debug mode.\n" ) + if last_resort: + message="Starting debug mode" + else: + message="Starting fallback sshd" + + + log.write( "\n\nStep: %s.\n"%message ) # make sure we have the variables we need try: @@ -49,86 +58,63 @@ def Run( vars, log ): if BM_SOURCE_DIR == "": raise ValueError, "BM_SOURCE_DIR" - BOOT_CD_VERSION= vars["BOOT_CD_VERSION"] - if BOOT_CD_VERSION == "": - raise ValueError, "BOOT_CD_VERSION" - 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 - - log.write( "Starting debug environment\n" ) - + # constants ssh_source_files= "%s/debug_files/" % BM_SOURCE_DIR ssh_dir= "/etc/ssh/" ssh_home= "/root/.ssh" cancel_boot_flag= "/tmp/CANCEL_BOOT" sshd_started_flag= "/tmp/SSHD_RUNNING" - sshd_started= 0 - try: - os.stat(sshd_started_flag) - sshd_started= 1 - except OSError, e: - pass - - if not sshd_started: - # NOTE: these commands hang if ssh_host_*_key files exist, b/c - # ssh-keygen asks for user input to confirm the overwrite. - # could fix this with "echo 'y' | " - log.write( "Creating ssh host keys\n" ) - - utils.makedirs( ssh_dir ) - utils.sysexec( "ssh-keygen -t rsa1 -b 1024 -f %s/ssh_host_key -N ''" % - ssh_dir, log ) - utils.sysexec( "ssh-keygen -t rsa -f %s/ssh_host_rsa_key -N ''" % - ssh_dir, log ) - utils.sysexec( "ssh-keygen -d -f %s/ssh_host_dsa_key -N ''" % - ssh_dir, log ) - - if BOOT_CD_VERSION[0] >= 3: - utils.sysexec( "cp -f %s/sshd_config_v3 %s/sshd_config" % - (ssh_source_files,ssh_dir), log ) - else: - utils.sysexec( "cp -f %s/sshd_config_v2 %s/sshd_config" % - (ssh_source_files,ssh_dir), log ) - else: - log.write( "ssh host keys already created\n" ) - + # create host keys if needed + if not os.path.isdir (ssh_dir): + utils.makedirs (ssh_dir) + key=ssh_dir+"/ssh_host_key" + if not os.path.isfile (key): + log.write("Creating host rsa1 key %s\n"%key) + utils.sysexec( "ssh-keygen -t rsa1 -b 1024 -f %s -N ''" % key, log ) + key=ssh_dir+"/ssh_host_rsa_key" + if not os.path.isfile (key): + log.write("Creating host rsa key %s\n"%key) + utils.sysexec( "ssh-keygen -t rsa -f %s -N ''" % key, log ) + key=ssh_dir+"/ssh_host_dsa_key" + if not os.path.isfile (key): + log.write("Creating host dsa key %s\n"%key) + utils.sysexec( "ssh-keygen -d -f %s -N ''" % key, log ) + + # (over)write sshd config + utils.sysexec( "cp -f %s/sshd_config %s/sshd_config" % (ssh_source_files,ssh_dir), log ) + + ### xxx ### xxx ### xxx ### xxx ### xxx - # always update the key, may have change in this instance of the bootmanager + # always update the key, may have changed in this instance of the bootmanager log.write( "Installing debug ssh key for root user\n" ) - - utils.makedirs( ssh_home ) - utils.sysexec( "cp -f %s/debug_root_ssh_key %s/authorized_keys" % - (ssh_source_files,ssh_home), log ) + if not os.path.isdir ( ssh_home): + utils.makedirs( ssh_home ) + utils.sysexec( "cp -f %s/debug_root_ssh_key %s/authorized_keys" % (ssh_source_files,ssh_home), log ) utils.sysexec( "chmod 700 %s" % ssh_home, log ) utils.sysexec( "chmod 600 %s/authorized_keys" % ssh_home, log ) - if not sshd_started: + # start sshd + if not os.path.isfile(sshd_started_flag): log.write( "Starting sshd\n" ) - - if BOOT_CD_VERSION[0] == 2: - utils.sysexec( "/usr/sbin/sshd", log ) - else: - utils.sysexec( "service sshd start", log ) - + utils.sysexec( "service sshd start", log ) # flag that ssh is running utils.sysexec( "touch %s" % sshd_started_flag, log ) else: - log.write( "sshd already running\n" ) + # it is expected that sshd is already running when last_resort==True + if not last_resort: + log.write( "sshd is already running\n" ) - - # this will make the initial script stop requesting scripts from PLC - utils.sysexec( "touch %s" % cancel_boot_flag, log ) - - # for ease of use, setup lvm on 2.x cds - if BOOT_CD_VERSION[0] == 2: - compatibility.setup_lvm_2x_cd(vars,log) + if last_resort: + # this will make the initial script stop requesting scripts from PLC + utils.sysexec( "touch %s" % cancel_boot_flag, log ) - print message + if last_resort: + print warning_message return - diff --git a/source/steps/ValidateNodeInstall.py b/source/steps/ValidateNodeInstall.py index e16e736..bda60b1 100644 --- a/source/steps/ValidateNodeInstall.py +++ b/source/steps/ValidateNodeInstall.py @@ -11,7 +11,6 @@ import os from Exceptions import * import utils import systeminfo -import compatibility import ModelOptions @@ -24,7 +23,6 @@ def Run( vars, log ): 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 @@ -37,10 +35,6 @@ def Run( vars, log ): # 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"] if SYSIMG_PATH == "": raise ValueError, "SYSIMG_PATH" @@ -66,16 +60,13 @@ def Run( vars, log ): ROOT_MOUNTED= 0 - if 'ROOT_MOUNTED' in vars.keys(): + 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 diff --git a/source/utils.py b/source/utils.py index fcab87d..407216b 100644 --- a/source/utils.py +++ b/source/utils.py @@ -17,6 +17,62 @@ import exceptions from Exceptions import * +### handling breakpoints in the startup process +import select, sys, string + +### global debug settings +# NOTE. when BREAKPOINT_MODE turns out enabled, +# you have to attend the boot phase, that would hang otherwise + +# enabling this will cause the node to ask for breakpoint-mode at startup +# production code should read False/False +PROMPT_MODE=False +# default for when prompt is turned off, or it's on but the timeout triggers +BREAKPOINT_MODE=False +VERBOSE_MODE=False +VERBOSE_MODE=True +# in seconds : if no input, proceed +PROMPT_TIMEOUT=5 + +def prompt_for_breakpoint_mode (): + + global BREAKPOINT_MODE + if PROMPT_MODE: + default_answer=BREAKPOINT_MODE + answer='' + if BREAKPOINT_MODE: + display="[y]/n" + else: + display="y/[n]" + sys.stdout.write ("Want to run in breakpoint mode ? %s "%display) + sys.stdout.flush() + r,w,e = select.select ([sys.stdin],[],[],PROMPT_TIMEOUT) + if r: + answer = string.strip(sys.stdin.readline()) + else: + sys.stdout.write("\nTimed-out (%d s)"%PROMPT_TIMEOUT) + if answer: + BREAKPOINT_MODE = ( answer == "y" or answer == "Y") + else: + BREAKPOINT_MODE = default_answer + label="Off" + if BREAKPOINT_MODE: + label="On" + sys.stdout.write("\nCurrent BREAKPOINT_MODE is %s\n"%label) + +def breakpoint (message, cmd = None): + + if BREAKPOINT_MODE: + + if cmd is None: + cmd="/bin/sh" + message=message+" -- Entering bash - type ^D to proceed" + + print message + os.system(cmd) + + +######################################## def makedirs( path ): """ from python docs for os.makedirs: @@ -70,7 +126,7 @@ def sysexec( cmd, log= None ): 0 if failed. A BootManagerException is raised if the command was unable to execute or was interrupted by the user with Ctrl+C """ - if BREAKPOINT_MODE: + if VERBOSE_MODE: print ("sysexec >>> %s" % cmd) prog= popen2.Popen4( cmd, 0 ) if prog is None: @@ -160,54 +216,3 @@ def get_mac_from_interface(ifname): return ret -### handling breakpoints in the startup process -import select, sys, string - -### global debug settings -# NOTE. when BREAKPOINT_MODE turns out enabled, -# you have to attend the boot phase, that would hang otherwise - -# enabling this will cause the node to ask for breakpoint-mode at startup -# production code should read False/False -PROMPT_MODE=False -# default for when prompt is turned off, or it's on but the timeout triggers -BREAKPOINT_MODE=False -# in seconds : if no input, proceed -PROMPT_TIMEOUT=5 - -def prompt_for_breakpoint_mode (): - - global BREAKPOINT_MODE - if PROMPT_MODE: - default_answer=BREAKPOINT_MODE - answer='' - if BREAKPOINT_MODE: - display="[y]/n" - else: - display="y/[n]" - sys.stdout.write ("Want to run in breakpoint mode ? %s "%display) - sys.stdout.flush() - r,w,e = select.select ([sys.stdin],[],[],PROMPT_TIMEOUT) - if r: - answer = string.strip(sys.stdin.readline()) - else: - sys.stdout.write("\nTimed-out (%d s)"%PROMPT_TIMEOUT) - if answer: - BREAKPOINT_MODE = ( answer == "y" or answer == "Y") - else: - BREAKPOINT_MODE = default_answer - label="Off" - if BREAKPOINT_MODE: - label="On" - sys.stdout.write("\nCurrent BREAKPOINT_MODE is %s\n"%label) - -def breakpoint (message, cmd = None): - - if BREAKPOINT_MODE: - - if cmd is None: - cmd="/bin/sh" - message=message+" -- Entering bash - type ^D to proceed" - - print message - os.system(cmd) -- 2.45.2