Commit 07cd723a authored by Iustin Pop's avatar Iustin Pop

Implement job auto-archiving

This patch adds a new luxi call that implements auto-archiving of jobs
older than a certain age (or -1 for all completed jobs), and the gnt-job
command that makes use of this (with 'all' for -1).

Reviewed-by: imsnah
parent 2241e2b9
......@@ -216,6 +216,10 @@ class ClientOps:
job_id = args
return queue.ArchiveJob(job_id)
elif method == luxi.REQ_AUTOARCHIVE_JOBS:
age = args
return queue.AutoArchiveJobs(age)
elif method == luxi.REQ_WAIT_FOR_JOB_CHANGE:
(job_id, fields, prev_job_info, prev_log_serial, timeout) = args
return queue.WaitForJobChanges(job_id, fields, prev_job_info,
......
......@@ -47,7 +47,7 @@ __all__ = ["DEBUG_OPT", "NOHDR_OPT", "SEP_OPT", "GenericMain",
"USEUNITS_OPT", "FIELDS_OPT", "FORCE_OPT", "SUBMIT_OPT",
"ListTags", "AddTags", "RemoveTags", "TAG_SRC_OPT",
"FormatError", "SplitNodeOption", "SubmitOrSend",
"JobSubmittedException", "FormatTimestamp",
"JobSubmittedException", "FormatTimestamp", "ParseTimespec",
]
......
......@@ -666,16 +666,15 @@ class JobQueue(object):
finally:
self.UpdateJobUnlocked(job)
@utils.LockedMethod
@_RequireOpenQueue
def ArchiveJob(self, job_id):
def _ArchiveJobUnlocked(self, job_id):
"""Archives a job.
@type job_id: string
@param job_id: Job ID of job to be archived.
"""
logging.debug("Archiving job %s", job_id)
logging.info("Archiving job %s", job_id)
job = self._LoadJobUnlocked(job_id)
if not job:
......@@ -695,6 +694,51 @@ class JobQueue(object):
logging.debug("Successfully archived job %s", job.id)
@utils.LockedMethod
@_RequireOpenQueue
def ArchiveJob(self, job_id):
"""Archives a job.
@type job_id: string
@param job_id: Job ID of job to be archived.
"""
return self._ArchiveJobUnlocked(job_id)
@utils.LockedMethod
@_RequireOpenQueue
def AutoArchiveJobs(self, age):
"""Archives all jobs based on age.
The method will archive all jobs which are older than the age
parameter. For jobs that don't have an end timestamp, the start
timestamp will be considered. The special '-1' age will cause
archival of all jobs (that are not running or queued).
@type age: int
@param age: the minimum age in seconds
"""
logging.info("Archiving jobs with age more than %s seconds", age)
now = time.time()
for jid in self._GetJobIDsUnlocked(archived=False):
job = self._LoadJobUnlocked(jid)
if job.CalcStatus() not in (constants.OP_STATUS_SUCCESS,
constants.OP_STATUS_ERROR,
constants.OP_STATUS_CANCELED):
continue
if job.end_timestamp is None:
if job.start_timestamp is None:
job_age = job.received_timestamp
else:
job_age = job.start_timestamp
else:
job_age = job.end_timestamp
if age == -1 or now - job_age[0] > age:
self._ArchiveJobUnlocked(jid)
def _GetJobInfoUnlocked(self, job, fields):
row = []
for fname in fields:
......
......@@ -47,6 +47,7 @@ REQ_SUBMIT_JOB = "SubmitJob"
REQ_WAIT_FOR_JOB_CHANGE = "WaitForJobChange"
REQ_CANCEL_JOB = "CancelJob"
REQ_ARCHIVE_JOB = "ArchiveJob"
REQ_AUTOARCHIVE_JOBS = "AutoArchiveJobs"
REQ_QUERY_JOBS = "QueryJobs"
REQ_QUERY_INSTANCES = "QueryInstances"
REQ_QUERY_NODES = "QueryNodes"
......@@ -290,6 +291,9 @@ class Client(object):
def ArchiveJob(self, job_id):
return self.CallMethod(REQ_ARCHIVE_JOB, job_id)
def AutoArchiveJobs(self, age):
return self.CallMethod(REQ_AUTOARCHIVE_JOBS, age)
def WaitForJobChange(self, job_id, fields, prev_job_info, prev_log_serial):
timeout = (DEF_RWTO - 1) / 2
while True:
......
......@@ -116,6 +116,20 @@ def ArchiveJobs(opts, args):
return 0
def AutoArchiveJobs(opts, args):
client = GetClient()
age = args[0]
if age == 'all':
age = -1
else:
age = ParseTimespec(age)
client.AutoArchiveJobs(age)
return 0
def CancelJobs(opts, args):
client = GetClient()
......@@ -261,6 +275,10 @@ commands = {
[DEBUG_OPT],
"<job-id> [<job-id> ...]",
"Archive specified jobs"),
'autoarchive': (AutoArchiveJobs, ARGS_ONE,
[DEBUG_OPT],
"<age>",
"Auto archive jobs older than the given age"),
'cancel': (CancelJobs, ARGS_ANY,
[DEBUG_OPT],
"<job-id> [<job-id> ...]",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment