Setting tag NodeUpdate-0.5-6
[nodeupdate.git] / NodeUpdate.py
index 28e635a..d8e110a 100644 (file)
@@ -3,6 +3,10 @@
 import sys, os
 from random import Random
 import string
+from types import StringTypes
+
+from time import strftime
+TIMEFORMAT="%Y-%m-%d %H:%M:%S"
 
 NODEUPDATE_PID_FILE= "/var/run/NodeUpdate.pid"
 
@@ -31,25 +35,31 @@ REBOOT_FLAG = '/etc/planetlab/update-reboot'
 # location of directory containing boot server ssl certs
 SSL_CERT_DIR='/mnt/cdrom/bootme/cacert/'
 
-# file containing list of extra groups to attempt to update,
-# if necessary.
-EXTRA_GROUPS_FILE= '/etc/planetlab/extra-node-groups'
+# file containing the list of extensions this node has, each
+# correspond to a package group in yum repository.
+# this is expected to be updated from the 'extensions tag' 
+# through the 'extensions.php' nodeconfig script
+EXTENSIONS_FILE='/etc/planetlab/extensions'
 
 # file containing a list of rpms that we should attempt to delete
-# before we updating everything else. this list is not
-# removed with 'yum remove', because that could accidently remove
-# dependency rpms that were not intended to be deleted.
+# before updating everything else. This list is not removed with 
+# 'yum remove', because that could accidently remove dependency rpms
+# that were not intended to be deleted.
 DELETE_RPM_LIST_FILE= '/etc/planetlab/delete-rpm-list'
 
 
 # print out a message only if we are displaying output
-def Message(Str):
+def Message(message):
     if displayOutput:
-        print Str
-
+        if isinstance(message,StringTypes) and len(message) >=2 and message[0]=="\n":
+            print "\n",
+            message=message[1:]
+        print strftime(TIMEFORMAT),
+        print message
 
-# print out a message only if we are displaying output
+# always print errors
 def Error(Str):
+    print strftime(TIMEFORMAT),
     print Str
 
 
@@ -60,14 +70,15 @@ def UpdateCronFile():
     try:
         
         randomMinute= Random().randrange( 0, 59, 1 );
-        randomHour= Random().randrange( 0, 23, 1 );
+        randomHour= Random().randrange( 0, 11, 1 );
         
         f = open( CRON_FILE, 'w' );
         f.write( "# %s\n" % (TARGET_DESC) );
+        ### xxx is root aliased to the support mailing list ?
         f.write( "MAILTO=%s\n" % (TARGET_USER) );
         f.write( "SHELL=%s\n" % (TARGET_SHELL) );
-        f.write( "%s %s * * * %s %s\n\n" %
-                 (randomMinute, randomHour, TARGET_USER, TARGET_SCRIPT) );
+        f.write( "%s %s,%s * * * %s %s\n\n" %
+                 (randomMinute, randomHour, randomHour + 12, TARGET_USER, TARGET_SCRIPT) );
         f.close()
     
         print( "Created new cron.d entry." )
@@ -97,7 +108,7 @@ class NodeUpdate:
     
 
     def CheckProxy( self ):
-        Message( "Checking existance of proxy config file..." )
+        Message( "Checking existence of proxy config file..." )
         
         if os.access(PROXY_FILE, os.R_OK) and os.path.isfile(PROXY_FILE):
             self.HTTP_PROXY= string.strip(file(PROXY_FILE,'r').readline())
@@ -130,34 +141,44 @@ class NodeUpdate:
 
         Message( "\nChecking if yum supports SSL certificate checks" )
         if os.system( "%s --help | grep -q sslcertdir" % YUM_PATH ) == 0:
-            Message( "Yes, using --sslcertdir option" )
+            Message( "It does, using --sslcertdir option" )
             sslcertdir = "--sslcertdir=" + SSL_CERT_DIR
         else:
-            Message( "No, not using --sslcertdir option" )
+            Message( "Unsupported, not using --sslcertdir option" )
             sslcertdir = ""
                     
