* 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
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)
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())
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
# 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
# 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 )
_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
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
_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:
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
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()) )
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)
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!" );
+++ /dev/null
-#!/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
-
-
-
+++ /dev/null
-# 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
import UpdateNodeConfiguration
from Exceptions import *
import utils
-import compatibility
import systeminfo
import BootAPI
import notify_messages
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
# 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"
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
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 )
import InstallPartitionDisks
from Exceptions import *
import systeminfo
-import compatibility
import utils
import os
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:
# 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"
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= []
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 )
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
"""
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
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
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
# 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"
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"
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
from Exceptions import *
import utils
import BootServerRequest
-import compatibility
import ModelOptions
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" )
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"]
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 )
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')
# 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) )
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
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
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:
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
# 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"
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):
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"]
# 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)
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
from Exceptions import *
import utils
-import compatibility
-message= \
+warning_message= \
"""
---------------------------------------------------------
This machine has entered a temporary debug state, so
---------------------------------------------------------
"""
+# 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.
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:
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
-
from Exceptions import *
import utils
import systeminfo
-import compatibility
import ModelOptions
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
# 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"
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
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:
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:
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)