Skip to content

Commit

Permalink
Merge pull request #25501 from basepi/job.cache.finish.time.23563
Browse files Browse the repository at this point in the history
Add optional job end time to the local_cache returner
  • Loading branch information
Mike Place committed Jul 17, 2015
2 parents cef7461 + b8c687d commit 77738f6
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 0 deletions.
4 changes: 4 additions & 0 deletions salt/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,9 @@
# that it receives
'master_job_cache': str,

# Specify whether the master should store end times for jobs as returns come in
'job_cache_store_endtime': bool,

# The minion data cache is a cache of information about the minions stored on the master.
# This information is primarily the pillar and grains data. The data is cached in the master
# cachedir under the name of the minion and used to predetermine what minions are expected to
Expand Down Expand Up @@ -948,6 +951,7 @@
'job_cache': True,
'ext_job_cache': '',
'master_job_cache': 'local_cache',
'job_cache_store_endtime': False,
'minion_data_cache': True,
'enforce_mine_cache': False,
'ipc_mode': _DFLT_IPC_MODE,
Expand Down
7 changes: 7 additions & 0 deletions salt/daemons/masterapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,8 @@ def _return(self, load):
'''
Handle the return data sent from the minions
'''
# Generate EndTime
endtime = salt.utils.jid.jid_to_time(salt.utils.jid.gen_jid())
# If the return data is invalid, just ignore it
if any(key not in load for key in ('return', 'jid', 'id')):
return False
Expand All @@ -757,6 +759,11 @@ def _return(self, load):
if not self.opts['job_cache'] or self.opts.get('ext_job_cache'):
return

fstr = '{0}.update_endtime'.format(self.opts['master_job_cache'])
if (self.opts.get('job_cache_store_endtime')
and fstr in self.mminion.returners):
self.mminion.returners[fstr](load['jid'], endtime)

fstr = '{0}.returner'.format(self.opts['master_job_cache'])
self.mminion.returners[fstr](load)

Expand Down
39 changes: 39 additions & 0 deletions salt/returners/local_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
RETURN_P = 'return.p'
# out is the "out" from the minion data
OUT_P = 'out.p'
# endtime is the end time for a job, not stored as msgpack
ENDTIME = 'endtime'


def _job_dir():
Expand Down Expand Up @@ -253,6 +255,12 @@ def get_jids():
ret = {}
for jid, job, _, _ in _walk_through(_job_dir()):
ret[jid] = salt.utils.jid.format_jid_instance(jid, job)

if __opts__.get('job_cache_store_endtime'):
endtime = get_endtime(jid)
if endtime:
ret[jid]['EndTime'] = endtime

return ret


Expand Down Expand Up @@ -280,3 +288,34 @@ def clean_old_jobs():
hours_difference = (cur - jid_ctime) / 3600.0
if hours_difference > __opts__['keep_jobs']:
shutil.rmtree(f_path)


def update_endtime(jid, time):
'''
Update (or store) the end time for a given job
Endtime is stored as a plain text string
'''
jid_dir = _jid_dir(jid)
try:
if not os.path.exists(jid_dir):
os.makedirs(jid_dir)
with salt.utils.fopen(os.path.join(jid_dir, ENDTIME), 'w') as etfile:
etfile.write(time)
except IOError as exc:
log.warning('Could not write job invocation cache file: {0}'.format(exc))


def get_endtime(jid):
'''
Retrieve the stored endtime for a given job
Returns False if no endtime is present
'''
jid_dir = _jid_dir(jid)
etpath = os.path.join(jid_dir, ENDTIME)
if not os.path.exists(etpath):
return False
with salt.utils.fopen(etpath, 'r') as etfile:
endtime = etfile.read().strip('\n')
return endtime
16 changes: 16 additions & 0 deletions salt/runners/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,14 @@ def list_job(jid, ext_source=None, outputter=None):
job = mminion.returners['{0}.get_load'.format(returner)](jid)
ret.update(_format_jid_instance(jid, job))
ret['Result'] = mminion.returners['{0}.get_jid'.format(returner)](jid)

fstr = '{0}.get_endtime'.format(__opts__['master_job_cache'])
if (__opts__.get('job_cache_store_endtime')
and fstr in mminion.returners):
endtime = mminion.returners[fstr](jid)
if endtime:
ret['EndTime'] = endtime

if outputter:
salt.utils.warn_until(
'Boron',
Expand Down Expand Up @@ -344,6 +352,14 @@ def print_job(jid, ext_source=None, outputter=None):
'Check master log for details.'.format(returner))
return ret
ret[jid]['Result'] = mminion.returners['{0}.get_jid'.format(returner)](jid)

fstr = '{0}.get_endtime'.format(__opts__['master_job_cache'])
if (__opts__.get('job_cache_store_endtime')
and fstr in mminion.returners):
endtime = mminion.returners[fstr](jid)
if endtime:
ret[jid]['EndTime'] = endtime

if outputter:
salt.utils.warn_until(
'Boron',
Expand Down
8 changes: 8 additions & 0 deletions salt/utils/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def store_job(opts, load, event=None, mminion=None):
'''
Store job information using the configured master_job_cache
'''
# Generate EndTime
endtime = salt.utils.jid.jid_to_time(salt.utils.jid.gen_jid())
# If the return data is invalid, just ignore it
if any(key not in load for key in ('return', 'jid', 'id')):
return False
Expand Down Expand Up @@ -84,6 +86,12 @@ def store_job(opts, load, event=None, mminion=None):
if 'jid' in load and 'get_load' in mminion.returners and not mminion.returners[getfstr](load.get('jid', '')):
mminion.returners[savefstr](load['jid'], load)
mminion.returners[fstr](load)

updateetfstr = '{0}.update_endtime'.format(job_cache)
if (opts.get('job_cache_store_endtime')
and updateetfstr in mminion.returners):
mminion.returners[updateetfstr](load['jid'], endtime)

except KeyError:
emsg = "Returner '{0}' does not support function returner".format(job_cache)
log.error(emsg)
Expand Down

0 comments on commit 77738f6

Please sign in to comment.