예제 #1
0
def buildDeadmanDriver():
	
	sgDriverDir = '/opt/cmcluster/drivers'
	logger = logging.getLogger("patchLogger")

	logger.info("Rebuilding and installing the deadman driver for the new kernel.")

	#Save the current working directory, so that we can return to it after building the driver.
	cwd = os.getcwd()

	try:
		os.chdir(sgDriverDir)
	except OSError as err:
                        logger.error("Could not change into the deadman drivers directory (" + sgDriverDir + ").\n" + str(err))
                        print RED + "Could not change into the deadman drivers directory; check the log file for errors; the deadman driver will have to be manually built/installed." + RESETCOLORS
			return 'Failure'

	driverBuildCommandsList = ['make modules', 'make modules_install', 'depmod -a']

	timeFeedbackThread = TimeFeedbackThread("Rebuilding and installing the deadman driver")
	timeFeedbackThread.start()

	for command in driverBuildCommandsList:
		buildCommand = command
		result = subprocess.Popen(buildCommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
		out, err = result.communicate()

		logger.debug("The output of the command (" + command + ") used in building and installing the deadman driver was: " + out.strip())

		if result.returncode != 0:
			timeFeedbackThread.stopTimer()
                        timeFeedbackThread.join()
                        logger.error("Failed to build and install the deadman driver.\n" + err)
                        print RED + "Failed to build and install the deadman driver; check the log file for errors; the deadman driver will have to be manually built/installed." + RESETCOLORS
			return 'Failure'

	timeFeedbackThread.stopTimer()
	timeFeedbackThread.join()

	try:
		os.chdir(cwd)
	except:
		pass

	logger.info("Done rebuilding and installing the deadman driver for the new kernel.")

	return 'Success'
예제 #2
0
class ApplyPatches:
    """
    Use the constructor to create a threading event that will be used to stop and restart the timer thread          
    when a signal (SIGINT, SIGQUIT) is captured.  Additionally, create the timer thread without a message, 
    since it will be set later depending on the type of patches being applied.
    self.exitStatus is used to inform the caller as to whether or not the program needs to exit, which would be
    the case if self.exitStatus is not 0.
    """

    def __init__(self):
        self.timerController = threading.Event()
        self.timeFeedbackThread = ''
        self.pid = ''
        self.exitStatus = 0
        self.cancelled = 'no'

    def applyPatches(self, repositoryList, loggerName):
        logger = logging.getLogger(loggerName)
        if len(repositoryList) > 1:
            logger.info('Applying patches from repositories ' + ', '.join(repositoryList) + '.')
        else:
            logger.info('Applying patches from repository ' + repositoryList[0] + '.')
        logger.info('The patch repository list was determined to be: ' + str(repositoryList))
        for repository in repositoryList:
            time.sleep(2)
            if 'kernel' in repository.lower():
                self.timeFeedbackThread = TimeFeedbackThread(componentMessage='Installing the new kernel', event=self.timerController)
                self.timeFeedbackThread.start()
                command = 'zypper -n --non-interactive-include-reboot-patches --no-refresh in -r ' + repository + ' ' + repository + ':*'
            elif 'additional' not in repository.lower():
                self.timeFeedbackThread = TimeFeedbackThread(componentMessage='Applying the OS patches', event=self.timerController)
                self.timeFeedbackThread.start()
                command = 'zypper -n --non-interactive-include-reboot-patches --no-refresh up -r ' + repository + ' ' + repository + ':*'
            result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=self.preexec, shell=True)
            self.pid = result.pid
            out, err = result.communicate()
            logger.info('The output of the patch update command (' + command + ') was: ' + out.strip())
            if result.returncode == 0:
                logger.info('Successfully updated the system using patches from the repository ' + repository + '.')
            else:
                self.timeFeedbackThread.stopTimer()
                self.timeFeedbackThread.join()
                print ''
                if self.cancelled == 'yes':
                    logger.info('The patch update was cancelled by the user.')
                    print RED + 'The patch update was cancelled; exiting program execution.' + RESETCOLORS
                else:
                    logger.error('Problems were encountered while updating the system using patches from the repository ' + repository + '.\n' + err)
                    print RED + 'Problems were encountered while applying the patches to the system; check the log file for errors; exiting program execution.' + RESETCOLORS
                self.exitStatus = 1
                return
            self.timeFeedbackThread.stopTimer()
            self.timeFeedbackThread.join()
            print ''

        if len(repositoryList) > 1:
            logger.info('Done applying patches from repositories ' + ', '.join(repositoryList) + '.')
        else:
            logger.info('Done applying patches from repository ' + repositoryList[0] + '.')

    def endTask(self):
        try:
            self.cancelled = 'yes'
            pgid = os.getpgid(self.pid)
            os.killpg(pgid, signal.SIGKILL)
        except OSError:
            pass

    def preexec(self):
        os.setpgrp()

    def getExitStatus(self):
        return self.exitStatus

    def pauseTimerThread(self):
        self.timeFeedbackThread.pauseTimer()

    def resumeTimerThread(self):
        self.timeFeedbackThread.resumeTimer()
