예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
    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
예제 #6
0
    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)
예제 #7
0
    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
예제 #8
0
    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)
예제 #9
0
    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
예제 #10
0
    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)