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 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>
 
 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
 URL: http://cvs.planet-lab.org/cvs/bootmanager
 
 Summary: The PlanetLab Boot Manager
-Name: bootmanager
+Name: %{name}
 Version: %{version}
 Release: %{release}
 License: BSD
 Version: %{version}
 Release: %{release}
 License: BSD
index 18aca8c..5323103 100755 (executable)
@@ -294,6 +294,12 @@ class BootManager:
             
             
 def main(argv):
             
             
 def main(argv):
+
+    import utils
+    utils.prompt_for_breakpoint_mode()
+
+    utils.breakpoint ("Entering BootManager::main")
+    
     global NodeRunStates
     NodeRunStates = {'new':None,
                      'inst':None,
     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 )
 
     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 )
         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 
 
         # kargs, which is ramdisk_size=8192
         pass 
 
+    utils.breakpoint ("Before kexec");
     try:
         utils.sysexec( 'kexec --force --initrd=/tmp/initrd ' \
                        '--append="%s" /tmp/kernel' % kargs)
     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)
             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 )
                 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
 
         # 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"))
 
             # 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
     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"
         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
 
         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" % \
     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()
 
     # 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" )
 
     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:
     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.
 
     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" )
 
         # 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 )
 
         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:
             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
     """
     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, \
     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:
               "for command: %s" % cmd
 
     if log is not None:
@@ -158,3 +160,46 @@ def get_mac_from_interface(ifname):
         
     return ret
 
         
     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)