예제 #3
0
class BuildDeadmanDriver:

        '''
        Use the constructor to create a threading event that will be used to stop and restart the timer thread
        when a signal (SIGINT, SIGQUIT) is captured.
        '''
        def __init__(self):

                self.timerController = threading.Event()
                self.timeFeedbackThread = TimeFeedbackThread(componentMessage = "Rebuilding and installing the deadman driver", event = self.timerController)
                self.pid = ''
                self.cancelled = 'no'
		self.completionStatus = ''
        #End __init__(self):

	'''
	This function is used to configure the deadman driver on Serviceguard systems.
	'''
	def buildDeadmanDriver(self, loggerName):
		
		sgDriverDir = '/opt/cmcluster/drivers'
		logger = logging.getLogger(loggerName)

		logger.info("Rebuilding and installing the deadman driver for the new kernel.")

		#Save the current working directory, so that we can return to it after building the driver.
		cwd = os.getcwd()

		try:
			os.chdir(sgDriverDir)
		except OSError as err:
				logger.error("Could not change into the deadman drivers directory (" + sgDriverDir + ").\n" + str(err))
				print RED + "Could not change into the deadman drivers directory; check the log file for errors; the deadman driver will have to be manually built/installed." + RESETCOLORS
				self.completionStatus = 'Failure'
				return

		driverBuildCommandsList = ['make modules', 'make modules_install', 'depmod -a']

		self.timeFeedbackThread.start()

		for command in driverBuildCommandsList:
			buildCommand = command
			result = subprocess.Popen(buildCommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=self.preexec, shell=True)

			#We get the processes PID in case the process is cancelled and we need to kill the process.
                        self.pid = result.pid

			out, err = result.communicate()

			logger.debug("The output of the command (" + command + ") used in building and installing the deadman driver was: " + out.strip())

			if result.returncode != 0:
				self.timeFeedbackThread.stopTimer()
				self.timeFeedbackThread.join()

                                #Move the cursor to the next line once the timer is stopped.
                                print ''

				if self.cancelled == 'yes':
                                        logger.info("The deadman driver build and install was cancelled by the user.")
                                        print RED + "The deadman driver build and install was cancelled; the deadman driver will have to be manually built/installed." + RESETCOLORS
				else:
					logger.error("Failed to build and install the deadman driver.\n" + err)
					print RED + "Failed to build and install the deadman driver; check the log file for errors; the deadman driver will have to be manually built/installed." + RESETCOLORS

				self.completionStatus = 'Failure'
				return

		self.timeFeedbackThread.stopTimer()
		self.timeFeedbackThread.join()

		#Move the cursor to the next line once the timer is stopped.
		print ''

		try:
			os.chdir(cwd)
		except:
			pass

		logger.info("Done rebuilding and installing the deadman driver for the new kernel.")

		self.completionStatus = 'Success'

	#End buildDeadmanDriver(loggerName):


        #This function will attempt to kill the running processes as requested by the user.
        def endTask(self):

                try:
                        self.cancelled = 'yes'
                        pgid = os.getpgid(self.pid)
                        os.killpg(pgid, signal.SIGKILL)
                except OSError:
                        pass

        #End endTask(self):


        '''
        This function is used by subprocess so that signals are not propagated to the child process, which
        would result in the child process being cancelled without program control.
        '''
        def preexec(self):
                os.setpgrp()
        #End preexec(self):


        #This function is used to get the completion status (Failure or Success) of the deadman build/install.
        def getCompletionStatus(self):
                return self.completionStatus
        #End getExitStatus(self):


        #This function is used to pause the timer thread when a signal is recieved.
        def pauseTimerThread(self):
                self.timeFeedbackThread.pauseTimer()
        #End pauseTimerThread(self):


        #This function is used to restart the timer thread once the signal has been handled.
        def resumeTimerThread(self):
                self.timeFeedbackThread.resumeTimer()
