A few goodies from onelab's bootmanager
authorThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Thu, 22 Nov 2007 19:30:16 +0000 (19:30 +0000)
committerThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Thu, 22 Nov 2007 19:30:16 +0000 (19:30 +0000)
(*) breakpoint utilities - for when things get bad - disabled of course
(*) spec file changed to support auto-tagging
(*) Makefile : use make sync to install your working dir on a test plc
(*) also I had numbered this a version 4 CD, so had to make changes that seem to make sense anyway

Makefile [new file with mode: 0644]
bootmanager.spec
source/BootManager.py
source/steps/ChainBootNode.py
source/steps/CheckForNewDisks.py
source/steps/InstallPartitionDisks.py
source/steps/InstallWriteConfig.py
source/steps/ReadNodeConfiguration.py
source/steps/StartDebug.py
source/utils.py

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..9b10e44
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,26 @@
+# 
+# $Id: Makefile 682 2007-07-19 09:00:25Z thierry $
+#
+
+########## make sync PLCHOST=hostname
+ifdef PLCHOST
+PLCSSH:=root@$(PLCHOST)
+endif
+
+LOCAL_RSYNC_EXCLUDES   := --exclude '*.pyc' 
+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)
+
+sync:
+ifeq (,$(PLCSSH))
+       echo "sync: You must define target host as PLCHOST on the command line"
+       echo " e.g. make sync PLCHOST=private.one-lab.org" ; exit 1
+else
+       +$(RSYNC) source $(PLCSSH):/plc/root/usr/share/bootmanager/
+       ssh $(PLCSSH) chroot /plc/root service plc start bootmanager
+endif
+
+##########
+tags:
+       find . '(' -name '*.py' -o -name '*.spec' ')' | xargs etags
index 7bd04b1..07c7de5 100644 (file)
@@ -1,6 +1,11 @@
+#
+# $Id: bootmanager.spec 856 2007-09-21 13:54:58Z thierry $
+#
 %define name bootmanager
-%define version 3.1.16
-%define release 1%{?pldistro:.%{pldistro}}%{?date:.%{date}}
+%define version 3.1
+%define subversion 16
+
+%define release %{subversion}%{?pldistro:.%{pldistro}}%{?date:.%{date}}
 
 Vendor: PlanetLab
 Packager: PlanetLab Central <support@planet-lab.org>
@@ -8,7 +13,7 @@ Distribution: PlanetLab 4.1
 URL: http://cvs.planet-lab.org/cvs/bootmanager
 
 Summary: The PlanetLab Boot Manager
-Name: bootmanager
+Name: %{name}
 Version: %{version}
 Release: %{release}
 License: BSD
index 18aca8c..5323103 100755 (executable)
@@ -294,6 +294,12 @@ class BootManager:
             
             
 def main(argv):
