debian-koji/www/kojiweb/taskinfo.html.j2
2025-05-07 14:07:03 +02:00

324 lines
10 KiB
Django/Jinja

#macro printChildren(taskID, childMap)
#set children = childMap[taskID|string]
#if children
<ul>
#for child in children
#if not loop.last
<li class="sibling">
#else
<li>
#endif
#set childState = util.taskState(child.state)
<span class="treeBranch">
<span class="treeLabel">
<span class="task{{ childState }}">{{ util.imageTag(childState) }}</span>
<a href="taskinfo?taskID={{ child.id }}" class="task{{ childState }}" title="{{ childState }}">{{ koji.taskLabel(child) }}</a>
</span>
</span>
{{ printChildren(child.id, childMap) }}
</li>
#endfor
</ul>
#endif
#endmacro
#macro printMap(vals, prefix='')
#for key, value in vals.items()
#if key == 'properties'
{{ prefix }}properties&nbsp;=&nbsp;{{ printProperties(value) }}<br/>
#elif key != '__starstar'
{{ prefix }}{{ key }}&nbsp;=&nbsp;{{ printValue(key, value) }}<br/>
#endif
#endfor
#endmacro
#macro printOpts(opts)
#if opts
<strong>Options:</strong><br/>
{{ printMap(opts, S('&nbsp;&nbsp;')) }}
#endif
#endmacro
#macro printValue(key, value, sep=', ')
#if value is none
None
#elif key == 'user'
<a href="userinfo?userID={{ value['id'] }}">{{ value['name'] }}</a>
#elif key == 'task'
<a href="taskinfo?taskID={{ value['id'] }}">{{ value['id'] }}</a>
#elif key == 'host'
<a href="hostinfo?hostID={{ value['id'] }}">{{ value['name'] }}</a>
#elif key == 'build'
<a href="buildinfo?buildID={{ value['id'] }}">{{ value['nvr'] }}</a>
#elif key == 'buildroot'
<a href="buildrootinfo?buildrootID={{ value['id'] }}">{{ value['id'] }}</a>
#elif key in ('tag', 'destination_tag', 'build_tag')
<a href="taginfo?tagID={{ value['id'] }}">{{ value['name'] }}</a>
#elif key in ('build_target', 'target_info')
<a href="buildtargetinfo?targetID={{ value['id'] }}">{{ value['name'] }}</a>
#elif key in ('repo_info', 'oldrepo', 'repo')
#if value is mapping
<a href="repoinfo?repoID={{ value.id }}">{{ value.id }}</a> ({{ koji.formatTimeLong(value.create_ts) }})
#elif value is sequence and value is not string
{{ value|join(sep) }}
#else
{{ value }}
#endif
#elif key == 'task_list'
#for task in params['task_list']
<br/><strong>&nbsp;Task:</strong><br/>
{{ printMap(task, S('&nbsp;&nbsp;')) }}
#endfor
#elif value is mapping
{{ printSimpleMap(value, sep) }}
#elif value is sequence and value is not string
{{ value|join(sep) }}
#else
{{ value }}
#endif
#endmacro
{%- macro printSimpleMap(value, sep) %}
{%- for name, value in value|dictsort -%}
{{- '%s=%s' % ("''" if name == '' else name, value) -}}
{{- sep if not loop.last else '' -}}
{%- endfor -%}
{%- endmacro %}
#macro printProperties(props)
## TODO this needs refactoring, but for now we simply port the logic
{%- for name, value in props|dictsort -%}
{{- name if value is none else '%s=%s' % (name, value) -}}
{{- ', ' if not loop.last else '' -}}
{%- endfor -%}
#endmacro
#include "includes/header.html.j2"
<h4>Information for task <a href="taskinfo?taskID={{ task.id }}">{{ koji.taskLabel(task) }}</a></h4>
<table>
<tr>
<th>ID</th><td>{{ task.id }}</td>
</tr>
<tr>
<th>Method</th><td>{{ task.method }}</td>
</tr>
<tr>
<th>Parameters</th>
<td>
#for key in params|sort
#if params[key] is not none
<strong>{{ key | capitalize |replace('_', ' ') }}</strong>: {{ printValue(key, params[key]) }}<br/>
#endif
#endfor
{{ printOpts(opts) }}
</td>
</tr>
<tr>
#set state = util.taskState(task.state)
<th>State</th>
<td class="task{{ state }}">{{ state }}
#if currentUser and ('admin' in perms or task.owner == currentUser.id)
#if task.state in (koji.TASK_STATES.FREE, koji.TASK_STATES.OPEN, koji.TASK_STATES.ASSIGNED)
<span class="adminLink">(<a href="canceltask?taskID={{ task.id }}{{ util.authToken() }}">cancel</a>)</span>
#elif task.state in (koji.TASK_STATES.CANCELED, koji.TASK_STATES.FAILED) and (not parent)
<span class="adminLink">(<a href="resubmittask?taskID={{ task.id }}{{ util.authToken() }}">resubmit</a>)</span>
#endif
#endif
#if currentUser and 'admin' in perms and task.state in (koji.TASK_STATES.OPEN, koji.TASK_STATES.ASSIGNED)
<span class="adminLink">(<a href="freetask?taskID={{ task.id }}{{ util.authToken() }}">free</a>)</span>
#endif
</td>
</tr>
#if taskBuilds
#for build in taskBuilds
<tr>
<th>Build</th><td><a href="buildinfo?buildID={{ build.build_id }}">{{ koji.buildLabel(build) }}</a></td>
</tr>
#endfor
#endif
<tr>
<th>Created</th><td>{{ util.formatTimeLong(task.create_ts) }}</td>
</tr>
#if task.start_time
<tr>
<th>Started</th><td>{{ util.formatTimeLong(task.start_ts) }}</td>
#endif
#set end_ts = None
#if task.state == koji.TASK_STATES.OPEN
#if estCompletion
<tr>
<th title="Estimation based on previous builds of same package">Est. Completion</th>
<td>{{ util.formatTimeLong(estCompletion) }}</td>
</tr>
#endif
#elif task.completion_time
<tr>
<th>Completed</th><td>{{ util.formatTimeLong(task.completion_ts) }}</td>
</tr>
#set end_ts = task.completion_ts
#endif
#if not end_ts
#set end_ts = koji.time.time()
#endif
<tr>
<th title="From task's creation">Total time</th>
<td>{{ util.formatTimestampDifference(task.create_ts, end_ts) }}</td>
</tr>
#if task.start_time
<tr>
<th title="From task's start">Task time</th>
<td>{{ util.formatTimestampDifference(task.start_ts, end_ts) }}</td>
</tr>
#endif
<tr>
<th>Owner</th>
<td>
#if owner
#if owner.usertype == koji.USERTYPES['HOST']
<a href="hostinfo?userID={{ owner.id }}">{{ owner.name }}</a>
#else
<a href="userinfo?userID={{ owner.id }}">{{ owner.name }}</a>
#endif
#endif
</td>
</tr>
<tr>
<th>Channel</th>
<td>
#if task.channel_id
<a href="channelinfo?channelID={{ task.channel_id }}">{{ channelName }}</a>
#endif
</td>
</tr>
<tr>
<th>Host</th>
<td>
#if task.host_id
<a href="hostinfo?hostID={{ task.host_id }}">{{ hostName }}</a>
#endif
</td>
</tr>
<tr>
<th>Arch</th><td>{{ task.arch }}</td>
</tr>
#if buildroots
<tr>
<th>Buildroot{{ 's' if buildroots|length > 1 else '' }}</th>
<td>
#for buildroot in buildroots
<a href="buildrootinfo?buildrootID={{ buildroot.id }}">{{ '' if task.method == 'vmExec' else '/var/lib/mock/' }}{{ buildroot.tag_name }}-{{ buildroot.id }}-{{ buildroot.repo_id }}</a><br/>
#endfor
</td>
</tr>
#endif
<tr>
<th>Parent</th>
<td>
#if parent
<a href="taskinfo?taskID={{ parent.id }}" class="task{{ util.taskState(parent.state) }}">{{ koji.taskLabel(parent) }}</a>
#endif
</td>
</tr>
<tr>
<th>Descendants</th>
<td class="tree">
#if descendents[task.id|string]
#set taskState = util.taskState(task.state)
<span class="task{{ taskState }}">{{ util.imageTag(taskState) }}</span>
<span class="root">{{ task.method }}</span>
#endif
{{ printChildren(task.id, descendents) }}
</td>
</tr>
<tr>
<th>Waiting?</th><td>{{ 'yes' if task.waiting else 'no' }}</td>
</tr>
<tr>
<th>Awaited?</th><td>{{ 'yes' if task.awaited else 'no' }}</td>
</tr>
<tr>
<th>Priority</th><td>{{ task.priority }}</td>
</tr>
<tr>
<th>Weight</th><td>{{ '%.2f' % task.weight }}</td>
</tr>
<tr>
<th>Result</th>
<td>
#if abbr_result_text
<div id="abbr-result">
{{ abbr_result_text }}
</div>
<div id="full-result">
{{ full_result_text }}
</div>
<a href="#" collapse" id="toggle-abbreviated-result" style="display: none;">Show abbreviated results</a>
<a href="#" collapse" id="toggle-full-result" style="display: none;">Show complete results</a>
#else
<div id="result">
{{ full_result_text }}
</div>
#endif
</td>
</tr>
<tr>
<th>Output</th>
<td>
#for pair in output
#set volume = pair[0]
#set filename = pair[1]
<a href="{{ pathinfo.task(task.id, volume=volume) }}/{{ filename|urlencode }}">{{ filename }}</a>
#if filename.endswith('.log')
(<a href="getfile?taskID={{ task.id }}&volume={{ volume }}&name={{ filename|urlencode }}&offset=-4000">tail</a>)
#endif
<br/>
#endfor
#if not output
<div title="Not all tasks produce outputs, and task outputs are not retained indefinitely.">No outputs reported</div>
#endif
{% if task.state not in (koji.TASK_STATES.CLOSED, koji.TASK_STATES.CANCELED, koji.TASK_STATES.FAILED) and
task.method in ('buildSRPMFromSCM', 'buildArch', 'createLiveMedia', 'buildMaven', 'wrapperRPM', 'vmExec', 'createrepo', 'runroot', 'createAppliance', 'createLiveCD') %}
<br/>
<a href="watchlogs?taskID={{ task.id }}">Watch logs</a>
{% endif %}
</td>
</tr>
</table>
#if abbr_result_text
<script type="text/javascript">
(function() {
var abbr = document.getElementById('abbr-result');
var full = document.getElementById('full-result');
var link_to_show_abbr = document.getElementById('toggle-abbreviated-result');
var link_to_show_full = document.getElementById('toggle-full-result');
full.style.display = 'none';
abbr.style.display = 'block'
link_to_show_full.style.display = 'inline'
link_to_show_abbr.style.display = 'none'
var trigger = function(e) {
if (link_to_show_abbr.style.display == 'none') {
link_to_show_abbr.style.display = 'inline'
link_to_show_full.style.display = 'none'
abbr.style.display = 'none';
full.style.display = 'block'
}
else {
link_to_show_abbr.style.display = 'none'
link_to_show_full.style.display = 'inline'
abbr.style.display = 'block';
full.style.display = 'none'
}
return false;
};
link_to_show_full.onclick = trigger
link_to_show_abbr.onclick = trigger
})();
</script>
#endif
#include "includes/footer.html.j2"