예제 #4
0
class UpdateFusionIO():
    """
    Use the constructor to create a threading event that will be used to stop and restart the timer thread
    when a signal (SIGINT, SIGQUIT) is captured.
    """
    def __init__(self):
        self.timerController = threading.Event()
        self.timeFeedbackThread = ''
        self.pid = ''
        self.cancelled = 'no'
        self.completionStatus = ''

    def updateFusionIO(self, patchResourceDict, loggerName, **kwargs):
        firmwareUpdateRequired = kwargs['firmwareUpdateRequired']
        iomemoryCfgBackup = kwargs['iomemory-vslBackup']
        logger = logging.getLogger(loggerName)
        if firmwareUpdateRequired == 'yes':
            logger.info('Updating the FusionIO firmware and software.')
            busList = kwargs['busList'].split()
        else:
            logger.info('Updating the FusionIO software.')
        try:
            patchBaseDir = re.sub(
                '\\s+', '', patchResourceDict['patchBaseDir']).rstrip('/')
            fusionIOSubDir = re.sub('\\s+', '',
                                    patchResourceDict['fusionIOSubDir'])
            fusionPatchDir = patchBaseDir + '/' + fusionIOSubDir
            fusionSourceDir = fusionPatchDir + '/src/'
            fusionIODriverSrcRPM = re.sub(
                '\\s+', '', patchResourceDict['fusionIODriverSrcRPM'])
        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; the FusionIO firmware and software/driver will have to be updated manually.' + RESETCOLORS
            self.completionStatus = 'Failure'
            return

        command = 'uname -r'
        result = subprocess.Popen(command,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  shell=True)
        out, err = result.communicate()
        logger.debug('The output of the command (' + command +
                     ') used to get the currently used kernel was: ' +
                     out.strip())
        if result.returncode != 0:
            logger.error(
                "Unable to get the system's current kernel information.\n" +
                err)
            print RED + "Unable to get the system's current kernel information; check the log file for errors; the FusionIO firmware and software/driver will have to be updated manually." + RESETCOLORS
            self.completionStatus = 'Failure'
            return
        kernel = out.strip()
        command = 'uname -p'
        result = subprocess.Popen(command,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  shell=True)
        out, err = result.communicate()
        logger.debug('The output of the command (' + command +
                     ") used to get the system's processor type was: " +
                     out.strip())
        if result.returncode != 0:
            logger.error("Unable to get the system's processor type.\n" + err)
            print RED + "Unable to get the system's processor type; check the log file for errors; the FusionIO firmware and software/driver will have to be updated manually." + RESETCOLORS
            self.completionStatus = 'Failure'
            return
        processorType = out.strip()
        fusionIODriverRPM = fusionIODriverSrcRPM.replace(
            'iomemory-vsl', '-vsl-' + kernel).replace('src', processorType)
        if firmwareUpdateRequired == 'yes':
            for bus in busList:
                time.sleep(2)
                message = 'Updating ioDIMM in slot ' + bus
                self.timeFeedbackThread = TimeFeedbackThread(
                    componentMessage=message, event=self.timerController)
                self.timeFeedbackThread.start()
                command = 'fio-update-iodrive -y -f -s ' + bus + ' ' + fusionPatchDir + '/' + '*.fff'
                result = subprocess.Popen(command,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE,
                                          preexec_fn=self.preexec,
                                          shell=True)
                self.pid = result.pid
                out, err = result.communicate()
                logger.debug('The output of the command (' + command +
                             ') used to update the FusionIO firmware was: ' +
                             out.strip())
                self.timeFeedbackThread.stopTimer()
                self.timeFeedbackThread.join()
                print ''
                if result.returncode != 0:
                    if self.cancelled == 'yes':
                        logger.info(
                            'The FusionIO firmware update was cancelled by the user.'
                        )
                        print RED + 'The FusionIO firmware update was cancelled; the FusionIO firmware and software/driver will have to be updated manually.' + RESETCOLORS
                    else:
                        logger.error(
                            'Failed to upgrade the FusionIO firmware:\n' + err)
                        print RED + 'Failed to upgrade the FusionIO firmware; check the log file for errors; the FusionIO firmware and software/driver will have to be updated manually.' + RESETCOLORS
                    self.completionStatus = 'Failure'
                    return

            command = 'rpm -e fio-util'
            result = subprocess.Popen(command,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      shell=True)
            out, err = result.communicate()
            logger.debug(
                'The output of the command (' + command +
                ') used to remove the fio-util package before updating the FusionIO software was: '
                + out.strip())
            if result.returncode != 0:
                logger.error('Failed to remove the fio-util package:\n' + err)
                print RED + 'Failed to remove the fio-util package; check the log file for errors; the FusionIO software/driver will have to be updated manually.' + RESETCOLORS
                self.completionStatus = 'Failure'
                return
        self.timeFeedbackThread = TimeFeedbackThread(
            componentMessage='Updating the FusionIO driver and software',
            event=self.timerController)
        self.timeFeedbackThread.start()
        command = 'rpmbuild --rebuild ' + fusionSourceDir + '*.rpm'
        result = subprocess.Popen(command,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  preexec_fn=self.preexec,
                                  shell=True)
        self.pid = result.pid
        out, err = result.communicate()
        logger.debug('The output of the command (' + command +
                     ') used to build the FusionIO driver was: ' + out.strip())
        if result.returncode != 0:
            self.timeFeedbackThread.stopTimer()
            self.timeFeedbackThread.join()
            if self.cancelled == 'yes':
                logger.info(
                    'The FusionIO driver and software update was cancelled by the user.'
                )
                print RED + '\nThe FusionIO driver and software update was cancelled; the FusionIO software/driver will have to be updated manually.' + RESETCOLORS
            else:
                logger.error('Failed to build the FusionIO driver:\n' + err)
                print RED + 'Failed to build the FusionIO driver; check the log file for errors; the FusionIO software/driver will have to be updated manually.' + RESETCOLORS
            self.completionStatus = 'Failure'
            return
        out = out.strip()
        fusionIODriverPattern = re.compile(
            '.*Wrote:\\s+((/[0-9,a-z,A-Z,_]+)+' + fusionIODriverRPM + ')',
            re.DOTALL)
        logger.debug(
            'The regex used to get the FusionIO driver RPM location was: ' +
            fusionIODriverPattern.pattern)
        driverRPM = re.match(fusionIODriverPattern, out).group(1)
        logger.debug('The FuionIO driver was determined to be: ' + driverRPM)
        try:
            shutil.copy2(driverRPM, fusionPatchDir)
        except IOError as err:
            self.timeFeedbackThread.stopTimer()
            self.timeFeedbackThread.join()
            print ''
            logger.error('Unable to retrieve the driver RPM.\n' + err)
            print RED + 'Unable to retrieve the driver RPM; check log file for errors; the FusionIO firmware and software/driver will have to be updated manually.' + RESETCOLORS
            self.completionStatus = 'Failure'
            return

        command = 'rpm -ivh ' + fusionPatchDir + '/' + '*.rpm'
        result = subprocess.Popen(command,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  preexec_fn=self.preexec,
                                  shell=True)
        self.pid = result.pid
        out, err = result.communicate()
        logger.debug(
            'The output of the command (' + command +
            ') used to install the FusionIO software and driver was: ' +
            out.strip())
        if result.returncode != 0:
            self.timeFeedbackThread.stopTimer()
            self.timeFeedbackThread.join()
            print ''
            if self.cancelled == 'yes':
                logger.info(
                    'The FusionIO driver and software installation was cancelled by the user.'
                )
                print RED + 'The FusionIO driver and software installation was cancelled; the FusionIO software/driver will have to be installed manually from ' + fusionPatchDir + '.' + RESETCOLORS
            else:
                logger.error(
                    'Failed to install the FusionIO software and driver:\n' +
                    err)
                print RED + 'Failed to install the FusionIO software and driver; check the log file for errors; the FusionIO software/driver will have to be installed manually from ' + fusionPatchDir + '.' + RESETCOLORS
            self.completionStatus = 'Failure'
            return
        try:
            shutil.copy2(iomemoryCfgBackup, '/etc/sysconfig/iomemory-vsl')
        except IOError as err:
            logger.error(
                "Failed to restore the system's iomemory-vsl configuration file.\n"
                + str(err))
            print RED + "Failed to restore the system's iomemory-vsl configuration file; check the log file for errors; the file will need to be restored manually." + RESETCOLORS

        if firmwareUpdateRequired == 'yes':
            logger.info('Done Updating the FusionIO firmware and software.')
        else:
            logger.info('Done Updating the FusionIO software.')
        self.timeFeedbackThread.stopTimer()
        self.timeFeedbackThread.join()
        print ''
        self.completionStatus = 'Success'

    def endTask(self):
        try:
            self.cancelled = 'yes'
            pgid = os.getpgid(self.pid)
            os.killpg(pgid, signal.SIGKILL)
        except OSError:
            pass

    def preexec(self):
        os.setpgrp()

    def getCompletionStatus(self):
        return self.completionStatus

    def pauseTimerThread(self):
        self.timeFeedbackThread.pauseTimer()

    def resumeTimerThread(self):
        self.timeFeedbackThread.resumeTimer()