+        yum_options=""
+        Message( "\nChecking if yum supports --verbose" )
+        if os.system( "%s --help | grep -q verbose" % YUM_PATH ) == 0:
+            Message( "It does, using --verbose option" )
+            yum_options += " --verbose"
+        else:
+            Message( "Unsupported, not using --verbose option" )
+                    
         Message( "\nUpdating PlanetLab group" )
-        os.system( "%s %s -y groupupdate \"PlanetLab\"" %
-                   (YUM_PATH, sslcertdir) )
+        os.system( "%s %s %s -y groupupdate \"PlanetLab\"" %
+                   (YUM_PATH, yum_options, sslcertdir) )
 
         Message( "\nUpdating rest of system" )
-        os.system( "%s %s -y update" %
-                   (YUM_PATH, sslcertdir) )
-
-        Message( "\nChecking for extra groups to update" )
-        if os.access(EXTRA_GROUPS_FILE, os.R_OK) and \
-           os.path.isfile(EXTRA_GROUPS_FILE):
-            extra_groups_contents= file(EXTRA_GROUPS_FILE).read()
-            extra_groups_contents= string.strip(extra_groups_contents)
-            if extra_groups_contents == "":
+        os.system( "%s %s %s -y update" %
+                   (YUM_PATH, yum_options, sslcertdir) )
+
+        Message( "\nChecking for extra groups (extensions) to update" )
+        if os.access(EXTENSIONS_FILE, os.R_OK) and \
+           os.path.isfile(EXTENSIONS_FILE):
+            extensions_contents= file(EXTENSIONS_FILE).read()
+            extensions_contents= string.strip(extensions_contents)
+            if extensions_contents == "":
                 Message( "No extra groups found in file." )
             else:
-                for group in string.split(extra_groups_contents,"\n"):
+                extensions_contents.strip()
+                for extension in extensions_contents.split():
+                    group = "extension%s" % extension
                     Message( "\nUpdating %s group" % group )
-                    os.system( "%s %s -y groupupdate \"%s\"" %
-                               (YUM_PATH, sslcertdir, group) )
+                    os.system( "%s %s %s -y groupupdate \"%s\"" %
+                               (YUM_PATH, yum_options, sslcertdir, group) )
         else:
-            Message( "No extra groups file found" )
+            Message( "No extensions file found" )
             
         if os.access(REBOOT_FLAG, os.R_OK) and os.path.isfile(REBOOT_FLAG) and self.doReboot:
             Message( "\nAt least one update requested the system be rebooted" )
@@ -171,6 +192,13 @@ class NodeUpdate:
         try: os.system( "%s --rebuilddb" % RPM_PATH )
         except Exception, err: print "RebuildRPMdb: %s" % err
 
+    def YumCleanAll ( self ):
+        Message ("\nCleaning all yum cache (yum clean all)")
+        try:
+            os.system( "yum clean all")
+        except:
+            pass
+
     def RemoveRPMS( self ):
 
         Message( "\nLooking for RPMs to be deleted." )
@@ -202,9 +230,10 @@ class NodeUpdate:
 
 if __name__ == "__main__":
 
-    # if we are invoked with 'start', display the output. this
-    # is usefull for running something under cron and as a service
-    # (at startup), so the cron only outputs errors and doesn't
+    # if we are invoked with 'start', display the output. 
+    # this is useful for running something silently 
+    # under cron and as a service (at startup), 
+    # so the cron only outputs errors and doesn't
     # generate mail when it works correctly
 
     displayOutput= 0
@@ -215,8 +244,9 @@ if __name__ == "__main__":
     
     doReboot= 1
 
-    if "start" in sys.argv:
+    if "start" in sys.argv or "display" in sys.argv:
         displayOutput= 1
+        Message ("\nTurning on messages")
 
     if "noreboot" in sys.argv:
         doReboot= 0
@@ -256,6 +286,7 @@ if __name__ == "__main__":
         nodeupdate.RebuildRPMdb()
         nodeupdate.RemoveRPMS()
         nodeupdate.InstallKeys()
+        nodeupdate.YumCleanAll()
         nodeupdate.CheckForUpdates()
         Message( "\nUpdate complete." )