PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/at.py |
""" Wrapper module for at(1) Also, a 'tag' feature has been added to more easily tag jobs. :platform: linux,openbsd,freebsd .. versionchanged:: 2017.7.0 """ import datetime import re import time import salt.utils.data import salt.utils.path import salt.utils.platform # pylint: enable=import-error,redefined-builtin from salt.exceptions import CommandNotFoundError # pylint: disable=import-error,redefined-builtin # OS Families that should work (Ubuntu and Debian are the default) # TODO: Refactor some of this module to remove the checks for binaries # Tested on OpenBSD 5.0 BSD = ("OpenBSD", "FreeBSD") __virtualname__ = "at" def __virtual__(): """ Most everything has the ability to support at(1) """ if salt.utils.platform.is_windows() or salt.utils.platform.is_sunos(): return (False, "The at module could not be loaded: unsupported platform") if salt.utils.path.which("at") is None: return (False, "The at module could not be loaded: at command not found") return __virtualname__ def _cmd(binary, *args): """ Wrapper to run at(1) or return None. """ binary = salt.utils.path.which(binary) if not binary: raise CommandNotFoundError(f"{binary}: command not found") cmd = [binary] + list(args) return __salt__["cmd.run_stdout"]([binary] + list(args), python_shell=False) def atq(tag=None): """ List all queued and running jobs or only those with an optional 'tag'. CLI Example: .. code-block:: bash salt '*' at.atq salt '*' at.atq [tag] salt '*' at.atq [job number] """ jobs = [] # Shim to produce output similar to what __virtual__() should do # but __salt__ isn't available in __virtual__() # Tested on CentOS 5.8 if __grains__["os_family"] == "RedHat": output = _cmd("at", "-l") else: output = _cmd("atq") if output is None: return "'at.atq' is not available." # No jobs so return if output == "": return {"jobs": jobs} # Jobs created with at.at() will use the following # comment to denote a tagged job. job_kw_regex = re.compile(r"^### SALT: (\w+)") # Split each job into a dictionary and handle # pulling out tags or only listing jobs with a certain # tag for line in output.splitlines(): job_tag = "" # Redhat/CentOS if __grains__["os_family"] == "RedHat": job, spec = line.split("\t") specs = spec.split() elif __grains__["os"] == "OpenBSD": if line.startswith(" Rank"): continue else: tmp = line.split() timestr = " ".join(tmp[1:5]) job = tmp[6] specs = ( datetime.datetime(*(time.strptime(timestr, "%b %d, %Y %H:%M")[0:5])) .isoformat() .split("T") ) specs.append(tmp[7]) specs.append(tmp[5]) elif __grains__["os"] == "FreeBSD": if line.startswith("Date"): continue else: tmp = line.split() timestr = " ".join(tmp[1:6]) job = tmp[8] specs = ( datetime.datetime( *(time.strptime(timestr, "%b %d %H:%M:%S %Z %Y")[0:5]) ) .isoformat() .split("T") ) specs.append(tmp[7]) specs.append(tmp[6]) else: job, spec = line.split("\t") tmp = spec.split() timestr = " ".join(tmp[0:5]) specs = ( datetime.datetime(*(time.strptime(timestr)[0:5])).isoformat().split("T") ) specs.append(tmp[5]) specs.append(tmp[6]) # Search for any tags atc_out = _cmd("at", "-c", job) for line in atc_out.splitlines(): tmp = job_kw_regex.match(line) if tmp: job_tag = tmp.groups()[0] if __grains__["os"] in BSD: job = str(job) else: job = int(job) # If a tag is supplied, only list jobs with that tag if tag: # TODO: Looks like there is a difference between salt and salt-call # If I don't wrap job in an int(), it fails on salt but works on # salt-call. With the int(), it fails with salt-call but not salt. if tag == job_tag or tag == job: jobs.append( { "job": job, "date": specs[0], "time": specs[1], "queue": specs[2], "user": specs[3], "tag": job_tag, } ) else: jobs.append( { "job": job, "date": specs[0], "time": specs[1], "queue": specs[2], "user": specs[3], "tag": job_tag, } ) return {"jobs": jobs} def atrm(*args): """ Remove jobs from the queue. CLI Example: .. code-block:: bash salt '*' at.atrm <jobid> <jobid> .. <jobid> salt '*' at.atrm all salt '*' at.atrm all [tag] """ # Need to do this here also since we use atq() if not salt.utils.path.which("at"): return "'at.atrm' is not available." if not args: return {"jobs": {"removed": [], "tag": None}} # Convert all to strings args = salt.utils.data.stringify(args) if args[0] == "all": if len(args) > 1: opts = list(list(map(str, [j["job"] for j in atq(args[1])["jobs"]]))) ret = {"jobs": {"removed": opts, "tag": args[1]}} else: opts = list(list(map(str, [j["job"] for j in atq()["jobs"]]))) ret = {"jobs": {"removed": opts, "tag": None}} else: opts = list( list( map( str, [i["job"] for i in atq()["jobs"] if str(i["job"]) in args], ) ) ) ret = {"jobs": {"removed": opts, "tag": None}} # Shim to produce output similar to what __virtual__() should do # but __salt__ isn't available in __virtual__() output = _cmd("at", "-d", " ".join(opts)) if output is None: return "'at.atrm' is not available." return ret def at(*args, **kwargs): # pylint: disable=C0103 """ Add a job to the queue. The 'timespec' follows the format documented in the at(1) manpage. CLI Example: .. code-block:: bash salt '*' at.at <timespec> <cmd> [tag=<tag>] [runas=<user>] salt '*' at.at 12:05am '/sbin/reboot' tag=reboot salt '*' at.at '3:05am +3 days' 'bin/myscript' tag=nightly runas=jim salt '*' at.at '"22:02"' 'bin/myscript' tag=nightly runas=jim """ if len(args) < 2: return {"jobs": []} # Shim to produce output similar to what __virtual__() should do # but __salt__ isn't available in __virtual__() binary = salt.utils.path.which("at") if not binary: return "'at.at' is not available." if "tag" in kwargs: stdin = "### SALT: {}\n{}".format(kwargs["tag"], " ".join(args[1:])) else: stdin = " ".join(args[1:]) cmd = [binary, args[0]] cmd_kwargs = {"stdin": stdin, "python_shell": False} if "runas" in kwargs: cmd_kwargs["runas"] = kwargs["runas"] output = __salt__["cmd.run"](cmd, **cmd_kwargs) if output is None: return "'at.at' is not available." if output.endswith("Garbled time"): return {"jobs": [], "error": "invalid timespec"} if output.startswith("warning: commands"): output = output.splitlines()[1] if output.startswith("commands will be executed"): output = output.splitlines()[1] output = output.split()[1] if __grains__["os"] in BSD: return atq(str(output)) else: return atq(int(output)) def atc(jobid): """ Print the at(1) script that will run for the passed job id. This is mostly for debugging so the output will just be text. CLI Example: .. code-block:: bash salt '*' at.atc <jobid> """ # Shim to produce output similar to what __virtual__() should do # but __salt__ isn't available in __virtual__() output = _cmd("at", "-c", str(jobid)) if output is None: return "'at.atc' is not available." elif output == "": return {"error": f"invalid job id '{jobid}'"} return output def _atq(**kwargs): """ Return match jobs list """ jobs = [] runas = kwargs.get("runas", None) tag = kwargs.get("tag", None) hour = kwargs.get("hour", None) minute = kwargs.get("minute", None) day = kwargs.get("day", None) month = kwargs.get("month", None) year = kwargs.get("year", None) if year and len(str(year)) == 2: year = f"20{year}" jobinfo = atq()["jobs"] if not jobinfo: return {"jobs": jobs} for job in jobinfo: if not runas: pass elif runas == job["user"]: pass else: continue if not tag: pass elif tag == job["tag"]: pass else: continue if not hour: pass elif f"{int(hour):02d}" == job["time"].split(":")[0]: pass else: continue if not minute: pass elif f"{int(minute):02d}" == job["time"].split(":")[1]: pass else: continue if not day: pass elif f"{int(day):02d}" == job["date"].split("-")[2]: pass else: continue if not month: pass elif f"{int(month):02d}" == job["date"].split("-")[1]: pass else: continue if not year: pass elif year == job["date"].split("-")[0]: pass else: continue jobs.append(job) if not jobs: note = "No match jobs or time format error" return {"jobs": jobs, "note": note} return {"jobs": jobs} def jobcheck(**kwargs): """ Check the job from queue. The kwargs dict include 'hour minute day month year tag runas' Other parameters will be ignored. CLI Example: .. code-block:: bash salt '*' at.jobcheck runas=jam day=13 salt '*' at.jobcheck day=13 month=12 year=13 tag=rose """ if not kwargs: return {"error": "You have given a condition"} return _atq(**kwargs)