예제 #5
0
class UpdateFusionIO:
    '''
        Use the constructor to create a threading event that will be used to stop and restart the timer thread
        when a signal (SIGINT, SIGQUIT) is captured.
        '''
    
    def __init__(self):
        self.timerController = Event()
        self.timeFeedbackThread = ''
        self.pid = 0
        self.cancelled = 'no'
        self.completionStatus = ''
        self.fusionIOFirmwareUpdateStarted = False
        self.fusionIOFirmwareUpdateThreadList = []

    
    def updateFusionIO(self, patchResourceDict, loggerName, **kwargs):
        firmwareUpdateRequired = kwargs['firmwareUpdateRequired']
        iomemoryCfgBackup = kwargs['iomemory-vslBackup']
        logger = logging.getLogger(loggerName)
        if firmwareUpdateRequired == 'yes':
            logger.info('Updating the FusionIO firmware and software.')
            busList = kwargs['busList'].split()
        else:
            logger.info('Updating the FusionIO software.')
        
        try:
            patchBaseDir = re.sub('\\s+', '', patchResourceDict['patchBaseDir']).rstrip('/')
            fusionIOSubDir = re.sub('\\s+', '', patchResourceDict['fusionIOSubDir'])
            fusionPatchDir = patchBaseDir + '/' + fusionIOSubDir
            fusionSourceDir = fusionPatchDir + '/src/'
            fusionIODriverSrcRPM = re.sub('\\s+', '', patchResourceDict['fusionIODriverSrcRPM'])
        except KeyError:
            err = None
            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; the FusionIO firmware and software/driver will have to be updated manually.' + RESETCOLORS
            self.completionStatus = 'Failure'
            return None

        command = 'uname -r'
        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 currently used kernel was: ' + out.strip())
        if result.returncode != 0:
            logger.error("Unable to get the system's current kernel information.\n" + err)
            print RED + "Unable to get the system's current kernel information; check the log file for errors; the FusionIO firmware and software/driver will have to be updated manually." + RESETCOLORS
            self.completionStatus = 'Failure'
            return None
        kernel = None.strip()
        command = 'uname -p'
        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 processor type was: " + out.strip())
        if result.returncode != 0:
            logger.error("Unable to get the system's processor type.\n" + err)
            print RED + "Unable to get the system's processor type; check the log file for errors; the FusionIO firmware and software/driver will have to be updated manually." + RESETCOLORS
            self.completionStatus = 'Failure'
            return None
        processorType = None.strip()
        fusionIODriverRPM = fusionIODriverSrcRPM.replace('iomemory-vsl', '-vsl-' + kernel).replace('src', processorType)
        if firmwareUpdateRequired == 'yes':
            message = 'Updating ioDIMM(s) ' + ', '.join(busList)
            self.timeFeedbackThread = TimeFeedbackThread(componentMessage = message, event = self.timerController)
            self.timeFeedbackThread.start()
            fusionIOFirmwareUpdateFailureList = []
            self.fusionIOFirmwareUpdateStarted = True
            firmwareImage = fusionPatchDir + '/*.fff'
            for bus in busList:
                self.fusionIOFirmwareUpdateThreadList.append(FusionIOFirmwareUpdate(bus, firmwareImage, fusionIOFirmwareUpdateFailureList, loggerName))
                self.fusionIOFirmwareUpdateThreadList[-1].start()
            
            while None:
                for i in range(0, len(self.fusionIOFirmwareUpdateThreadList)):
                    if not self.fusionIOFirmwareUpdateThreadList[i].isAlive():
                        del self.fusionIOFirmwareUpdateThreadList[i]
                        break
                        continue
                if len(self.fusionIOFirmwareUpdateThreadList) == 0:
                    break
                    continue
                self.fusionIOFirmwareUpdateStarted = False
                self.timeFeedbackThread.stopTimer()
                self.timeFeedbackThread.join()
                print ''
                if len(fusionIOFirmwareUpdateFailureList) > 0:
                    if self.cancelled == 'yes':
                        logger.info('The FusionIO firmware update was cancelled by the user.')
                        print RED + 'The FusionIO firmware update was cancelled; the FusionIO firmware and software/driver will have to be updated manually.' + RESETCOLORS
                    else:
                        logger.error('Problems were encountered while updating the FusionIO firmware for the IODIMMS: ' + ', '.join(fusionIOFirmwareUpdateFailureList))
                        print RED + 'Failed to upgrade the FusionIO firmware; check the log file for errors; the FusionIO firmware and software/driver will have to be updated manually.' + RESETCOLORS
                    self.completionStatus = 'Failure'
                    return None
                command = None
                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 remove the fio-util package before updating the FusionIO software was: ' + out.strip())
                if result.returncode != 0:
                    logger.error('Failed to remove the fio-util package:\n' + err)
                    print RED + 'Failed to remove the fio-util package; check the log file for errors; the FusionIO software/driver will have to be updated manually.' + RESETCOLORS
                    self.completionStatus = 'Failure'
                    return None
                self.timeFeedbackThread = TimeFeedbackThread(componentMessage = 'Updating the FusionIO driver and software', event = self.timerController)
                self.timeFeedbackThread.start()
                command = 'rpmbuild --rebuild ' + fusionSourceDir + '*.rpm'
                result = subprocess.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.PIPE, preexec_fn = self.preexec, shell = True)
                self.pid = result.pid
                (out, err) = result.communicate()
                logger.info('The output of the command (' + command + ') used to build the FusionIO driver was: ' + out.strip())
                if result.returncode != 0:
                    self.timeFeedbackThread.stopTimer()
                    self.timeFeedbackThread.join()
                    if self.cancelled == 'yes':
                        logger.info('The FusionIO driver and software update was cancelled by the user.')
                        print RED + '\nThe FusionIO driver and software update was cancelled; the FusionIO software/driver will have to be updated manually.' + RESETCOLORS
                    else:
                        logger.error('Failed to build the FusionIO driver:\n' + err)
                        print RED + 'Failed to build the FusionIO driver; check the log file for errors; the FusionIO software/driver will have to be updated manually.' + RESETCOLORS
                    self.completionStatus = 'Failure'
                    return None
                out = None.strip()
                fusionIODriverPattern = re.compile('.*Wrote:\\s+((/[0-9,a-z,A-Z,_]+)+' + fusionIODriverRPM + ')', re.DOTALL)
                logger.info('The regex used to get the FusionIO driver RPM location was: ' + fusionIODriverPattern.pattern)
                driverRPM = re.match(fusionIODriverPattern, out).group(1)
                logger.info('The FuionIO driver was determined to be: ' + driverRPM)
                
                try:
                    shutil.copy2(driverRPM, fusionPatchDir)
                except IOError:
                    err = None
                    self.timeFeedbackThread.stopTimer()
                    self.timeFeedbackThread.join()
                    print ''
                    logger.error('Unable to retrieve the driver RPM.\n' + err)
                    print RED + 'Unable to retrieve the driver RPM; check log file for errors; the FusionIO firmware and software/driver will have to be updated manually.' + RESETCOLORS
                    self.completionStatus = 'Failure'
                    return None

                self.pid = 0
                command = 'rpm -ivh ' + fusionPatchDir + '/' + '*.rpm'
                result = subprocess.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.PIPE, preexec_fn = self.preexec, shell = True)
                self.pid = result.pid
                (out, err) = result.communicate()
                logger.info('The output of the command (' + command + ') used to install the FusionIO software and driver was: ' + out.strip())
                if result.returncode != 0:
                    self.timeFeedbackThread.stopTimer()
                    self.timeFeedbackThread.join()
                    print ''
                    if self.cancelled == 'yes':
                        logger.info('The FusionIO driver and software installation was cancelled by the user.')
                        print RED + 'The FusionIO driver and software installation was cancelled; the FusionIO software/driver will have to be installed manually from ' + fusionPatchDir + '.' + RESETCOLORS
                    else:
                        logger.error('Failed to install the FusionIO software and driver:\n' + err)
                        print RED + 'Failed to install the FusionIO software and driver; check the log file for errors; the FusionIO software/driver will have to be installed manually from ' + fusionPatchDir + '.' + RESETCOLORS
                    self.completionStatus = 'Failure'
                    return None
                shutil.copy2(iomemoryCfgBackup, '/etc/sysconfig/iomemory-vsl')
        else:
            except IOError:
                err = None
                logger.error("Failed to restore the system's iomemory-vsl configuration file.\n" + str(err))
                print RED + "Failed to restore the system's iomemory-vsl configuration file; check the log file for errors; the file will need to be restored manually." + RESETCOLORS
        if firmwareUpdateRequired == 'yes':
            logger.info('Done Updating the FusionIO firmware and software.')
        else:
            logger.info('Done Updating the FusionIO software.')
        self.timeFeedbackThread.stopTimer()
        self.timeFeedbackThread.join()
        print ''
        self.completionStatus = 'Success'
