Ejemplo n.º 1
0
 def _check_requires(self, element, cluster_data=None):
     """
     Validate a requires element, raising excError if the requirement is
     not met.
     """
     if element is None:
         return
     if element == "impossible":
         raise ex.excContinueAction("skip impossible requirement")
     if element.count("(") == 1:
         rid, states = element.rstrip(")").split("(")
         states = states.split(",")
     else:
         rid = element
         states = ["up", "stdby up"]
     if rid not in self.svc.resources_by_id:
         self.log.warning("ignore requires on %s: resource not found", rid)
         return
     if cluster_data:
         try:
             current_state = cluster_data[rcEnv.nodename]["services"][
                 "status"][self.svc.path]["resources"][rid]["status"]
         except KeyError:
             current_state = "undef"
     else:
         resource = self.svc.resources_by_id[rid]
         current_state = rcStatus.Status(resource.status())
     if current_state not in states:
         msg = "requires on resource %s in state %s, current state %s" % \
               (rid, " or ".join(states), current_state)
         if self.svc.options.cron:
             raise ex.excContinueAction(msg)
         else:
             raise ex.excError(msg)
Ejemplo n.º 2
0
    def load_status_last(self, refresh=False):
        """
        Fetch the resource status from the on-disk cache.
        """
        try:
            with open(self.fpath_status_last, 'r') as ofile:
                data = json.load(ofile)
        except ValueError:
            return rcStatus.UNDEF
        except (OSError, IOError) as exc:
            if exc.errno != 2:
                # not EEXISTS
                self.log.debug(exc)
            return rcStatus.UNDEF

        try:
            status = rcStatus.Status(data["status"])
        except (IndexError, AttributeError, ValueError) as exc:
            self.log.debug(exc)
            return rcStatus.UNDEF

        if not refresh and hasattr(self, "set_label"):
            if hasattr(self, "_lazy_label"):
                attr = "_lazy_label"
            else:
                attr = "label"
            try:
                setattr(self, attr, data["label"])
            except (IndexError, AttributeError, ValueError) as exc:
                pass

        self.status_logs = data.get("log", [])

        return status
Ejemplo n.º 3
0
 def write_status_history(self):
     """
     Log a change to the resource status history file.
     """
     fpath = self.fpath_status_history
     try:
         with open(fpath, 'r') as ofile:
             lines = ofile.readlines()
             last = lines[-1].split(" | ")[-1].strip("\n")
     except:
         last = None
     current = rcStatus.Status(self.rstatus)
     if current == last:
         return
     log = logging.getLogger("status_history")
     logformatter = logging.Formatter("%(asctime)s | %(message)s")
     logfilehandler = logging.handlers.RotatingFileHandler(
         fpath,
         maxBytes=512000,
         backupCount=1,
     )
     logfilehandler.setFormatter(logformatter)
     log.addHandler(logfilehandler)
     log.error(current)
     logfilehandler.close()
     log.removeHandler(logfilehandler)
Ejemplo n.º 4
0
 def _status(self, verbose=False):
     self.data_status()
     if not self.volsvc.exists():
         self.status_log("volume %s does not exist" % self.volname, "info")
         return rcStatus.DOWN
     status = rcStatus.Status(self.volsvc.print_status_data()["avail"])
     if not self.flag_installed():
         self.status_log("%s is %s" % (self.volsvc.path, status), "info")
         return rcStatus.DOWN
     return status
Ejemplo n.º 5
0
    def status(self, **kwargs):
        """
        Resource status evaluation method wrapper.
        Handles caching, nostatus tag and disabled flag.
        """
        verbose = kwargs.get("verbose", False)
        refresh = kwargs.get("refresh", False)
        ignore_nostatus = kwargs.get("ignore_nostatus", False)

        if self.is_disabled():
            return rcStatus.NA

        if not ignore_nostatus and "nostatus" in self.tags:
            self.status_log("nostatus tag", "info")
            return rcStatus.NA

        if self.rstatus is not None and not refresh:
            return self.rstatus

        last_status = self.load_status_last(refresh)

        if refresh:
            self.purge_status_last()
        else:
            self.rstatus = last_status

        # now the rstatus can no longer be None
        if self.rstatus == rcStatus.UNDEF or refresh:
            self.status_logs = []
            self.rstatus = self.try_status(verbose)
            self.rstatus = self.status_stdby(self.rstatus)
            self.log.debug("refresh status: %s => %s",
                           rcStatus.Status(last_status),
                           rcStatus.Status(self.rstatus))
            self.write_status()

        if self.rstatus in (rcStatus.UP, rcStatus.STDBY_UP) and \
           self.is_provisioned_flag() is False:
            self.write_is_provisioned_flag(True)

        return self.rstatus
