def getFcpDevices(rh): """ Lists the FCP device channels that are active, free, or offline. Input: Request Handle with the following properties: function - 'GETHOST' subfunction - 'FCPDEVICES' Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter getHost.getFcpDevices") parms = ["-T", "dummy"] results = invokeSMCLI(rh, "System_WWPN_Query", parms) if results['overallRC'] == 0: rh.printLn("N", results['response']) else: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI rh.printSysLog("Exit getHost.getFcpDevices, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def getDirectory(rh): """ Get the virtual machine's directory statements. Input: Request Handle with the following properties: function - 'CMDVM' subfunction - 'CMD' userid - userid of the virtual machine Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter getVM.getDirectory") parms = ["-T", rh.userid] results = invokeSMCLI(rh, "Image_Query_DM", parms) if results['overallRC'] == 0: results['response'] = re.sub('\*DVHOPT.*', '', results['response']) rh.printLn("N", results['response']) else: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI rh.printSysLog("Exit getVM.getDirectory, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def getDiskPoolNames(rh): """ Obtain the list of disk pools known to the directory manager. Input: Request Handle with the following properties: function - 'GETHOST' subfunction - 'DISKPOOLNAMES' Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter getHost.getDiskPoolNames") parms = ["-q", "1", "-e", "3", "-T", "dummy"] results = invokeSMCLI(rh, "Image_Volume_Space_Query_DM", parms) if results['overallRC'] == 0: for line in results['response'].splitlines(): poolName = line.partition(' ')[0] rh.printLn("N", poolName) else: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI rh.printSysLog("Exit getHost.getDiskPoolNames, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def activate(rh): """ Activate a virtual machine. Input: Request Handle with the following properties: function - 'POWERVM' subfunction - 'ON' userid - userid of the virtual machine parms['desiredState'] - Desired state. Optional, unless 'maxQueries' is specified. parms['maxQueries'] - Maximum number of queries to issue. Optional. parms['maxWait'] - Maximum time to wait in seconds. Optional, unless 'maxQueries' is specified. parms['poll'] - Polling interval in seconds. Optional, unless 'maxQueries' is specified. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter powerVM.activate, userid: " + rh.userid) parms = ["-T", rh.userid] smcliResults = invokeSMCLI(rh, "Image_Activate", parms) if smcliResults['overallRC'] == 0: pass elif (smcliResults['overallRC'] == 8 and smcliResults['rc'] == 200 and smcliResults['rs'] == 8): pass # All good. No need to change the ReqHandle results. else: # SMAPI API failed. rh.printLn("ES", smcliResults['response']) rh.updateResults(smcliResults) # Use results from invokeSMCLI if rh.results['overallRC'] == 0 and 'maxQueries' in rh.parms: # Wait for the system to be in the desired state of: # OS is 'up' and reachable or VM is 'on'. if rh.parms['desiredState'] == 'up': results = waitForOSState(rh, rh.userid, rh.parms['desiredState'], maxQueries=rh.parms['maxQueries'], sleepSecs=rh.parms['poll']) else: results = waitForVMState(rh, rh.userid, rh.parms['desiredState'], maxQueries=rh.parms['maxQueries'], sleepSecs=rh.parms['poll']) if results['overallRC'] == 0: rh.printLn("N", "%s: %s" % (rh.userid, rh.parms['desiredState'])) else: rh.updateResults(results) rh.printSysLog("Exit powerVM.activate, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def removeIPL(rh): """ Sets the IPL statement in the virtual machine's directory entry. Input: Request Handle with the following properties: function - 'CHANGEVM' subfunction - 'REMOVEIPL' userid - userid of the virtual machine Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter changeVM.removeIPL") parms = ["-T", rh.userid] results = invokeSMCLI(rh, "Image_IPL_Delete_DM", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI rh.printSysLog("Exit changeVM.removeIPL, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def unpause(rh): """ Unpause a virtual machine. Input: Request Handle with the following properties: function - 'POWERVM' subfunction - 'UNPAUSE' userid - userid of the virtual machine Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter powerVM.unpause, userid: " + rh.userid) parms = ["-T", rh.userid, "-k", "PAUSE=NO"] results = invokeSMCLI(rh, "Image_Pause", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI rh.printSysLog("Exit powerVM.unpause, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def modifyMigrate(rh): """ Modify an existing VMRelocate request. Input: Request Handle with the following properties: function - 'MIGRATEVM' subfunction - 'MODIFY' userid - userid of the virtual machine parms['maxQuiesce'] - maximum quiesce time in seconds, or -1 to indicate no limit. parms['maxTotal'] - maximum total time in seconds, or -1 to indicate no limit. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter migrateVM.modifyMigrate") parms = ["-T", rh.userid] if 'maxQuiesce' in rh.parms: if rh.parms['maxQuiesce'] == -1: parms.extend(["-k", "max_quiesce=NOLIMIT"]) else: parms.extend(["-k", "max_quiesce=" + str(rh.parms['maxQuiesce'])]) if 'maxTotal' in rh.parms: if rh.parms['maxTotal'] == -1: parms.extend(["-k", "max_total=NOLIMIT"]) else: parms.extend(["-k", "max_total=" + str(rh.parms['maxTotal'])]) results = invokeSMCLI(rh, "VMRELOCATE_Modify", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI if results['rc'] == 8 and results['rs'] == 3010: if "1926" in results['response']: # No relocations in progress msg = msgs.msg['0419'][1] % (modId, rh.userid) rh.printLn("ES", msg) rh.updateResults(msgs.msg['0419'][0]) else: # More details in message codes lines = results['response'].split("\n") for line in lines: if "Details:" in line: codes = line.split(' ', 1)[1] msg = msgs.msg['0420'][1] % (modId, "VMRELOCATE Modify", rh.userid, codes) rh.printLn("ES", msg) rh.printSysLog("Exit migrateVM.modifyMigrate, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def removeDisk(rh): """ Remove a disk from a virtual machine. Input: Request Handle with the following properties: function - 'CHANGEVM' subfunction - 'REMOVEDISK' userid - userid of the virtual machine parms['vaddr'] - Virtual address Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter changeVM.removeDisk") results = {'overallRC': 0, 'rc': 0, 'rs': 0} # Is image logged on loggedOn = False results = isLoggedOn(rh, rh.userid) if results['overallRC'] == 0: if results['rs'] == 0: loggedOn = True results = disableEnableDisk(rh, rh.userid, rh.parms['vaddr'], '-d') if results['overallRC'] != 0: rh.printLn("ES", results['response']) rh.updateResults(results) if results['overallRC'] == 0 and loggedOn: strCmd = "/sbin/vmcp detach " + rh.parms['vaddr'] results = execCmdThruIUCV(rh, rh.userid, strCmd) if results['overallRC'] != 0: rh.printLn("ES", results['response']) rh.updateResults(results) if results['overallRC'] == 0: # Remove the disk from the user entry. parms = ["-T", rh.userid, "-v", rh.parms['vaddr'], "-e", "0"] results = invokeSMCLI(rh, "Image_Disk_Delete_DM", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI else: # Unexpected error. Message already sent. rh.updateResults(results) rh.printSysLog("Exit changeVM.removeDisk, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def deactivate(rh): """ Deactivate a virtual machine. Input: Request Handle with the following properties: function - 'POWERVM' subfunction - 'OFF' userid - userid of the virtual machine parms['maxQueries'] - Maximum number of queries to issue. Optional. parms['maxWait'] - Maximum time to wait in seconds. Optional, unless 'maxQueries' is specified. parms['poll'] - Polling interval in seconds. Optional, unless 'maxQueries' is specified. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter powerVM.deactivate, userid: " + rh.userid) parms = ["-T", rh.userid, "-f", "IMMED"] results = invokeSMCLI(rh, "Image_Deactivate", parms) if results['overallRC'] == 0: pass elif (results['overallRC'] == 8 and results['rc'] == 200 and (results['rs'] == 12 or results['rs'] == 16)): # Tolerable error. Machine is already in or going into the state # we want it to enter. rh.printLn("N", rh.userid + ": off") rh.updateResults({}, reset=1) else: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI if results['overallRC'] == 0 and 'maxQueries' in rh.parms: results = waitForVMState(rh, rh.userid, 'off', maxQueries=rh.parms['maxQueries'], sleepSecs=rh.parms['poll']) if results['overallRC'] == 0: rh.printLn("N", rh.userid + ": off") else: rh.updateResults(results) rh.printSysLog("Exit powerVM.deactivate, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def createVM(rh): """ Create a virtual machine in z/VM. Input: Request Handle with the following properties: function - 'CMDVM' subfunction - 'CMD' userid - userid of the virtual machine Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter makeVM.createVM") dirLines = [] dirLines.append("USER " + rh.userid + " " + rh.parms['pw'] + " " + rh.parms['priMemSize'] + " " + rh.parms['maxMemSize'] + " " + rh.parms['privClasses']) if 'profName' in rh.parms: dirLines.append("INCLUDE " + rh.parms['profName']) dirLines.append("CPU 00 BASE") if 'cpuCnt' in rh.parms: for i in range(1, rh.parms['cpuCnt']): dirLines.append("CPU %0.2X" % i) if 'ipl' in rh.parms: dirLines.append("IPL %0.4s" % rh.parms['ipl']) if 'byUsers' in rh.parms: for user in rh.parms['byUsers']: dirLines.append("LOGONBY " + user) # Construct the temporary file for the USER entry. fd, tempFile = mkstemp() os.write(fd, '\n'.join(dirLines) + '\n') os.close(fd) parms = ["-T", rh.userid, "-f", tempFile] results = invokeSMCLI(rh, "Image_Create_DM", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI os.remove(tempFile) rh.printSysLog("Exit makeVM.createVM, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def getStatus(rh): """ Get status of a VMRelocate request. Input: Request Handle with the following properties: function - 'MIGRATEVM' subfunction - 'STATUS' userid - userid of the virtual machine parms['all'] - If present, set status_target to ALL. parms['incoming'] - If present, set status_target to INCOMING. parms['outgoing'] - If present, set status_target to OUTGOING. if parms does not contain 'all', 'incoming' or 'outgoing', the status_target is set to 'USER <userid>'. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter migrateVM.getStatus") parms = ["-T", rh.userid] if 'all' in rh.parms: parms.extend(["-k", "status_target=ALL"]) elif 'incoming' in rh.parms: parms.extend(["-k", "status_target=INCOMING"]) elif 'outgoing' in rh.parms: parms.extend(["-k", "status_target=OUTGOING"]) else: parms.extend(["-k", "status_target=USER " + rh.userid + ""]) results = invokeSMCLI(rh, "VMRELOCATE_Status", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI if results['rc'] == 4 and results['rs'] == 3001: # No relocation in progress msg = msgs.msg['0419'][1] % (modId, rh.userid) rh.printLn("ES", msg) rh.updateResults(msgs.msg['0419'][0]) else: rh.printLn("N", results['response']) rh.printSysLog("Exit migrateVM.getStatus, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def testMigrate(rh): """ Test the ability to use VMRelocate on the target userid. Input: Request Handle with the following properties: function - 'MIGRATEVM' subfunction - 'TEST' userid - userid of the virtual machine parms['dest'] - Target SSI system. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter migrateVM.testMigrate") parms = ["-T", rh.userid, "-k", "action=TEST"] if 'dest' in rh.parms: parms.extend(["-k", "destination=" + rh.parms['dest']]) results = invokeSMCLI(rh, "VMRELOCATE", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI if results['rc'] == 4 and results['rs'] == 3000: if "0045" in results['response']: # User not logged on msg = msgs.msg['0418'][1] % (modId, rh.userid) rh.printLn("ES", msg) rh.updateResults(msgs.msg['0418'][0]) else: # More details in message codes lines = results['response'].split("\n") for line in lines: if "Details:" in line: codes = line.split(' ', 1)[1] msg = msgs.msg['0420'][1] % (modId, "VMRELOCATE Move", rh.userid, codes) rh.printSysLog("Exit migrateVM.testMigrate, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def cancelMigrate(rh): """ Cancel an existing VMRelocate request. Input: Request Handle with the following properties: function - 'MIGRATEVM' subfunction - 'CANCEL' userid - userid of the virtual machine Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter migrateVM.cancelMigrate") parms = ["-T", rh.userid, "-k", "action=CANCEL"] results = invokeSMCLI(rh, "VMRELOCATE", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI if results['rc'] == 8 and results['rs'] == 3000: if "1926" in results['response']: # No relocation in progress msg = msgs.msg['0419'][1] % (modId, rh.userid) rh.printLn("ES", msg) rh.updateResults(msgs.msg['0419'][0]) else: # More details in message codes lines = results['response'].split("\n") for line in lines: if "Details:" in line: codes = line.split(' ', 1)[1] msg = msgs.msg['420'][1] % (modId, "VMRELOCATE Cancel", rh.userid, codes) rh.printLn("ES", msg) rh.printSysLog("Exit migrateVM.cancelMigrate, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def invokeSmapiApi(rh): """ Invoke a SMAPI API. Input: Request Handle with the following properties: function - 'SMAPI' subfunction - 'API' userid - 'HYPERVISOR' parms['apiName'] - Name of API as defined by SMCLI parms['operands'] - List (array) of operands to send or an empty list. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter smapi.invokeSmapiApi") if rh.userid != 'HYPERVISOR': userid = rh.userid else: userid = 'dummy' parms = ["-T", userid] if 'operands' in rh.parms: parms.extend(rh.parms['operands']) results = invokeSMCLI(rh, rh.parms['apiName'], parms) if results['overallRC'] == 0: rh.printLn("N", results['response']) else: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI rh.printSysLog("Exit smapi.invokeCmd, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def addIPL(rh): """ Sets the IPL statement in the virtual machine's directory entry. Input: Request Handle with the following properties: function - 'CHANGEVM' subfunction - 'IPL' userid - userid of the virtual machine parms['addrOrNSS'] - Address or NSS name parms['loadparms'] - Loadparms operand (optional) parms['parms'] - Parms operand (optional) Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter changeVM.addIPL") parms = ["-T", rh.userid, "-s", rh.parms['addrOrNSS']] if 'loadparms' in rh.parms: parms.extend(["-l", rh.parms['loadparms']]) if 'parms' in rh.parms: parms.extend(["-p", rh.parms['parms']]) results = invokeSMCLI(rh, "Image_IPL_Set_DM", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI rh.printSysLog("Exit changeVM.addIPL, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def add9336(rh): """ Adds a 9336 (FBA) disk to virtual machine's directory entry. Input: Request Handle with the following properties: function - 'CHANGEVM' subfunction - 'ADD9336' userid - userid of the virtual machine parms['diskPool'] - Disk pool parms['diskSize'] - size of the disk in blocks or bytes. parms['fileSystem'] - Linux filesystem to install on the disk. parms['mode'] - Disk access mode parms['multiPW'] - Multi-write password parms['readPW'] - Read password parms['vaddr'] - Virtual address parms['writePW'] - Write password Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter changeVM.add9336") results, blocks = generalUtils.cvtToBlocks(rh, rh.parms['diskSize']) if results['overallRC'] != 0: # message already sent. Only need to update the final results. rh.updateResults(results) if results['overallRC'] == 0: parms = [ "-T", rh.userid, "-v", rh.parms['vaddr'], "-t", "9336", "-a", "AUTOG", "-r", rh.parms['diskPool'], "-u", "1", "-z", blocks, "-f", "1" ] hideList = [] if 'mode' in rh.parms: parms.extend(["-m", rh.parms['mode']]) else: parms.extend(["-m", 'W']) if 'readPW' in rh.parms: parms.extend(["-R", rh.parms['readPW']]) hideList.append(len(parms) - 1) if 'writePW' in rh.parms: parms.extend(["-W", rh.parms['writePW']]) hideList.append(len(parms) - 1) if 'multiPW' in rh.parms: parms.extend(["-M", rh.parms['multiPW']]) hideList.append(len(parms) - 1) results = invokeSMCLI(rh, "Image_Disk_Create_DM", parms, hideInLog=hideList) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI if (results['overallRC'] == 0 and 'fileSystem' in rh.parms): # Install the file system results = installFS(rh, rh.parms['vaddr'], rh.parms['mode'], rh.parms['fileSystem'], "9336") if results['overallRC'] == 0: results = isLoggedOn(rh, rh.userid) if (results['overallRC'] == 0 and results['rs'] == 0): # Add the disk to the active configuration. parms = [ "-T", rh.userid, "-v", rh.parms['vaddr'], "-m", rh.parms['mode'] ] results = invokeSMCLI(rh, "Image_Disk_Create", parms) if results['overallRC'] == 0: rh.printLn( "N", "Added dasd " + rh.parms['vaddr'] + " to the active configuration.") else: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI rh.printSysLog("Exit changeVM.add9336, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def softDeactivate(rh): """ Deactivate a virtual machine by first shutting down Linux and then log it off. Input: Request Handle with the following properties: function - 'POWERVM' subfunction - 'SOFTOFF' userid - userid of the virtual machine parms['maxQueries'] - Maximum number of queries to issue. Optional. parms['maxWait'] - Maximum time to wait in seconds. Optional, unless 'maxQueries' is specified. parms['poll'] - Polling interval in seconds. Optional, unless 'maxQueries' is specified. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter powerVM.softDeactivate, userid: " + rh.userid) strCmd = "echo 'ping'" iucvResults = execCmdThruIUCV(rh, rh.userid, strCmd) if iucvResults['overallRC'] == 0: # We could talk to the machine, tell it to shutdown nicely. strCmd = "shutdown -h now" iucvResults = execCmdThruIUCV(rh, rh.userid, strCmd) if iucvResults['overallRC'] == 0: time.sleep(15) else: # Shutdown failed. Let CP take down the system # after we log the results. rh.printSysLog("powerVM.softDeactivate " + rh.userid + " is unreachable. Treating it as already shutdown.") else: # Could not ping the machine. Treat it as a success # after we log the results. rh.printSysLog("powerVM.softDeactivate " + rh.userid + " is unreachable. Treating it as already shutdown.") # Tell z/VM to log off the system. parms = ["-T", rh.userid] smcliResults = invokeSMCLI(rh, "Image_Deactivate", parms) if smcliResults['overallRC'] == 0: pass elif (smcliResults['overallRC'] == 8 and smcliResults['rc'] == 200 and (smcliResults['rs'] == 12 or +smcliResults['rs'] == 16)): # Tolerable error. # Machine is already logged off or is logging off. rh.printLn("N", rh.userid + " is already logged off.") else: # SMAPI API failed. rh.printLn("ES", smcliResults['response']) rh.updateResults(smcliResults) # Use results from invokeSMCLI if rh.results['overallRC'] == 0 and 'maxQueries' in rh.parms: # Wait for the system to log off. waitResults = waitForVMState(rh, rh.userid, 'off', maxQueries=rh.parms['maxQueries'], sleepSecs=rh.parms['poll']) if waitResults['overallRC'] == 0: rh.printLn( "N", "Userid '" + rh.userid + " is in the desired state: off") else: rh.updateResults(waitResults) rh.printSysLog("Exit powerVM.softDeactivate, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def reset(rh): """ Reset a virtual machine. Input: Request Handle with the following properties: function - 'POWERVM' subfunction - 'RESET' userid - userid of the virtual machine parms['maxQueries'] - Maximum number of queries to issue. Optional. parms['maxWait'] - Maximum time to wait in seconds. Optional, unless 'maxQueries' is specified. parms['poll'] - Polling interval in seconds. Optional, unless 'maxQueries' is specified. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter powerVM.reset, userid: " + rh.userid) # Log off the user parms = ["-T", rh.userid] results = invokeSMCLI(rh, "Image_Deactivate", parms) if results['overallRC'] != 0: if results['rc'] == 200 and results['rs'] == 12: # Tolerated error. Machine is already in the desired state. results['overallRC'] = 0 results['rc'] = 0 results['rs'] = 0 else: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI # Wait for the logoff to complete if results['overallRC'] == 0: results = waitForVMState(rh, rh.userid, "off", maxQueries=30, sleepSecs=10) # Log the user back on if results['overallRC'] == 0: parms = ["-T", rh.userid] results = invokeSMCLI(rh, "Image_Activate", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI if results['overallRC'] == 0 and 'maxQueries' in rh.parms: if rh.parms['desiredState'] == 'up': results = waitForOSState(rh, rh.userid, rh.parms['desiredState'], maxQueries=rh.parms['maxQueries'], sleepSecs=rh.parms['poll']) else: results = waitForVMState(rh, rh.userid, rh.parms['desiredState'], maxQueries=rh.parms['maxQueries'], sleepSecs=rh.parms['poll']) if results['overallRC'] == 0: rh.printLn("N", rh.userid + ": " + rh.parms['desiredState']) else: rh.updateResults(results) rh.printSysLog("Exit powerVM.reset, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def addLOADDEV(rh): """ Sets the LOADDEV statement in the virtual machine's directory entry. Input: Request Handle with the following properties: function - 'CHANGEVM' subfunction - 'ADDLOADDEV' userid - userid of the virtual machine parms['boot'] - Boot program number parms['addr'] - Logical block address of the boot record parms['lun'] - One to eight-byte logical unit number of the FCP-I/O device. parms['wwpn'] - World-Wide Port Number parms['scpDataType'] - SCP data type parms['scpData'] - Designates information to be passed to the program is loaded during guest IPL. Note that any of the parms may be left blank, in which case we will not update them. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter changeVM.addLOADDEV") # scpDataType and scpData must appear or disappear concurrently if ('scpData' in rh.parms and 'scpDataType' not in rh.parms): msg = msgs.msg['0014'][1] % (modId, "scpData", "scpDataType") rh.printLn("ES", msg) rh.updateResults(msgs.msg['0014'][0]) return if ('scpDataType' in rh.parms and 'scpData' not in rh.parms): if rh.parms['scpDataType'].lower() == "delete": scpDataType = 1 else: # scpDataType and scpData must appear or disappear # concurrently unless we're deleting data msg = msgs.msg['0014'][1] % (modId, "scpDataType", "scpData") rh.printLn("ES", msg) rh.updateResults(msgs.msg['0014'][0]) return scpData = "" if 'scpDataType' in rh.parms: if rh.parms['scpDataType'].lower() == "hex": scpData = rh.parms['scpData'] scpDataType = 3 elif rh.parms['scpDataType'].lower() == "ebcdic": scpData = rh.parms['scpData'] scpDataType = 2 # scpDataType not hex, ebcdic or delete elif rh.parms['scpDataType'].lower() != "delete": msg = msgs.msg['0016'][1] % (modId, rh.parms['scpDataType']) rh.printLn("ES", msg) rh.updateResults(msgs.msg['0016'][0]) return else: # Not specified, 0 for do nothing scpDataType = 0 scpData = "" if 'boot' not in rh.parms: boot = "" else: boot = rh.parms['boot'] if 'addr' not in rh.parms: block = "" else: block = rh.parms['addr'] if 'lun' not in rh.parms: lun = "" else: lun = rh.parms['lun'] # Make sure it doesn't have the 0x prefix lun.replace("0x", "") if 'wwpn' not in rh.parms: wwpn = "" else: wwpn = rh.parms['wwpn'] # Make sure it doesn't have the 0x prefix wwpn.replace("0x", "") parms = [ "-T", rh.userid, "-b", boot, "-k", block, "-l", lun, "-p", wwpn, "-s", str(scpDataType) ] if scpData != "": parms.extend(["-d", scpData]) results = invokeSMCLI(rh, "Image_SCSI_Characteristics_Define_DM", parms) # SMAPI API failed. if results['overallRC'] != 0: rh.printLn("ES", results['response']) rh.updateResults(results) rh.printSysLog("Exit changeVM.addLOADDEV, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def getDiskPoolSpace(rh): """ Obtain disk pool space information for all or a specific disk pool. Input: Request Handle with the following properties: function - 'GETHOST' subfunction - 'DISKPOOLSPACE' parms['poolName'] - Name of the disk pool. Optional, if not present then information for all disk pools is obtained. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter getHost.getDiskPoolSpace") results = {'overallRC': 0} if 'poolName' not in rh.parms: poolNames = ["*"] else: if isinstance(rh.parms['poolName'], types.ListType): poolNames = rh.parms['poolName'] else: poolNames = [rh.parms['poolName']] if results['overallRC'] == 0: # Loop thru each pool getting total. Do it for query 2 & 3 totals = {} for qType in ["2", "3"]: parms = [ "-q", qType, "-e", "3", "-T", "DUMMY", "-n", " ".join(poolNames)] results = invokeSMCLI(rh, "Image_Volume_Space_Query_DM", parms) if results['overallRC'] == 0: for line in results['response'].splitlines(): parts = line.split() if len(parts) == 9: poolName = parts[7] else: poolName = parts[4] if poolName not in totals: totals[poolName] = {"2": 0., "3": 0.} if parts[1][:4] == "3390": totals[poolName][qType] += int(parts[3]) * 737280 elif parts[1][:4] == "9336": totals[poolName][qType] += int(parts[3]) * 512 else: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI break if results['overallRC'] == 0: if len(totals) == 0: # No pool information found. msg = msgs.msg['0402'][1] % (modId, " ".join(poolNames)) rh.printLn("ES", msg) rh.updateResults(msgs.msg['0402'][0]) else: # Produce a summary for each pool for poolName in sorted(totals): total = totals[poolName]["2"] + totals[poolName]["3"] rh.printLn("N", poolName + " Total: " + generalUtils.cvtToMag(rh, total)) rh.printLn("N", poolName + " Used: " + generalUtils.cvtToMag(rh, totals[poolName]["3"])) rh.printLn("N", poolName + " Free: " + generalUtils.cvtToMag(rh, totals[poolName]["2"])) rh.printSysLog("Exit getHost.getDiskPoolSpace, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def deleteMachine(rh): """ Delete a virtual machine from the user directory. Input: Request Handle with the following properties: function - 'DELETEVM' subfunction - 'DIRECTORY' userid - userid of the virtual machine to be deleted. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter deleteVM.deleteMachine") results = {'overallRC': 0, 'rc': 0, 'rs': 0} # Is image logged on ? state = 'on' # Assume 'on'. results = isLoggedOn(rh, rh.userid) if results['overallRC'] != 0: # Cannot determine the log on/off state. # Message already included. Act as if it is 'on'. pass elif results['rs'] == 0: # State is powered on. pass else: state = 'off' # Reset values for rest of subfunction results['overallRC'] = 0 results['rc'] = 0 results['rs'] = 0 if state == 'on': parms = ["-T", rh.userid, "-f IMMED"] results = invokeSMCLI(rh, "Image_Deactivate", parms) if results['overallRC'] == 0: pass elif (results['overallRC'] == 8 and results['rc'] == 200 and (results['rs'] == 12 or results['rs'] == 16)): # Tolerable error. Machine is already in or going into the state # that we want it to enter. rh.updateResults({}, reset=1) else: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results returned by invokeSMCLI if results['overallRC'] == 0: parms = ["-T", rh.userid, "-e", "0"] results = invokeSMCLI(rh, "Image_Delete_DM", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results returned by invokeSMCLI rh.printSysLog("Exit deleteVM.deleteMachine, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def getGeneralInfo(rh): """ Obtain general information about the host. Input: Request Handle with the following properties: function - 'GETHOST' subfunction - 'GENERAL' Output: Request Handle updated with the results. Return code - 0: ok Return code - 4: problem getting some info """ rh.printSysLog("Enter getHost.getGeneralInfo") # Get host using VMCP rh.results['overallRC'] = 0 cmd = ["/sbin/vmcp", "query userid"] strCmd = ' '.join(cmd) rh.printSysLog("Invoking: " + strCmd) try: host = subprocess.check_output( cmd, close_fds=True, stderr=subprocess.STDOUT).split()[2] except subprocess.CalledProcessError as e: msg = msgs.msg['0405'][1] % (modId, "Hypervisor Name", strCmd, e.output) rh.printLn("ES", msg) rh.updateResults(msgs.msg['0405'][0]) host = "no info" except Exception as e: # All other exceptions. rh.printLn("ES", msgs.msg['0421'][1] % (modId, strCmd, type(e).__name__, str(e))) rh.updateResults(msgs.msg['0421'][0]) host = "no info" # Get a bunch of info from /proc/sysinfo lparCpuTotal = "no info" lparCpuUsed = "no info" cecModel = "no info" cecVendor = "no info" hvInfo = "no info" with open('/proc/sysinfo', 'r') as myFile: for num, line in enumerate(myFile, 1): # Get total physical CPU in this LPAR if "LPAR CPUs Total" in line: lparCpuTotal = line.split()[3] # Get used physical CPU in this LPAR if "LPAR CPUs Configured" in line: lparCpuUsed = line.split()[3] # Get CEC model if "Type:" in line: cecModel = line.split()[1] # Get vendor of CEC if "Manufacturer:" in line: cecVendor = line.split()[1] # Get hypervisor type and version if "VM00 Control Program" in line: hvInfo = line.split()[3] + " " + line.split()[4] if lparCpuTotal == "no info": msg = msgs.msg['0405'][1] % (modId, "LPAR CPUs Total", "cat /proc/sysinfo", "not found") rh.printLn("ES", msg) rh.updateResults(msgs.msg['0405'][0]) if lparCpuUsed == "no info": msg = msgs.msg['0405'][1] % (modId, "LPAR CPUs Configured", "cat /proc/sysinfo", "not found") rh.printLn("ES", msg) rh.updateResults(msgs.msg['0405'][0]) if cecModel == "no info": msg = msgs.msg['0405'][1] % (modId, "Type:", "cat /proc/sysinfo", "not found") rh.printLn("ES", msg) rh.updateResults(msgs.msg['0405'][0]) if cecVendor == "no info": msg = msgs.msg['0405'][1] % (modId, "Manufacturer:", "cat /proc/sysinfo", "not found") rh.printLn("ES", msg) rh.updateResults(msgs.msg['0405'][0]) if hvInfo == "no info": msg = msgs.msg['0405'][1] % (modId, "VM00 Control Program", "cat /proc/sysinfo", "not found") rh.printLn("ES", msg) rh.updateResults(msgs.msg['0405'][0]) # Get processor architecture arch = str(os.uname()[4]) # Get LPAR memory total & offline parm = ["-T", "dummy", "-k", "STORAGE="] lparMemTotal = "no info" lparMemStandby = "no info" results = invokeSMCLI(rh, "System_Information_Query", parm) if results['overallRC'] == 0: for line in results['response'].splitlines(): if "STORAGE=" in line: lparMemOnline = line.split()[0] lparMemStandby = line.split()[4] lparMemTotal = lparMemOnline.split("=")[2] lparMemStandby = lparMemStandby.split("=")[1] else: # SMAPI API failed, so we put out messages # 300 and 405 for consistency rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI msg = msgs.msg['0405'][1] % (modId, "LPAR memory", "(see message 300)", results['response']) rh.printLn("ES", msg) # Get LPAR memory in use parm = ["-T", "dummy", "-k", "detailed_cpu=show=no"] lparMemUsed = "no info" results = invokeSMCLI(rh, "System_Performance_Information_Query", parm) if results['overallRC'] == 0: for line in results['response'].splitlines(): if "MEMORY_IN_USE=" in line: lparMemUsed = line.split("=")[1] lparMemUsed = generalUtils.getSizeFromPage(rh, lparMemUsed) else: # SMAPI API failed, so we put out messages # 300 and 405 for consistency rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI msg = msgs.msg['0405'][1] % (modId, "LPAR memory in use", "(see message 300)", results['response']) rh.printLn("ES", msg) # Get IPL Time ipl = "" cmd = ["/sbin/vmcp", "query cplevel"] strCmd = ' '.join(cmd) rh.printSysLog("Invoking: " + strCmd) try: ipl = subprocess.check_output( cmd, close_fds=True, stderr=subprocess.STDOUT).split("\n")[2] except subprocess.CalledProcessError as e: msg = msgs.msg['0405'][1] % (modId, "IPL Time", strCmd, e.output) rh.printLn("ES", msg) rh.updateResults(msgs.msg['0405'][0]) except Exception as e: # All other exceptions. rh.printLn("ES", msgs.msg['0421'][1] % (modId, strCmd, type(e).__name__, str(e))) rh.updateResults(msgs.msg['0421'][0]) # Create output string outstr = "z/VM Host: " + host outstr += "\nArchitecture: " + arch outstr += "\nCEC Vendor: " + cecVendor outstr += "\nCEC Model: " + cecModel outstr += "\nHypervisor OS: " + hvInfo outstr += "\nHypervisor Name: " + host outstr += "\nLPAR CPU Total: " + lparCpuTotal outstr += "\nLPAR CPU Used: " + lparCpuUsed outstr += "\nLPAR Memory Total: " + lparMemTotal outstr += "\nLPAR Memory Offline: " + lparMemStandby outstr += "\nLPAR Memory Used: " + lparMemUsed outstr += "\nIPL Time: " + ipl rh.printLn("N", outstr) rh.printSysLog("Exit getHost.getGeneralInfo, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def getConsole(rh): """ Get the virtual machine's console output. Input: Request Handle with the following properties: function - 'CMDVM' subfunction - 'CMD' userid - userid of the virtual machine Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter getVM.getConsole") # Transfer the console to this virtual machine. parms = ["-T", rh.userid] results = invokeSMCLI(rh, "Image_Console_Get", parms) if results['overallRC'] != 0: if (results['overallRC'] == 8 and results['rc'] == 8 and results['rs'] == 8): # Give a more specific message. Userid is either # not logged on or not spooling their console. msg = msgs.msg['0409'][1] % (modId, rh.userid) else: msg = results['response'] rh.updateResults(results) # Use results from invokeSMCLI rh.printLn("ES", msg) rh.printSysLog("Exit getVM.parseCmdLine, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC'] # Check whether the reader is online with open('/sys/bus/ccw/drivers/vmur/0.0.000c/online', 'r') as myfile: out = myfile.read().replace('\n', '') myfile.close() # Nope, offline, error out and exit if int(out) != 1: msg = msgs.msg['0411'][1] rh.printLn("ES", msg) rh.updateResults(msgs.msg['0411'][0]) rh.printSysLog("Exit getVM.parseCmdLine, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC'] # We should set class to *, otherwise we will get errors like: # vmur: Reader device class does not match spool file class cmd = ["/sbin/vmcp", "spool reader class *"] strCmd = ' '.join(cmd) rh.printSysLog("Invoking: " + strCmd) try: subprocess.check_output(cmd, close_fds=True, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: # If we couldn't change the class, that's not fatal # But we want to warn about possibly incomplete # results msg = msgs.msg['0407'][1] % (modId, strCmd, e.output) rh.printLn("WS", msg) except Exception as e: # All other exceptions. # If we couldn't change the class, that's not fatal # But we want to warn about possibly incomplete # results rh.printLn( "ES", msgs.msg['0422'][1] % (modId, strCmd, type(e).__name__, str(e))) rh.printLn("ES", msgs.msg['0423'][1] % modId, strCmd, type(e).__name__, str(e)) # List the spool files in the reader cmd = ["/usr/sbin/vmur", "list"] strCmd = ' '.join(cmd) rh.printSysLog("Invoking: " + strCmd) try: files = subprocess.check_output(cmd, close_fds=True, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: # Uh oh, vmur list command failed for some reason msg = msgs.msg['0408'][1] % (modId, rh.userid, strCmd, e.output) rh.printLn("ES", msg) rh.updateResults(msgs.msg['0408'][0]) rh.printSysLog("Exit getVM.parseCmdLine, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC'] except Exception as e: # All other exceptions. rh.printLn( "ES", msgs.msg['0421'][1] % (modId, strCmd, type(e).__name__, str(e))) rh.updateResults(msgs.msg['0421'][0]) rh.printSysLog("Exit getVM.parseCmdLine, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC'] # Now for each line that contains our user and is a # class T console file, add the spool id to our list spoolFiles = files.split('\n') outstr = "" for myfile in spoolFiles: if (myfile != "" and myfile.split()[0] == rh.userid and myfile.split()[2] == "T" and myfile.split()[3] == "CON"): fileId = myfile.split()[1] outstr += fileId + " " # No files in our list if outstr == "": msg = msgs.msg['0410'][1] % (modId, rh.userid) rh.printLn("ES", msg) rh.updateResults(msgs.msg['0410'][0]) rh.printSysLog("Exit getVM.parseCmdLine, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC'] # Output the list rh.printLn( "N", "List of spool files containing " "console logs from %s: %s" % (rh.userid, outstr)) rh.results['overallRC'] = 0 rh.printSysLog("Exit getVM.getConsole, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']
def moveVM(rh): """ Initiate a VMRelocate request to move a userid. Input: Request Handle with the following properties: function - 'MIGRATEVM' subfunction - 'MOVE' userid - userid of the virtual machine parms['destination'] - target SSI member parms['forcearch'] - if present, force=architecture is set. parms['forcedomain'] - if present, force=domain is set. parms['forcestorage'] - if present, force=storage is set. parms['immediate'] - if present, immediate=YES is set. parms['maxquiesce'] - maximum quiesce time in seconds, or -1 to indicate no limit. parms['maxTotal'] - maximum total time in seconds, or -1 to indicate no limit. Output: Request Handle updated with the results. Return code - 0: ok, non-zero: error """ rh.printSysLog("Enter migrateVM.moveVM") parms = ["-T", rh.userid, "-k", "action=MOVE"] if 'dest' in rh.parms: parms.extend(["-k", "destination=" + rh.parms['dest']]) forceOption = '' if 'forcearch' in rh.parms: forceOption = "ARCHITECTURE " if 'forcedomain' in rh.parms: forceOption = forceOption + "DOMAIN " if 'forcestorage' in rh.parms: forceOption = forceOption + "STORAGE " if forceOption != '': parms.extend(["-k", "\'force=" + forceOption + "\'"]) if 'immediate' in rh.parms: parms.extend(["-k", "\'immediate=YES"]) if 'maxQuiesce' in rh.parms: if rh.parms['maxQuiesce'] == -1: parms.extend(["-k", "max_quiesce=NOLIMIT"]) else: parms.extend(["-k", "max_quiesce=" + str(rh.parms['maxQuiesce'])]) if 'maxTotal' in rh.parms: if rh.parms['maxTotal'] == -1: parms.extend(["-k", "max_total=NOLIMIT"]) else: parms.extend(["-k", "max_total=" + str(rh.parms['maxTotal'])]) results = invokeSMCLI(rh, "VMRELOCATE", parms) if results['overallRC'] != 0: # SMAPI API failed. rh.printLn("ES", results['response']) rh.updateResults(results) # Use results from invokeSMCLI if results['rc'] == 8 and results['rs'] == 3000: if "0045" in results['response']: # User not logged on msg = msgs.msg['0418'][1] % (modId, rh.userid) rh.printLn("ES", msg) rh.updateResults(msgs.msg['0418'][0]) else: # More details in message codes lines = results['response'].split("\n") for line in lines: if "Details:" in line: codes = line.split(' ', 1)[1] msg = msgs.msg['0420'][1] % (modId, "VMRELOCATE Move", rh.userid, codes) rh.printLn("ES", msg) rh.printSysLog("Exit migrateVM.moveVM, rc: " + str(rh.results['overallRC'])) return rh.results['overallRC']