예제 #6
0
class ApplyPatches:
    '''
	Use the constructor to create a threading event that will be used to stop and restart the timer thread		
	when a signal (SIGINT, SIGQUIT) is captured.  Additionally, create the timer thread without a message, 
	since it will be set later depending on the type of patches being applied.
	self.exitStatus is used to inform the caller as to whether or not the program needs to exit, which would be
	the case if self.exitStatus is not 0.
	'''
    def __init__(self):

        self.timerController = threading.Event()
        self.timeFeedbackThread = ''
        self.pid = ''
        self.exitStatus = 0
        self.cancelled = 'no'
#End __init__(self):

    '''
	This function is used to apply the patches. 
	'''
    def applyPatches(self, repositoryList, loggerName):

        logger = logging.getLogger(loggerName)

        if len(repositoryList) > 1:
            logger.info('Applying patches from repositories ' +
                        ', '.join(repositoryList) + '.')
        else:
            logger.info('Applying patches from repository ' +
                        repositoryList[0] + '.')

        logger.debug("The patch repository list was determined to be: " +
                     str(repositoryList))

        #Update OS patches and install kernel patches.
        for repository in repositoryList:
            time.sleep(2)

            if 'kernel' in repository.lower():
                self.timeFeedbackThread = TimeFeedbackThread(
                    componentMessage='Installing the new kernel',
                    event=self.timerController)
                self.timeFeedbackThread.start()

                command = 'zypper -n --non-interactive-include-reboot-patches in ' + repository + ':*'
            else:
                self.timeFeedbackThread = TimeFeedbackThread(
                    componentMessage='Applying the OS patches',
                    event=self.timerController)
                self.timeFeedbackThread.start()

                command = 'zypper -n --non-interactive-include-reboot-patches up ' + repository + ':*'

            result = subprocess.Popen(command,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      preexec_fn=self.preexec,
                                      shell=True)

            #We get the processes PID in case the process is cancelled and we need to kill the process.
            self.pid = result.pid

            out, err = result.communicate()

            logger.debug("The output of the patch update command (" + command +
                         ") was: " + out.strip())

            if result.returncode == 0:
                logger.info(
                    "Successfully updated the system using patches from the repository "
                    + repository + ".")
            else:
                self.timeFeedbackThread.stopTimer()
                self.timeFeedbackThread.join()

                #Move the cursor to the next line once the timer is stopped.
                print ''

                if self.cancelled == 'yes':
                    logger.info("The patch update was cancelled by the user.")
                    print RED + "The patch update was cancelled; exiting program execution." + RESETCOLORS
                else:
                    logger.error(
                        "Problems were encountered while updating the system using patches from the repository "
                        + repository + ".\n" + err)
                    print RED + "Problems were encountered while applying the patches to the system; check the log file for errors; exiting program execution." + RESETCOLORS

                self.exitStatus = 1
                return

            self.timeFeedbackThread.stopTimer()
            self.timeFeedbackThread.join()

            #Move the cursor to the next line once the timer is stopped.
            print ''

        if len(repositoryList) > 1:
            logger.info('Done applying patches from repositories ' +
                        ', '.join(repositoryList) + '.')
        else:
            logger.info('Done applying patches from repository ' +
                        repositoryList[0] + '.')

    #End applyPatches(repositoryList, loggerName):

    #This function will attempt to kill the running processes as requested by the user.
    def endTask(self):

        try:
            self.cancelled = 'yes'
            pgid = os.getpgid(self.pid)
            os.killpg(pgid, signal.SIGKILL)
        except OSError:
            pass

    #End endTask(self):
    '''
	This function is used by subprocess so that signals are not propagated to the child process, which
	would result in the child process being cancelled without program control.
	'''

    def preexec(self):
        os.setpgrp()

    #End preexec(self):

    #This function is used to get the exit status of the patch update.
    def getExitStatus(self):
        return self.exitStatus

    #End getExitStatus(self):

    #This function is used to pause the timer thread when a signal is recieved.
    def pauseTimerThread(self):
        self.timeFeedbackThread.pauseTimer()

    #End pauseTimerThread(self):

    #This function is used to restart the timer thread once the signal has been handled.
    def resumeTimerThread(self):
        self.timeFeedbackThread.resumeTimer()