Ejemplo n.º 6
0
 def write_status_last(self):
     """
     Write the in-memory resource status to the on-disk cache.
     """
     data = {
         "status": str(rcStatus.Status(self.rstatus)),
         "label": self.label,
         "log": self.status_logs,
     }
     dpath = os.path.dirname(self.fpath_status_last)
     if not os.path.exists(dpath):
         os.makedirs(dpath, 0o0755)
     with open(self.fpath_status_last, 'w') as ofile:
         json.dump(data, ofile)
         ofile.flush()
Ejemplo n.º 7
0
 def checkreserv(self):
     self.log.debug("starting checkreserv. prkey %s"%self.hostid)
     if self.ack_all_unit_attention() != 0:
         return rcStatus.WARN
     r = rcStatus.Status()
     for d in self.devs:
         try:
             key = self.get_reservation_key(d) # pylint: disable=assignment-from-none
             if key is None:
                 self.log.debug("disk %s is not reserved" % d)
                 r += rcStatus.DOWN
             elif key != self.hostid:
                 self.log.debug("disk %s is reserved by another host whose key is %s" % (d, key))
                 r += rcStatus.DOWN
             else:
                 self.log.debug("disk %s is correctly reserved" % d)
                 r += rcStatus.UP
         except ex.excScsiPrNotsupported as exc:
             self.log.warning(str(exc))
             continue
     return r.status
Ejemplo n.º 8
0
    def status(self, **kwargs):
        """
        Return the aggregate status a ResourceSet.
        """
        agg_status = rcStatus.Status()
        for resource in self.resources:
            if resource.is_disabled():
                continue
            if not self.svc.encap and resource.encap:
                # don't evaluate encap service resources
                continue

            try:
                status = resource.status(**kwargs)
            except:
                import traceback
                exc = sys.exc_info()
                print(exc[0], exc[1], traceback.print_tb(exc[2]))
                status = rcStatus.NA

            agg_status += status
        return agg_status.status
Ejemplo n.º 9
0
    def docker_start(self, verbose=True):
        """
        Start the docker daemon if in private mode and not already running.
        """
        if not self.docker_daemon_private:
            return
        if self.docker_cmd is None:
            raise ex.excError("docker executable not found")
        import lock
        lockfile = os.path.join(self.svc.var_d, "lock.docker_start")
        try:
            lockfd = lock.lock(timeout=15, delay=1, lockfile=lockfile)
        except lock.LOCK_EXCEPTIONS as exc:
            self.svc.log.error("dockerd start lock acquire failed: %s",
                               str(exc))
            return

        # Sanity checks before deciding to start the daemon
        if self.docker_running():
            lock.unlock(lockfd)
            return

        if self.container_data_dir is None:
            lock.unlock(lockfd)
            return

        resource = self._container_data_dir_resource()
        if resource is not None:
            state = resource._status()
            if state not in (rcStatus.UP, rcStatus.STDBY_UP):
                self.svc.log.warning(
                    "the docker daemon data dir is handled by the %s "
                    "resource in %s state. can't start the docker "
                    "daemon", resource.rid, rcStatus.Status(state))
                lock.unlock(lockfd)
                return

        if os.path.exists(self.docker_pid_file):
            self.svc.log.warning("removing leftover pid file %s",
                                 self.docker_pid_file)
            os.unlink(self.docker_pid_file)

        # Now we can start the daemon, creating its data dir if necessary
        cmd = self.dockerd_cmd

        if verbose:
            self.svc.log.info("starting docker daemon")
            self.svc.log.info(" ".join(cmd))
        import subprocess
        subprocess.Popen(
            ["nohup"] + cmd,
            stdout=open("/dev/null", "w"),
            stderr=open("/dev/null", "a"),
            preexec_fn=os.setpgrp,
            close_fds=True,
        )

        import time
        try:
            for _ in range(self.max_wait_for_dockerd):
                if self._docker_working():
                    self.clear_daemon_caches()
                    return
                time.sleep(1)
        finally:
            lock.unlock(lockfd)