def scan_pkg_filename(self, rpm): """ Determine what the distro is based on the release package filename. """ rpm_file = os.path.basename(rpm) if rpm_file.lower().find("-esx-") != -1: flavor = "esx" match = re.search(r'release-(\d)+-(\d)+\.(\d)+\.(\d)+-(\d)\.', rpm_file) if match: major = match.group(2) minor = match.group(3) release = match.group(4) update = match.group(5) else: # FIXME: what should we do if the re fails above? return None elif rpm_file.lower() == "vmkernel.gz": flavor = "esxi" major = 0 minor = 0 release = 0 update = 0 # this should return something like: # VMware ESXi 4.1.0 [Releasebuild-260247], built on May 18 2010 # though there will most likely be multiple results scan_cmd = 'gunzip -c %s | strings | grep -i "^vmware esxi"' % rpm (data, rc) = utils.subprocess_sp(self.logger, scan_cmd) lines = data.split('\n') m = re.compile( r'ESXi (\d)+\.(\d)+\.(\d)+ \[Releasebuild-([\d]+)\]') for line in lines: match = m.search(line) if match: major = match.group(1) minor = match.group(2) release = match.group(3) update = match.group(4) break else: return None #self.logger.info("DEBUG: in scan_pkg_filename() - major=%s, minor=%s, release=%s, update=%s" % (major,minor,release,update)) return (flavor, major, minor, release, update)
def scan_pkg_filename(self, rpm): """ Determine what the distro is based on the release package filename. """ rpm_file = os.path.basename(rpm) if rpm_file.lower().find("-esx-") != -1: flavor = "esx" match = re.search(r"release-(\d)+-(\d)+\.(\d)+\.(\d)+-(\d)\.", rpm_file) if match: major = match.group(2) minor = match.group(3) release = match.group(4) update = match.group(5) else: # FIXME: what should we do if the re fails above? return None elif rpm_file.lower() == "vmkernel.gz": flavor = "esxi" major = 0 minor = 0 release = 0 update = 0 # this should return something like: # VMware ESXi 4.1.0 [Releasebuild-260247], built on May 18 2010 # though there will most likely be multiple results scan_cmd = 'gunzip -c %s | strings | grep -i "^vmware esxi"' % rpm (data, rc) = utils.subprocess_sp(self.logger, scan_cmd) lines = data.split("\n") m = re.compile(r"ESXi (\d)+\.(\d)+\.(\d)+ \[Releasebuild-([\d]+)\]") for line in lines: match = m.search(line) if match: major = match.group(1) minor = match.group(2) release = match.group(3) update = match.group(4) break else: return None # self.logger.info("DEBUG: in scan_pkg_filename() - major=%s, minor=%s, release=%s, update=%s" % (major,minor,release,update)) return (flavor, major, minor, release, update)
def power(self, desired_state): """ state is either "on" or "off". Rebooting is implemented at the api.py level. The user and password need not be supplied. If not supplied they will be taken from the environment, COBBLER_POWER_USER and COBBLER_POWER_PASS. If provided, these will override any other data and be used instead. Users interested in maximum security should take that route. """ template = self.get_command_template() template_file = open(template, "r") meta = utils.blender(self.api, False, self.system) meta["power_mode"] = desired_state # allow command line overrides of the username/password if self.force_user is not None: meta["power_user"] = self.force_user if self.force_pass is not None: meta["power_pass"] = self.force_pass tmp = templar.Templar(self.api._config) cmd = tmp.render(template_file, meta, None, self.system) template_file.close() cmd = cmd.strip() self.logger.info("cobbler power configuration is:") self.logger.info(" type : %s" % self.system.power_type) self.logger.info(" address: %s" % self.system.power_address) self.logger.info(" user : %s" % self.system.power_user) self.logger.info(" id : %s" % self.system.power_id) # if no username/password data, check the environment if meta.get("power_user", "") == "": meta["power_user"] = os.environ.get("COBBLER_POWER_USER", "") if meta.get("power_pass", "") == "": meta["power_pass"] = os.environ.get("COBBLER_POWER_PASS", "") self.logger.info("- %s" % cmd) # use shell so we can have mutliple power commands chained together cmd = ['/bin/sh', '-c', cmd] # Try the power command 5 times before giving up. # Some power switches are flakey for x in range(0, 5): output, rc = utils.subprocess_sp(self.logger, cmd, shell=False) if rc == 0: # If the desired state is actually a query for the status # return different information than command return code if desired_state == 'status': match = re.match('(^Status:\s)(ON|OFF)', output) if match: power_status = match.groups()[1] if power_status == 'ON': return True else: return False utils.die( self.logger, "command succeeded (rc=%s), but output ('%s') was not understood" % (rc, output)) return None break else: time.sleep(2) if not rc == 0: utils.die( self.logger, "command failed (rc=%s), please validate the physical setup and cobbler config" % rc) return rc
def power(self, desired_state): """ state is either "on" or "off". Rebooting is implemented at the api.py level. The user and password need not be supplied. If not supplied they will be taken from the environment, COBBLER_POWER_USER and COBBLER_POWER_PASS. If provided, these will override any other data and be used instead. Users interested in maximum security should take that route. """ template = self.get_command_template() template_file = open(template, "r") meta = utils.blender(self.api, False, self.system) meta["power_mode"] = desired_state # allow command line overrides of the username/password if self.force_user is not None: meta["power_user"] = self.force_user if self.force_pass is not None: meta["power_pass"] = self.force_pass tmp = templar.Templar(self.api._config) cmd = tmp.render(template_file, meta, None, self.system) template_file.close() cmd = cmd.strip() self.logger.info("cobbler power configuration is:") self.logger.info(" type : %s" % self.system.power_type) self.logger.info(" address: %s" % self.system.power_address) self.logger.info(" user : %s" % self.system.power_user) self.logger.info(" id : %s" % self.system.power_id) # if no username/password data, check the environment if meta.get("power_user","") == "": meta["power_user"] = os.environ.get("COBBLER_POWER_USER","") if meta.get("power_pass","") == "": meta["power_pass"] = os.environ.get("COBBLER_POWER_PASS","") self.logger.info("- %s" % cmd) # use shell so we can have mutliple power commands chained together cmd = ['/bin/sh','-c', cmd] # Try the power command 5 times before giving up. # Some power switches are flakey for x in range(0,5): output, rc = utils.subprocess_sp(self.logger, cmd, shell=False) if rc == 0: # If the desired state is actually a query for the status # return different information than command return code if desired_state == 'status': match = re.match('(^Status:\s)(ON|OFF)', output) if match: power_status = match.groups()[1] if power_status == 'ON': return True else: return False utils.die(self.logger,"command succeeded (rc=%s), but output ('%s') was not understood" % (rc, output)) return None break else: time.sleep(2) if not rc == 0: utils.die(self.logger,"command failed (rc=%s), please validate the physical setup and cobbler config" % rc) return rc
def power(self, desired_state): """ state is either "on" or "off". Rebooting is implemented at the api.py level. The user and password need not be supplied. If not supplied they will be taken from the environment, COBBLER_POWER_USER and COBBLER_POWER_PASS. If provided, these will override any other data and be used instead. Users interested in maximum security should take that route. """ power_command = utils.get_power(self.system.power_type) if not power_command: utils.die(self.logger, "no power type set for system") meta = utils.blender(self.api, False, self.system) meta["power_mode"] = desired_state # allow command line overrides of the username/password if self.force_user is not None: meta["power_user"] = self.force_user if self.force_pass is not None: meta["power_pass"] = self.force_pass self.logger.info("cobbler power configuration is:") self.logger.info(" type : %s" % self.system.power_type) self.logger.info(" address: %s" % self.system.power_address) self.logger.info(" user : %s" % self.system.power_user) self.logger.info(" id : %s" % self.system.power_id) # if no username/password data, check the environment if meta.get("power_user", "") == "": meta["power_user"] = os.environ.get("COBBLER_POWER_USER", "") if meta.get("power_pass", "") == "": meta["power_pass"] = os.environ.get("COBBLER_POWER_PASS", "") template = utils.get_power_template(self.system.power_type) tmp = templar.Templar(self.api._config) template_data = tmp.render(template, meta, None, self.system) # Try the power command 5 times before giving up. # Some power switches are flakey for x in range(0, 5): output, rc = utils.subprocess_sp(self.logger, power_command, shell=False, input=template_data) if rc == 0: # If the desired state is actually a query for the status # return different information than command return code if desired_state == 'status': match = re.match('^(Status:|.+power\s=)\s(on|off)$', output, re.IGNORECASE | re.MULTILINE) if match: power_status = match.groups()[1] if power_status.lower() == 'on': return True else: return False utils.die(self.logger, "command succeeded (rc=%s), but output ('%s') was not understood" % (rc, output)) return None break else: time.sleep(2) if not rc == 0: utils.die(self.logger, "command failed (rc=%s), please validate the physical setup and cobbler config" % rc) return rc
def _power(self, system, power_operation, user=None, password=None, logger=None): """ Performs a power operation on a system. Internal method @param System system Cobbler system @param str power_operation power operation. Valid values: on, off, status. Rebooting is implemented as a set of 2 operations (off and on) in a higher level method. @param str user power management user. If user and password are not supplied, environment variables COBBLER_POWER_USER and COBBLER_POWER_PASS will be used. @param str password power management password @param Logger logger logger @return bool/None if power operation is 'status', return if system is on; otherwise, return None @raise CX if there are errors """ if logger is None: logger = self.logger power_command = get_power_command(system.power_type) if not power_command: utils.die(logger, "no power type set for system") meta = utils.blender(self.api, False, system) meta["power_mode"] = power_operation # allow command line overrides of the username/password if user is not None: meta["power_user"] = user if password is not None: meta["power_pass"] = password logger.info("cobbler power configuration is:") logger.info(" type : %s" % system.power_type) logger.info(" address: %s" % system.power_address) logger.info(" user : %s" % system.power_user) logger.info(" id : %s" % system.power_id) # if no username/password data, check the environment if meta.get("power_user", "") == "": meta["power_user"] = os.environ.get("COBBLER_POWER_USER", "") if meta.get("power_pass", "") == "": meta["power_pass"] = os.environ.get("COBBLER_POWER_PASS", "") template = get_power_template(system.power_type) tmp = templar.Templar(self.collection_mgr) template_data = tmp.render(template, meta, None, system) logger.info("power command: %s" % power_command) logger.info("power command input: %s" % template_data) # Try the power command 5 times before giving up. # Some power switches are flakey for x in range(0, 5): output, rc = utils.subprocess_sp(logger, power_command, shell=False, input=template_data) if rc == 0: # If the desired state is actually a query for the status # return different information than command return code if power_operation == 'status': match = re.match('^(Status:|.+power\s=)\s(on|off)$', output, re.IGNORECASE | re.MULTILINE) if match: power_status = match.groups()[1] if power_status.lower() == 'on': return True else: return False error_msg = "command succeeded (rc=%s), but output ('%s') was not understood" % ( rc, output) utils.die(logger, error_msg) raise CX(error_msg) return None else: time.sleep(2) if not rc == 0: error_msg = "command failed (rc=%s), please validate the physical setup and cobbler config" % rc utils.die(logger, error_msg) raise CX(error_msg)
def scan_pkg_filename(self, filename): """ Determine what the distro is based on the release package filename. """ file_base_name = os.path.basename(filename) success = False if file_base_name.lower().find("-esx-") != -1: flavor = "esx" match = re.search(r'release-(\d)+-(\d)+\.(\d)+\.(\d)+-(\d)\.', filename) if match: major = match.group(2) minor = match.group(3) release = match.group(4) update = match.group(5) success = True elif file_base_name.lower() == "vmkernel.gz": flavor = "esxi" major = 0 minor = 0 release = 0 update = 0 # this should return something like: # VMware ESXi 4.1.0 [Releasebuild-260247], built on May 18 2010 # though there will most likely be multiple results scan_cmd = 'gunzip -c %s | strings | grep -i "^vmware esxi"' % filename (data,rc) = utils.subprocess_sp(None, scan_cmd) lines = data.split('\n') m = re.compile(r'ESXi (\d)+\.(\d)+\.(\d)+ \[Releasebuild-([\d]+)\]') for line in lines: match = m.search(line) if match: major = match.group(1) minor = match.group(2) release = match.group(3) update = match.group(4) success = True break elif file_base_name.lower() == "s.v00": flavor = "esxi" major = 0 minor = 0 release = 0 update = 0 # this should return something like: # VMware ESXi 5.0.0 build-469512 # though there will most likely be multiple results scan_cmd = 'gunzip -c %s | strings | grep -i "^# vmware esxi"' % filename (data,rc) = utils.subprocess_sp(None, scan_cmd) lines = data.split('\n') m = re.compile(r'ESXi (\d)+\.(\d)+\.(\d)+[ ]+build-([\d]+)') for line in lines: match = m.search(line) if match: major = match.group(1) minor = match.group(2) release = match.group(3) update = match.group(4) success = True break if success: return (flavor, major, minor, release, update) else: return None
def power(self, desired_state): """ state is either "on" or "off". Rebooting is implemented at the api.py level. The user and password need not be supplied. If not supplied they will be taken from the environment, COBBLER_POWER_USER and COBBLER_POWER_PASS. If provided, these will override any other data and be used instead. Users interested in maximum security should take that route. """ power_command = utils.get_power(self.system.power_type) if not power_command: utils.die(self.logger, "no power type set for system") meta = utils.blender(self.api, False, self.system) meta["power_mode"] = desired_state # allow command line overrides of the username/password if self.force_user is not None: meta["power_user"] = self.force_user if self.force_pass is not None: meta["power_pass"] = self.force_pass self.logger.info("cobbler power configuration is:") self.logger.info(" type : %s" % self.system.power_type) self.logger.info(" address: %s" % self.system.power_address) self.logger.info(" user : %s" % self.system.power_user) self.logger.info(" id : %s" % self.system.power_id) # if no username/password data, check the environment if meta.get("power_user", "") == "": meta["power_user"] = os.environ.get("COBBLER_POWER_USER", "") if meta.get("power_pass", "") == "": meta["power_pass"] = os.environ.get("COBBLER_POWER_PASS", "") template = utils.get_power_template(self.system.power_type) tmp = templar.Templar(self.api._collection_mgr) template_data = tmp.render(template, meta, None, self.system) # Try the power command 5 times before giving up. # Some power switches are flakey for x in range(0, 5): output, rc = utils.subprocess_sp(self.logger, power_command, shell=False, input=template_data) if rc == 0: # If the desired state is actually a query for the status # return different information than command return code if desired_state == 'status': match = re.match('^(Status:|.+power\s=)\s(on|off)$', output, re.IGNORECASE | re.MULTILINE) if match: power_status = match.groups()[1] if power_status.lower() == 'on': return True else: return False error_msg = "command succeeded (rc=%s), but output ('%s') was not understood" % (rc, output) utils.die(self.logger, error_msg) raise CX(error_msg) return None else: time.sleep(2) if not rc == 0: error_msg = "command failed (rc=%s), please validate the physical setup and cobbler config" % rc utils.die(self.logger, error_msg) raise CX(error_msg)
def scan_pkg_filename(self, filename): """ Determine what the distro is based on the release package filename. """ file_base_name = os.path.basename(filename) success = False if file_base_name.lower().find("-esx-") != -1: flavor = "esx" match = re.search(r'release-(\d)+-(\d)+\.(\d)+\.(\d)+-(\d)\.', filename) if match: major = match.group(2) minor = match.group(3) release = match.group(4) update = match.group(5) success = True elif file_base_name.lower() == "vmkernel.gz": flavor = "esxi" major = 0 minor = 0 release = 0 update = 0 # this should return something like: # VMware ESXi 4.1.0 [Releasebuild-260247], built on May 18 2010 # though there will most likely be multiple results scan_cmd = 'gunzip -c %s | strings | grep -i "^vmware esxi"' % filename (data, rc) = utils.subprocess_sp(None, scan_cmd) lines = data.split('\n') m = re.compile( r'ESXi (\d)+\.(\d)+\.(\d)+ \[Releasebuild-([\d]+)\]') for line in lines: match = m.search(line) if match: major = match.group(1) minor = match.group(2) release = match.group(3) update = match.group(4) success = True break elif file_base_name.lower() == "s.v00": flavor = "esxi" major = 0 minor = 0 release = 0 update = 0 # this should return something like: # VMware ESXi 5.0.0 build-469512 # though there will most likely be multiple results scan_cmd = 'gunzip -c %s | strings | grep -i "^# vmware esxi"' % filename (data, rc) = utils.subprocess_sp(None, scan_cmd) lines = data.split('\n') m = re.compile(r'ESXi (\d)+\.(\d)+\.(\d)+[ ]+build-([\d]+)') for line in lines: match = m.search(line) if match: major = match.group(1) minor = match.group(2) release = match.group(3) update = match.group(4) success = True break if success: return (flavor, major, minor, release, update) else: return None
def _power(self, system, power_operation, user=None, password=None, logger=None): """ Performs a power operation on a system. Internal method @param System system Cobbler system @param str power_operation power operation. Valid values: on, off, status. Rebooting is implemented as a set of 2 operations (off and on) in a higher level method. @param str user power management user. If user and password are not supplied, environment variables COBBLER_POWER_USER and COBBLER_POWER_PASS will be used. @param str password power management password @param Logger logger logger @return bool/None if power operation is 'status', return if system is on; otherwise, return None @raise CX if there are errors """ if logger is None: logger = self.logger power_command = get_power_command(system.power_type) if not power_command: utils.die(logger, "no power type set for system") meta = utils.blender(self.api, False, system) meta["power_mode"] = power_operation # allow command line overrides of the username/password if user is not None: meta["power_user"] = user if password is not None: meta["power_pass"] = password logger.info("cobbler power configuration is:") logger.info(" type : %s" % system.power_type) logger.info(" address: %s" % system.power_address) logger.info(" user : %s" % system.power_user) logger.info(" id : %s" % system.power_id) # if no username/password data, check the environment if meta.get("power_user", "") == "": meta["power_user"] = os.environ.get("COBBLER_POWER_USER", "") if meta.get("power_pass", "") == "": meta["power_pass"] = os.environ.get("COBBLER_POWER_PASS", "") template = self.get_power_template(system.power_type) tmp = templar.Templar(self.collection_mgr) template_data = tmp.render(template, meta, None, system) logger.info("power command: %s" % power_command) logger.info("power command input: %s" % template_data) # Try the power command 5 times before giving up. # Some power switches are flakey for x in range(0, 5): output, rc = utils.subprocess_sp(logger, power_command, shell=False, input=template_data) if rc == 0: # If the desired state is actually a query for the status # return different information than command return code if power_operation == 'status': match = re.match('^(Status:|.+power\s=)\s(on|off)$', output, re.IGNORECASE | re.MULTILINE) if match: power_status = match.groups()[1] if power_status.lower() == 'on': return True else: return False error_msg = "command succeeded (rc=%s), but output ('%s') was not understood" % (rc, output) utils.die(logger, error_msg) raise CX(error_msg) return None else: time.sleep(2) if not rc == 0: error_msg = "command failed (rc=%s), please validate the physical setup and cobbler config" % rc utils.die(logger, error_msg) raise CX(error_msg)