예제 #7
0
class BuildDeadmanDriver:
    """
    Use the constructor to create a threading event that will be used to stop and restart the timer thread
    when a signal (SIGINT, SIGQUIT) is captured.
    """
    def __init__(self):
        self.timerController = threading.Event()
        self.timeFeedbackThread = TimeFeedbackThread(
            componentMessage='Rebuilding and installing the deadman driver',
            event=self.timerController)
        self.pid = ''
        self.cancelled = 'no'
        self.completionStatus = ''

    def buildDeadmanDriver(self, loggerName):
        sgDriverDir = '/opt/cmcluster/drivers'
        logger = logging.getLogger(loggerName)
        logger.info(
            'Rebuilding and installing the deadman driver for the new kernel.')
        cwd = os.getcwd()
        try:
            os.chdir(sgDriverDir)
        except OSError as err:
            logger.error(
                'Could not change into the deadman drivers directory (' +
                sgDriverDir + ').\n' + str(err))
            print RED + 'Could not change into the deadman drivers directory; check the log file for errors; the deadman driver will have to be manually built/installed.' + RESETCOLORS
            self.completionStatus = 'Failure'
            return

        driverBuildCommandsList = [
            'make modules', 'make modules_install', 'depmod -a'
        ]
        self.timeFeedbackThread.start()
        for command in driverBuildCommandsList:
            buildCommand = command
            result = subprocess.Popen(buildCommand,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      preexec_fn=self.preexec,
                                      shell=True)
            self.pid = result.pid
            out, err = result.communicate()
            logger.debug(
                'The output of the command (' + command +
                ') used in building and installing the deadman driver was: ' +
                out.strip())
            if result.returncode != 0:
                self.timeFeedbackThread.stopTimer()
                self.timeFeedbackThread.join()
                print ''
                if self.cancelled == 'yes':
                    logger.info(
                        'The deadman driver build and install was cancelled by the user.'
                    )
                    print RED + 'The deadman driver build and install was cancelled; the deadman driver will have to be manually built/installed.' + RESETCOLORS
                else:
                    logger.error(
                        'Failed to build and install the deadman driver.\n' +
                        err)
                    print RED + 'Failed to build and install the deadman driver; check the log file for errors; the deadman driver will have to be manually built/installed.' + RESETCOLORS
                self.completionStatus = 'Failure'
                return

        self.timeFeedbackThread.stopTimer()
        self.timeFeedbackThread.join()
        print ''
        try:
            os.chdir(cwd)
        except:
            pass

        logger.info(
            'Done rebuilding and installing the deadman driver for the new kernel.'
        )
        self.completionStatus = 'Success'

    def endTask(self):
        try:
            self.cancelled = 'yes'
            pgid = os.getpgid(self.pid)
            os.killpg(pgid, signal.SIGKILL)
        except OSError:
            pass

    def preexec(self):
        os.setpgrp()

    def getCompletionStatus(self):
        return self.completionStatus

    def pauseTimerThread(self):
        self.timeFeedbackThread.pauseTimer()

    def resumeTimerThread(self):
        self.timeFeedbackThread.resumeTimer()
