def init(applicationResourceFile, loggerName): if os.geteuid() != 0: print RED + 'You must be root to run this program.' + RESETCOLORS exit(1) usage = 'usage: %prog [[-a] [-k] [-o] [-p]] [-v] [-h]' parser = optparse.OptionParser(usage=usage) parser.add_option('-a', action='store_true', default=False, help='This option will result in the application of both OS and Kernel patches.') parser.add_option('-k', action='store_true', default=False, help='This option will result in the application of Kernel patches.') parser.add_option('-o', action='store_true', default=False, help='This option will result in the application of OS patches.') parser.add_option('-p', action='store_true', default=False, help='This option is used to perform the post update tasks.') parser.add_option('-v', action='store_true', default=False, help="This option is used to display the application's version.") options, args = parser.parse_args() applicationName = os.path.basename(sys.argv[0]) applicationVersion = 'v1.8-6' if options.v: print applicationName + ' ' + applicationVersion exit(0) if options.a and options.k or options.a and options.o or options.k and options.o or options.a and options.p or options.o and options.p or options.k and options.p: parser.error('Options -a, -k, -o and -p are mutually exclusive.') if not options.a and not options.k and not options.o and not options.p: parser.error("Try '" + applicationName + " -h' to get command specific help.") if options.p: print GREEN + 'Phase 1: Initializing for the post system update.' + RESETCOLORS else: print GREEN + 'Phase 1: Initializing for the system update.' + RESETCOLORS patchResourceDict = {} patchResourceDict['options'] = options try: with open(applicationResourceFile) as f: for line in f: line = line.strip() line = re.sub('[\'"]', '', line) if len(line) == 0 or re.match('^\\s*#', line) or re.match('^\\s+$', line): continue else: key, val = line.split('=') key = key.strip() patchResourceDict[key] = val.strip() except IOError as err: print RED + "Unable to access the application's resource file " + applicationResourceFile + '.\n' + str(err) + '\n' + RESETCOLORS exit(1) try: logBaseDir = re.sub('\\s+', '', patchResourceDict['logBaseDir']).rstrip('/') patchApplicationLog = re.sub('\\s+', '', patchResourceDict['patchApplicationLog']) patchApplicationLog = logBaseDir + '/' + patchApplicationLog except KeyError as err: print RED + 'The resource key (' + str(err) + ') was not present in the resource file; exiting program execution.' + '\n' + RESETCOLORS exit(1) if not options.p: try: logList = os.listdir(logBaseDir) for log in logList: os.remove(logBaseDir + '/' + log) except OSError as err: print RED + 'Unable to remove old logs in ' + logBaseDir + '; exiting program execution.\n' + str(err) + '\n' + RESETCOLORS exit(1) handler = logging.FileHandler(patchApplicationLog) logger = logging.getLogger(loggerName) logger.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(message)s', datefmt='%m/%d/%Y %H:%M:%S') handler.setFormatter(formatter) logger.addHandler(handler) if options.p: return patchResourceDict logger.info(applicationName + ' ' + applicationVersion) try: if len(patchResourceDict['rpmsToRemove']) != 0: patchResourceDict['removeRPMs'] = True else: patchResourceDict['removeRPMs'] = False if len(patchResourceDict['rpmsToAdd']) != 0: patchResourceDict['addRPMs'] = True else: patchResourceDict['addRPMs'] = False except KeyError as err: logger.error('The resource key (' + str(err) + ') was not present in the resource file.') print RED + 'A resource key was not present in the resource file, check the log file for errors; exiting program execution.' + '\n' + RESETCOLORS exit(1) #from modules.preUpdate import checkOSVersion, setPatchDirectories, removeFusionIOPackages, checkOSVersion, checkDiskSpace, updateBootloaderCFG # check the diskspace and OS Distribution level checkDiskSpace(loggerName) # Preupgrade 1 osDistLevel = checkOSVersion(patchResourceDict.copy(), loggerName) # Preupgrade 2 patchResourceDict['osDistLevel'] = osDistLevel command = 'dmidecode -s system-product-name' result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) out, err = result.communicate() logger.info('The output of the command (' + command + ") used to get the system's model was: " + out.strip()) if result.returncode != 0: logger.error("Unable to get the system's model information.\n" + err) print RED + "\nUnable to get the system's model information; check the log file for errors; exiting program execution.\n" + RESETCOLORS exit(1) systemModel = re.match('[a-z,0-9]+\\s+(.*)', out, re.IGNORECASE).group(1).replace(' ', '') logger.info("The system's model was determined to be: " + systemModel + '.') patchResourceDict['systemModel'] = systemModel #from modules.issues import updateSUSE_SLES_SAPRelease, sles12MultipathFix #Update the '/etc/dracut.conf.d/10-mp.conf' file by importing sles12MultipathFix if osDistLevel == 'SLES_SP1': sles12MultipathFix(loggerName) # issues 1 if options.a or options.k: if systemModel == 'DL580G7' or systemModel == 'DL980G7' or systemModel == 'DL380pGen8' or systemModel == 'DL360pGen8': patchResourceDict['postUpdateRequired'] = 'yes' try: logBaseDir = re.sub('\\s+', '', patchResourceDict['logBaseDir']).rstrip('/') postUpdateResumeLog = re.sub('\\s+', '', patchResourceDict['postUpdateResumeLog']) postUpdateResumeLog = logBaseDir + '/' + postUpdateResumeLog except KeyError as err: logger.error('The resource key (' + str(err) + ') was not present in the resource file.') print RED + 'The resource key for the post update resume log was not present in the resource file; check the log file for errors; exiting program execution.' + RESETCOLORS exit(1) try: f = open(postUpdateResumeLog, 'a') if systemModel == 'DL380pGen8' or systemModel == 'DL360pGen8': f.write('isServiceguardSystem = yes\n') else: f.write('isServiceguardSystem = no\n') if systemModel == 'DL580G7' or systemModel == 'DL980G7': f.write('isFusionIOSystem = yes\n') #from modules.preUpdate import checkOSVersion, setPatchDirectories, removeFusionIOPackages, checkOSVersion, checkDiskSpace, updateBootloaderCFG # remove the removeFusionIOPackages by importing from preUpdate removeFusionIOPackages(patchResourceDict.copy(), loggerName) # Preupgrade 3 else: f.write('isFusionIOSystem = no\n') f.close() except IOError as err: logger.error('Unable to access the post update resume log.\n' + str(err)) print RED + 'Unable to access the post update resume log; check the log file for errors; exiting program execution.' + RESETCOLORS exit(1) else: patchResourceDict['postUpdateRequired'] = 'no' else: patchResourceDict['postUpdateRequired'] = 'no' if (options.a or options.o) and patchResourceDict['suseSLESSAPReleaseRPM'] != '': command = 'rpm -q SUSE_SLES_SAP-release' result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) out, err = result.communicate() if result.returncode == 0: updateSUSE_SLES_SAPRelease(patchResourceDict.copy(), loggerName) # issues 2 elif 'package SUSE_SLES_SAP-release is not installed' not in out: logger.error('Unable to determine if the SUSE_SLES_SAP-release RPM is installed.\n' + out) print RED + 'Unable to determine if the SUSE_SLES_SAP-release RPM is installed; check the log file for errors; exiting program execution.' + RESETCOLORS exit(1) # from modules.preUpdate import setPatchDirectories patchDirList = setPatchDirectories(patchResourceDict.copy(), loggerName) # Preupgrade 4 #from modules.configureRepository import configureRepositories configureRepositories(patchDirList[:], loggerName) # configureRepository repositoryList = [] for dir in patchDirList: repositoryList.append(dir.split('/').pop()) patchResourceDict['repositoryList'] = repositoryList #from modules.updateZyppConf import updateZyppConf updateZyppConf(loggerName) # updateZyppConf
def init(applicationResourceFile): #The program can only be ran by root. if os.geteuid() != 0: print RED + "You must be root to run this program." + RESETCOLORS exit(1) usage = 'usage: %prog [[-a] [-k] [-o] [-p] -d] [-h]' parser = optparse.OptionParser(usage=usage) parser.add_option( '-a', action='store_true', default=False, help= 'This option will result in the application of both OS and Kernel patches.' ) parser.add_option( '-d', action='store_true', default=False, help= 'This option is used when problems are encountered and additional debug information is needed.' ) parser.add_option( '-k', action='store_true', default=False, help='This option will result in the application of Kernel patches.') parser.add_option( '-o', action='store_true', default=False, help='This option will result in the application of OS patches.') parser.add_option( '-p', action='store_true', default=False, help='This option is used to perform the post update tasks.') (options, args) = parser.parse_args() if (options.a and options.k) or (options.a and options.o) or ( options.k and options.o) or (options.a and options.p) or ( options.o and options.p) or (options.k and options.p): parser.error("Options -a, -k, -o and -p are mutually exclusive.") if not options.a and not options.k and not options.o and not options.p: parser.error( "At least one of the following options is required: -a, -k, -o or -p." ) if options.p: print GREEN + "Phase 1: Initializing for the post system update." + RESETCOLORS else: print GREEN + "Phase 1: Initializing for the system update." + RESETCOLORS patchResourceDict = {} #Save the options for later use. patchResourceDict['options'] = options #Get patch resource file data and save it to a dictionary (hash). try: with open(applicationResourceFile) as f: for line in f: line = line.strip() #Remove quotes from resources. line = re.sub('[\'"]', '', line) #Ignore commented and blank lines. if len(line) == 0 or re.match("^#", line): continue else: (key, val) = line.split('=') key = re.sub('\s+', '', key) patchResourceDict[key] = val.lstrip() except IOError as err: print RED + "Unable to access the application's resource file " + applicationResourceFile + ".\n" + str( err) + "\n" + RESETCOLORS exit(1) #Get the application's log file information. try: logBaseDir = (re.sub('\s+', '', patchResourceDict['logBaseDir'])).rstrip('/') patchApplicationLog = re.sub('\s+', '', patchResourceDict['patchApplicationLog']) patchApplicationLog = logBaseDir + '/' + patchApplicationLog except KeyError as err: print RED + "The resource key (" + str( err ) + ") was not present in the resource file; exiting program execution." + "\n" + RESETCOLORS exit(1) if not options.p: try: #Always start with an empty log directory when performing a new update. logList = os.listdir(logBaseDir) for log in logList: os.remove(logBaseDir + '/' + log) except Error as err: print RED + "Unable to remove old logs in " + logBaseDir + "; exiting program execution.\n" + str( err) + "\n" + RESETCOLORS exit(1) #Configure logging. handler = logging.FileHandler(patchApplicationLog) logger = logging.getLogger("patchLogger") if options.d: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(message)s', datefmt='%m/%d/%Y %H:%M:%S') handler.setFormatter(formatter) logger.addHandler(handler) if options.p: return patchResourceDict #Check available disk space. There needs to be at least 2G free. checkDiskSpace() #Check and get the OS distribution information. osDistLevel = checkOSVersion(patchResourceDict.copy()) patchResourceDict['osDistLevel'] = osDistLevel #Check if system has FusionIO cards for log and/or the system is a Serviceguard system. postUpdateRequired = '' if options.a or options.k: postUpdateRequired = checkSystemConfiguration(patchResourceDict) patchResourceDict['postUpdateRequired'] = postUpdateRequired ''' If OS patches are being installed then update SUSE_SLES_SAP-release first as it causes issues when trying to update with the rest of the patches. ''' if options.a or options.o: #Fist check to see if the SUSE_SLES_SAP-release RPM is installed. command = 'rpm -q SUSE_SLES_SAP-release' result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) out, err = result.communicate() if result.returncode == 0: updateSUSE_SLES_SAPRelease(patchResourceDict.copy()) else: if 'package SUSE_SLES_SAP-release is not installed' not in out: print RED + "Unable to determine if the SUSE_SLES_SAP-release RPM is installed; " + out + "; exiting program execution." + RESETCOLORS exit(1) #Check and get the patch directories. patchDirList = setPatchDirectories(patchResourceDict.copy()) #Configure the necessary patch repositories. configureRepositories(patchDirList[:]) #Need to extract and save the repository names, which will be used by zypper when updating the system. repositoryList = [] for dir in patchDirList: repositoryList.append(dir.split('/').pop()) patchResourceDict['repositoryList'] = repositoryList #Update zypp.conf so that the current kernel and the new kernel are both installed. updateZyppConf() return patchResourceDict