+
+    import utils
+    utils.prompt_for_breakpoint_mode()
+
+    utils.breakpoint ("Entering BootManager::main")
+    
     global NodeRunStates
     NodeRunStates = {'new':None,
                      'inst':None,
index cccd37f..ff9a8bc 100644 (file)
@@ -192,7 +192,7 @@ def Run( vars, log ):
 
     if BOOT_CD_VERSION[0] == 2:
         utils.sysexec_noerr( "killall dhcpcd", log )
-    elif BOOT_CD_VERSION[0] == 3:
+    elif BOOT_CD_VERSION[0] >= 3:
         utils.sysexec_noerr( "killall dhclient", log )
         
     utils.sysexec_noerr( "umount -a -r -t ext2,ext3", log )
@@ -270,6 +270,7 @@ def Run( vars, log ):
         # kargs, which is ramdisk_size=8192
         pass 
 
+    utils.breakpoint ("Before kexec");
     try:
         utils.sysexec( 'kexec --force --initrd=/tmp/initrd ' \
                        '--append="%s" /tmp/kernel' % kargs)
index 45ddb69..e90e459 100644 (file)
@@ -175,7 +175,7 @@ def Run( vars, log ):
             if BOOT_CD_VERSION[0] == 2:
                 cmd = "resize2fs %s" % PARTITIONS["vservers"]
                 resize = utils.sysexec_noerr(cmd,log)
-            elif BOOT_CD_VERSION[0] == 3:
+            elif BOOT_CD_VERSION[0] >= 3:
                 vars['ROOT_MOUNTED']= 1
                 cmd = "mount %s %s" % (PARTITIONS["root"],SYSIMG_PATH)
                 utils.sysexec_noerr( cmd, log )
index 42ce5e5..e49f0f9 100644 (file)
@@ -188,7 +188,7 @@ def single_partition_device( device, vars, log ):
 
         # 2.x cds have different libparted that 3.x cds, and they have
         # different interfaces
-        if BOOT_CD_VERSION[0] == 3:
+        if BOOT_CD_VERSION[0] >= 3:
 
             # create a new partition table
             disk= dev.disk_new_fresh(parted.disk_type_get("msdos"))
@@ -286,7 +286,7 @@ def get_partition_path_from_device( device, vars, log ):
     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:
+    if BOOT_CD_VERSION[0] >= 3:
         cciss_test= "/dev/cciss"
         if device[:len(cciss_test)] == cciss_test:
             part_path= device + "p1"
index ee5a0cc..2d19d47 100644 (file)
@@ -86,6 +86,7 @@ def Run( vars, log ):
         log.write( "Unable to create directory\n" )
         return 0
 
+    utils.breakpoint("Before fstab");
     log.write( "Writing system /etc/fstab\n" )
     fstab= file( "%s/etc/fstab" % SYSIMG_PATH, "w" )
     fstab.write( "%s           none        swap      sw        0 0\n" % \
@@ -101,6 +102,7 @@ def Run( vars, log ):
     # fstab.write( "none         /rcfs       rcfs      defaults  0 0\n" )
     fstab.close()
 
+    utils.breakpoint("after fstab");
 
     log.write( "Writing system /etc/issue\n" )
     issue= file( "%s/etc/issue" % SYSIMG_PATH, "w" )
index d19439e..295a365 100644 (file)
@@ -61,17 +61,17 @@ def Run( vars, log ):
     NODE_KEY                    The key for this node
     NETWORK_SETTINGS            A dictionary of the values from the network
                                 configuration file. keys set:
-                                   method
-                                   ip        
-                                   mac       
-                                   gateway   
-                                   network   
-                                   broadcast 
-                                   netmask   
-                                   dns1      
-                                   dns2      
-                                   hostname  
-                                   domainname
+                                   method               IP_METHOD
+                                   ip                   IP_ADDRESS
+                                   mac                  NET_DEVICE       
+                                   gateway              IP_GATEWAY
+                                   network              IP_NETADDR
+                                   broadcast            IP_BROADCASTADDR
+                                   netmask              IP_NETMASK
+                                   dns1                 IP_DNS1
+                                   dns2                 IP_DNS2
+                                   hostname             HOST_NAME
+                                   domainname           DOMAIN_NAME
 
     the mac address is read from the machine unless it exists in the
     configuration file.
@@ -175,7 +175,7 @@ def Run( vars, log ):
 
 
 
-    if BOOT_CD_VERSION[0] == 3:
+    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" )
 
index 6220704..286e5fc 100644 (file)
@@ -85,7 +85,7 @@ def Run( vars, log ):
         utils.sysexec( "ssh-keygen -d -f %s/ssh_host_dsa_key -N ''" %
                        ssh_dir, log )
 
-        if BOOT_CD_VERSION[0] == 3:
+        if BOOT_CD_VERSION[0] >= 3:
             utils.sysexec( "cp -f %s/sshd_config_v3 %s/sshd_config" %
                            (ssh_source_files,ssh_dir), log )
         else:
index 9efea4d..d115f7e 100644 (file)
@@ -70,10 +70,12 @@ 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:
+        print ("sysexec >>> %s" % cmd)
     prog= popen2.Popen4( cmd, 0 )
     if prog is None:
         raise BootManagerException, \
-              "Unable to create instance of popen2.Popen3 " \
+              "Unable to create instance of popen2.Popen4 " \
               "for command: %s" % cmd
 
     if log is not None:
@@ -158,3 +160,46 @@ 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
+# if promt mode enabled, this default is taken
+BREAKPOINT_MODE=False
+# in seconds : if no input, proceed
+PROMPT_TIMEOUT=5
+
+def prompt_for_breakpoint_mode ():
+
+    global BREAKPOINT_MODE
+    if PROMPT_MODE:
+        answer = "n"
+        sys.stdout.write ("Want to run in breakpoint mode ? y/[n] ")
+        sys.stdout.flush()
+        r,w,e = select.select ([sys.stdin],[],[],PROMPT_TIMEOUT)
+        if r:
+            answer = string.strip(sys.stdin.readline())
+        else:
+            sys.stdout.write("Timed-out is %ds\n"%PROMPT_TIMEOUT)
+        BREAKPOINT_MODE = ( answer == "y" or answer == "Y")
+    label="Off"
+    if BREAKPOINT_MODE:
+        label="On"
+    sys.stdout.write("Current 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)