예제 #8
0
def updateFusionIO(patchResourceDict, **kwargs):

	firmwareUpdateRequired = kwargs['firmwareUpdateRequired']

	logger = logging.getLogger("patchLogger")

	if firmwareUpdateRequired == 'yes':
		logger.info("Updating the FusionIO firmware and software.")
		busList = (kwargs['busList']).split()
	else:
		logger.info("Updating the FusionIO software.")

	try:
		patchBaseDir = (re.sub('\s+', '', patchResourceDict['patchBaseDir'])).rstrip('/')
		fusionIOSubDir = re.sub('\s+', '', patchResourceDict['fusionIOSubDir'])

		fusionPatchDir = patchBaseDir + '/' + fusionIOSubDir
		fusionSourceDir = fusionPatchDir + '/src/'

		fusionIODriverSrcRPM = re.sub('\s+', '', patchResourceDict['fusionIODriverSrcRPM'])
	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; the FusionIO firmware and software/driver will have to be updated manually." + RESETCOLORS
		return 'Failure'

	#Get the currently used kernel and processor type, which is used as part of the driver RPM name.
        command = 'uname -r'
        result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        out, err = result.communicate()

	logger.debug("The output of the command (" + command + ") used to get the currently used kernel was: " + out.strip())

        if result.returncode != 0:
                logger.error("Unable to get the system's current kernel information.\n" + err)
                print RED + "Unable to get the system's current kernel information; check the log file for errors; the FusionIO firmware and software/driver will have to be updated manually." + RESETCOLORS
                return
        else:
                kernel = out.strip()

        command = 'uname -p'
        result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        out, err = result.communicate()

	logger.debug("The output of the command (" + command + ") used to get the system's processor type was: " + out.strip())

        if result.returncode != 0:
                logger.error("Unable to get the system's processor type.\n" + err)
                print RED + "Unable to get the system's processor type; check the log file for errors; the FusionIO firmware and software/driver will have to be updated manually." + RESETCOLORS
		return 'Failure'
        else:
                processorType = out.strip()

	'''
	This strips off iomemory from RPM name, since it will not be needed in the regex match.
	Additionally, the source RPM is renamed to the driver RPM's name, which includes the current 
	kernel and processor type in its name.
	'''
	fusionIODriverRPM = (fusionIODriverSrcRPM.replace('iomemory-vsl', '-vsl-' + kernel)).replace('src', processorType)

	#Update the FusionIO firmware if it was determined that it is out of date.
	if firmwareUpdateRequired == 'yes':

		#Set traps so that the firmware update is not interrupted by the user.
		original_sigint_handler = signal.getsignal(signal.SIGINT)
		original_sigquit_handler = signal.getsignal(signal.SIGQUIT)
		signal.signal(signal.SIGINT, firmware_signal_handler)
		signal.signal(signal.SIGQUIT, firmware_signal_handler)

                for bus in busList:
			time.sleep(2)
                        timeFeedbackThread = TimeFeedbackThread("Updating ioDIMM in slot", bus)
                        timeFeedbackThread.start()

                        command = "fio-update-iodrive -y -f -s " + bus + ' ' + fusionPatchDir + '/' + "*.fff"
                        result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
                        out, err = result.communicate()

			logger.debug("The output of the command (" + command + ") used to update the FusionIO firmware was: " + out.strip())

			timeFeedbackThread.stopTimer()
                        timeFeedbackThread.join()

			if result.returncode != 0:
				logger.error("Failed to upgrade the FusionIO firmware:\n" + err)
				print RED + "Failed to upgrade the FusionIO firmware; check the log file for errors; the FusionIO firmware and software/driver will have to be updated manually." + RESETCOLORS
				signal.signal(signal.SIGINT, original_sigint_handler)
                		signal.signal(signal.SIGQUIT, original_sigquit_handler)
				return 'Failure'

		#Restore the signals back to their defaults.
		signal.signal(signal.SIGINT, original_sigint_handler)
                signal.signal(signal.SIGQUIT, original_sigquit_handler)

		#Remove the fio-util package before updating the software, since it is no longer needed for any firmware updates.
		command = "rpm -e fio-util"
		result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
		out, err = result.communicate()

		logger.debug("The output of the command (" + command + ") used to remove the fio-util package before updating the FusionIO software was: " + out.strip())

		if result.returncode != 0:
			logger.error("Failed to remove the fio-util package:\n" + err)
			print RED + "Failed to remove the fio-util package; check the log file for errors; the FusionIO software/driver will have to be updated manually." + RESETCOLORS
			return 'Failure'

	#Build the driver for the new kernel.
	timeFeedbackThread = TimeFeedbackThread("Updating the FusionIO driver and software")
	timeFeedbackThread.start()

	command = "rpmbuild --rebuild " + fusionSourceDir + "*.rpm"
	result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
	out, err = result.communicate()

	logger.debug("The output of the command (" + command + ") used to build the FusionIO driver was: " + out.strip())

	if result.returncode != 0:
		timeFeedbackThread.stopTimer()
		timeFeedbackThread.join()
		logger.error("Failed to build the FusionIO driver:\n" + err)
		print RED + "Failed to build the FusionIO driver; check the log file for errors; the FusionIO software/driver will have to be updated manually." + RESETCOLORS
		return 'Failure'

	out = out.strip()

	#Compile the regex that will be used to get the driver RPM location.
	fusionIODriverPattern = re.compile('.*Wrote:\s+((/[0-9,a-z,A-Z,_]+)+' + fusionIODriverRPM +')', re.DOTALL)

	logger.debug("The regex used to get the FusionIO driver RPM location was: " + fusionIODriverPattern.pattern)

	driverRPM = re.match(fusionIODriverPattern, out).group(1)

	logger.debug("The FuionIO driver was determined to be: " + driverRPM)

	#Now copy the new driver RPM to the FusionIO patch directory so that it gets installed with the rest of the RPMs.
	try:
		shutil.copy2(driverRPM, fusionPatchDir)
	except IOError as err:
		timeFeedbackThread.stopTimer()
		timeFeedbackThread.join()
		logger.error("Unable to retrieve the driver RPM.\n" + err)
                print RED + "Unable to retrieve the driver RPM; check log file for errors; the FusionIO firmware and software/driver will have to be updated manually." + RESETCOLORS
		return 'Failure'

	#Update the FusionIO software.
	command = "rpm -ivh " + fusionPatchDir + '/' + "*.rpm"
	result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
	out, err = result.communicate()

	logger.debug("The output of the command (" + command + ") used to update the FusionIO software was: " + out.strip())

	if result.returncode != 0:
		timeFeedbackThread.stopTimer()
		timeFeedbackThread.join()
		logger.error("Failed to update the FusionIO software:\n" + err)
		print RED + "Failed to update the FusionIO software; check the log file for errors; the FusionIO software/driver will have to be updated manually." + RESETCOLORS
		return 'Failure'

	if firmwareUpdateRequired == 'yes':
		logger.info("Done Updating the FusionIO firmware and software.")
	else:
		logger.info("Done Updating the FusionIO software.")

	timeFeedbackThread.stopTimer()
	timeFeedbackThread.join()

	return 'Success'