322 lines
10 KiB
Mako
322 lines
10 KiB
Mako
## -*- coding: utf-8; -*-
|
|
<%inherit file="/master/view.mako" />
|
|
|
|
<%def name="extra_javascript()">
|
|
${parent.extra_javascript()}
|
|
% if not use_buefy:
|
|
<script type="text/javascript">
|
|
|
|
function show_packages(type) {
|
|
if (type == 'all') {
|
|
$('.showing .diffs').css('font-weight', 'normal');
|
|
$('table.diff tbody tr').show();
|
|
$('.showing .all').css('font-weight', 'bold');
|
|
} else if (type == 'diffs') {
|
|
$('.showing .all').css('font-weight', 'normal');
|
|
$('table.diff tbody tr:not(.diff)').hide();
|
|
$('.showing .diffs').css('font-weight', 'bold');
|
|
}
|
|
}
|
|
|
|
$(function() {
|
|
|
|
show_packages('diffs');
|
|
|
|
$('.showing .all').click(function() {
|
|
show_packages('all');
|
|
return false;
|
|
});
|
|
|
|
$('.showing .diffs').click(function() {
|
|
show_packages('diffs')
|
|
return false;
|
|
});
|
|
|
|
});
|
|
|
|
</script>
|
|
% endif
|
|
</%def>
|
|
|
|
<%def name="extra_styles()">
|
|
${parent.extra_styles()}
|
|
% if master.has_perm('execute'):
|
|
<style type="text/css">
|
|
.progress-with-textout {
|
|
border: 1px solid Black;
|
|
line-height: 1.2;
|
|
overflow: auto;
|
|
padding: 1rem;
|
|
}
|
|
</style>
|
|
% endif
|
|
</%def>
|
|
|
|
<%def name="render_this_page()">
|
|
${parent.render_this_page()}
|
|
|
|
% if expose_websockets and master.has_perm('execute'):
|
|
<b-modal :active.sync="upgradeExecuting"
|
|
full-screen
|
|
:can-cancel="false">
|
|
<div class="card">
|
|
<div class="card-content">
|
|
|
|
<div class="level">
|
|
<div class="level-item has-text-centered"
|
|
style="display: flex; flex-direction: column;">
|
|
<p class="block">
|
|
Upgrading ${app_title} (please wait) ...
|
|
{{ executeUpgradeComplete ? "DONE!" : "" }}
|
|
</p>
|
|
<b-progress size="is-large"
|
|
style="width: 400px;"
|
|
## :value="80"
|
|
## show-value
|
|
## format="percent"
|
|
>
|
|
</b-progress>
|
|
</div>
|
|
<div class="level-right">
|
|
<div class="level-item">
|
|
<b-button type="is-warning"
|
|
icon-pack="fas"
|
|
icon-left="sad-tear"
|
|
@click="declareFailureClick()">
|
|
Declare Failure
|
|
</b-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="container progress-with-textout is-family-monospace is-size-7"
|
|
ref="textout">
|
|
<span v-for="line in progressOutput"
|
|
:key="line.key"
|
|
v-html="line.text">
|
|
</span>
|
|
|
|
## nb. we auto-scroll down to "see" this element
|
|
<div ref="seeme"></div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</b-modal>
|
|
% endif
|
|
|
|
% if master.has_perm('execute'):
|
|
${h.form(master.get_action_url('declare_failure', instance), ref='declareFailureForm')}
|
|
${h.csrf_token(request)}
|
|
${h.end_form()}
|
|
% endif
|
|
</%def>
|
|
|
|
<%def name="render_buefy_form()">
|
|
<div class="form">
|
|
<${form.component}
|
|
% if expose_websockets and master.has_perm('execute'):
|
|
% if instance_executable:
|
|
@execute-upgrade-click="executeUpgrade"
|
|
% endif
|
|
:upgrade-executing="upgradeExecuting"
|
|
@declare-failure-click="declareFailureClick"
|
|
:declare-failure-submitting="declareFailureSubmitting"
|
|
% endif
|
|
>
|
|
</${form.component}>
|
|
</div>
|
|
</%def>
|
|
|
|
<%def name="render_form_buttons()">
|
|
% if instance_executable and master.has_perm('execute'):
|
|
<div class="buttons">
|
|
% if instance.enabled and not instance.executing:
|
|
% if use_buefy and expose_websockets:
|
|
<b-button type="is-primary"
|
|
icon-pack="fas"
|
|
icon-left="arrow-circle-right"
|
|
:disabled="upgradeExecuting"
|
|
@click="$emit('execute-upgrade-click')">
|
|
{{ upgradeExecuting ? "Working, please wait..." : "Execute this upgrade" }}
|
|
</b-button>
|
|
% elif use_buefy:
|
|
${h.form(url('{}.execute'.format(route_prefix), uuid=instance.uuid), **{'@submit': 'submitForm'})}
|
|
${h.csrf_token(request)}
|
|
<b-button type="is-primary"
|
|
native-type="submit"
|
|
icon-pack="fas"
|
|
icon-left="arrow-circle-right"
|
|
:disabled="formSubmitting">
|
|
{{ formSubmitting ? "Working, please wait..." : "Execute this upgrade" }}
|
|
</b-button>
|
|
${h.end_form()}
|
|
% else:
|
|
${h.form(url('{}.execute'.format(route_prefix), uuid=instance.uuid), class_='autodisable')}
|
|
${h.csrf_token(request)}
|
|
${h.submit('execute', "Execute this upgrade", class_='button is-primary')}
|
|
${h.end_form()}
|
|
% endif
|
|
% elif instance.enabled:
|
|
<button type="button" class="button is-primary" disabled="disabled" title="This upgrade is currently executing">Execute this upgrade</button>
|
|
% else:
|
|
<button type="button" class="button is-primary" disabled="disabled" title="This upgrade is not enabled">Execute this upgrade</button>
|
|
% endif
|
|
</div>
|
|
% endif
|
|
</%def>
|
|
|
|
<%def name="modify_this_page_vars()">
|
|
${parent.modify_this_page_vars()}
|
|
<script type="text/javascript">
|
|
|
|
TailboneFormData.showingPackages = 'diffs'
|
|
|
|
% if master.has_perm('execute'):
|
|
|
|
% if expose_websockets:
|
|
|
|
ThisPageData.ws = null
|
|
|
|
//////////////////////////////
|
|
// execute upgrade
|
|
//////////////////////////////
|
|
|
|
TailboneForm.props.upgradeExecuting = {
|
|
type: Boolean,
|
|
default: false,
|
|
}
|
|
|
|
ThisPageData.upgradeExecuting = false
|
|
ThisPageData.progressOutput = []
|
|
ThisPageData.progressOutputCounter = 0
|
|
ThisPageData.executeUpgradeComplete = false
|
|
|
|
ThisPage.methods.adjustTextoutHeight = function() {
|
|
|
|
// grow the textout area to fill most of screen
|
|
let textout = this.$refs.textout
|
|
let height = window.innerHeight - textout.offsetTop - 50
|
|
textout.style.height = height + 'px'
|
|
}
|
|
|
|
ThisPage.methods.showExecuteDialog = function() {
|
|
this.upgradeExecuting = true
|
|
document.title = "Upgrading ${app_title} ..."
|
|
this.$nextTick(() => {
|
|
this.adjustTextoutHeight()
|
|
})
|
|
}
|
|
|
|
ThisPage.methods.establishWebsocket = function() {
|
|
|
|
## TODO: should be a cleaner way to get this url?
|
|
url = '${request.route_url('ws.upgrades.execution_progress', _query={'uuid': instance.uuid})}'
|
|
url = url.replace(/^https?:/, 'wss:')
|
|
|
|
this.ws = new WebSocket(url)
|
|
|
|
## TODO: add support for this here?
|
|
// this.ws.onclose = (event) => {
|
|
// // websocket closing means 1 of 2 things:
|
|
// // - user navigated away from page intentionally
|
|
// // - server connection was broken somehow
|
|
// // only one of those is "bad" and we only want to
|
|
// // display warning in 2nd case. so we simply use a
|
|
// // brief delay to "rule out" the 1st scenario
|
|
// setTimeout(() => { that.websocketBroken = true },
|
|
// 3000)
|
|
// }
|
|
|
|
this.ws.onmessage = (event) => {
|
|
let data = JSON.parse(event.data)
|
|
|
|
if (data.complete) {
|
|
|
|
// upgrade has completed; reload page to view result
|
|
this.executeUpgradeComplete = true
|
|
this.$nextTick(() => {
|
|
location.reload()
|
|
})
|
|
|
|
} else if (data.stdout) {
|
|
|
|
// add lines to textout area
|
|
this.progressOutput.push({
|
|
key: ++this.progressOutputCounter,
|
|
text: data.stdout})
|
|
|
|
// scroll down to end of textout area
|
|
this.$nextTick(() => {
|
|
this.$refs.seeme.scrollIntoView({behavior: 'smooth'})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
% if instance.executing:
|
|
ThisPage.mounted = function() {
|
|
this.showExecuteDialog()
|
|
this.establishWebsocket()
|
|
}
|
|
% endif
|
|
|
|
% if instance_executable:
|
|
|
|
ThisPage.methods.executeUpgrade = function() {
|
|
this.showExecuteDialog()
|
|
|
|
let url = '${master.get_action_url('execute', instance)}'
|
|
this.submitForm(url, {ws: true}, response => {
|
|
|
|
this.establishWebsocket()
|
|
})
|
|
}
|
|
|
|
% endif
|
|
|
|
% else:
|
|
## no websockets
|
|
|
|
//////////////////////////////
|
|
// execute upgrade
|
|
//////////////////////////////
|
|
|
|
TailboneFormData.formSubmitting = false
|
|
|
|
TailboneForm.methods.submitForm = function() {
|
|
this.formSubmitting = true
|
|
}
|
|
|
|
% endif
|
|
|
|
//////////////////////////////
|
|
// declare failure
|
|
//////////////////////////////
|
|
|
|
TailboneForm.props.declareFailureSubmitting = {
|
|
type: Boolean,
|
|
default: false,
|
|
}
|
|
|
|
TailboneForm.methods.declareFailureClick = function() {
|
|
this.$emit('declare-failure-click')
|
|
}
|
|
|
|
ThisPageData.declareFailureSubmitting = false
|
|
|
|
ThisPage.methods.declareFailureClick = function() {
|
|
if (confirm("Really declare this upgrade a failure?")) {
|
|
this.declareFailureSubmitting = true
|
|
this.$refs.declareFailureForm.submit()
|
|
}
|
|
}
|
|
|
|
% endif
|
|
|
|
</script>
|
|
</%def>
|
|
|
|
|
|
${parent.body()}
|
|
|