[enh] Interface for migrations (#186)

* [wip] Dirty draft of interface for migrations

* Update following changes in migrations_list : properly display pending / done migrations

* Handle run/skip actions

* Fix handling of disclaimers

* Fix to get the accept-disclaimer option working

* Cosmetic: prettier migrations names without the _ between words..

* Show disclaimer + ack checkbox directly on page instead of using modals. Check that disclaimer was acknowledged.

* Don't escape HTML in the disclaimer (for <br>)
This commit is contained in:
Alexandre Aubin 2018-05-02 01:59:02 +02:00 committed by GitHub
parent 516d07f0d4
commit c9f9719414
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 181 additions and 4 deletions

View file

@ -95,7 +95,7 @@
);
}
});
// Upgrade a specific apps
app.get('#/upgrade/apps/:app', function (c) {
c.confirm(
@ -197,15 +197,15 @@
c.redirect('#/logout');
}, 'PUT', {}, false, function (xhr) {
c.flash('success', y18n.t('tools_' + action + '_done'))
// Disconnect from the webadmin
// Disconnect from the webadmin
store.clear('url');
store.clear('connected');
store.set('path', '#/');
// Rename the page to allow refresh without ask for rebooting
window.location.href = window.location.href.split('#')[0] + '#/';
// Display reboot or shutdown info
// We can't use template because now the webserver is off
// We can't use template because now the webserver is off
if (action == 'reboot') {
$('#main').replaceWith('<div id="main"><div class="alert alert-warning"><i class="fa-refresh"></i> ' + y18n.t('tools_rebooting') + '</div></div>');
}
@ -250,4 +250,88 @@
});
});
// Reboot or shutdown button
app.get('#/tools/migrations', function (c) {
c.api('/migrations?pending', function(pending_migrations) {
c.api('/migrations?done', function(done_migrations) {
pending_migrations = pending_migrations.migrations;
done_migrations = done_migrations.migrations;
// Get rid of _ in the raw name of migrations (cosmetic)
for(var i = 0; i < pending_migrations.length; i++) {
pending_migrations[i].name = pending_migrations[i].name.replace(/_/g, " ")
if (pending_migrations[i].disclaimer)
{
pending_migrations[i].disclaimer = pending_migrations[i].disclaimer.replace(/\n/g, "<br />");
}
}
for(var i = 0; i < done_migrations.length; i++) {
done_migrations[i].name = done_migrations[i].name.replace(/_/g, " ")
}
c.view('tools/tools_migrations', {
'pending_migrations' : pending_migrations.reverse(),
'done_migrations' : done_migrations.reverse()
});
});
});
});
app.get('#/tools/migrations/run', function (c) {
var disclaimerAcks = $(".disclaimer-ack");
var withAcceptDisclaimerFlag = false;
for (var i = 0 ; i < disclaimerAcks.length ; i++)
{
console.log($(disclaimerAcks[i]).find("input:checked").val());
if (! $(disclaimerAcks[i]).find("input:checked").val())
{
// FIXME / TODO i18n
c.flash('fail', "Some of these migrations require you to acknowledge a disclaimer before running them.");
c.redirect('#/tools/migrations');
return;
}
else
{
withAcceptDisclaimerFlag = true;
}
};
// Not sure if necessary, but this distinction is to avoid accidentally
// triggering a migration with a disclaimer if one goes to the
// /tools/migrations/run page "directly" somehow ...
if (withAcceptDisclaimerFlag)
{
c.api('/migrations/migrate?accept_disclaimer',
function (data) {
store.clear('slide');
c.redirect('#/tools/migrations');
}, 'POST')
}
else
{
c.api('/migrations/migrate',
function (data) {
store.clear('slide');
c.redirect('#/tools/migrations');
}, 'POST')
}
});
app.get('#/tools/migrations/skip', function (c) {
c.confirm(
y18n.t('migrations'),
y18n.t('confirm_migrations_skip'),
function(){
c.api('/migrations/migrate?skip', function(data) {
store.clear('slide');
c.redirect('#/tools/migrations');
}, 'POST');
},
function(){
store.clear('slide');
c.redirect('#/tools/migrations');
}
);
});
})();

View file

@ -73,6 +73,7 @@
"confirm_firewall_close": "Are you sure you want to close port %s? (protocol: %s, connection: %s)",
"confirm_install_custom_app": "Installing 3rd party applications may compromise the security of your system. Use at your own risk.",
"confirm_install_domain_root": "You will not be able to install any other app on %s. Continue ?",
"confirm_migrations_skip": "Skipping migrations is not recommended. Are you sure you want to do that?",
"confirm_postinstall": "You are about to launch the post-installation process on the domain %s. It may take a few minutes, *do not interrupt the operation*.",
"confirm_restore": "Are you sure you want to restore %s ?",
"confirm_service_start": "Are you sure you want to start %s?",
@ -190,6 +191,11 @@
"manage_users": "Manage users",
"memory": "Memory",
"menu": "Menu",
"migrations": "Migrations",
"migrations_pending": "Pending migrations",
"migrations_done": "Previous migrations",
"migrations_no_pending": "No pending migrations",
"migrations_no_done": "No previous migrations",
"mode": "Mode",
"monitoring": "Monitoring",
"monitoring_check_glances": "Check <a href='#/services/glances'>glances</a> service status.",
@ -238,6 +244,7 @@
"refresh_app_list": "Refresh list",
"remove_access": "Remove access",
"restore": "Restore",
"run": "Run",
"running": "Running",
"save": "Save",
"select_user": "Select user",
@ -248,6 +255,7 @@
"services_list": "Service list",
"set_default": "Set default",
"size": "Size",
"skip": "Skip",
"start": "Start",
"status": "Status",
"stop": "Stop",

View file

@ -11,6 +11,10 @@
<span class="pull-right fa-chevron-right"></span>
<h2 class="list-group-item-heading">{{t 'diagnosis'}}</h2>
</a>
<a href="#/tools/migrations" class="list-group-item slide clearfix">
<span class="pull-right fa-chevron-right"></span>
<h2 class="list-group-item-heading">{{t 'migrations'}}</h2>
</a>
<a href="#/tools/monitor" class="list-group-item slide clearfix">
<span class="pull-right fa-chevron-right"></span>
<h2 class="list-group-item-heading">{{t 'monitoring'}}</h2>

View file

@ -0,0 +1,81 @@
<div class="btn-breadcrumb">
<a href="#/" ><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
<a href="#/tools">{{t 'tools'}}</a>
<a href="#/tools/migrations">{{t 'migrations'}}</a>
</div>
<div class="separator"></div>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title"><span class="fa-fw fa-cogs"></span> {{t 'migrations_pending'}}
{{#if pending_migrations}}
<div class="btn-toolbar pull-right">
<a href="#/tools/migrations/run" class="btn btn-success" style="margin-top: -3px"><span class="fa-fw fa-play"></span> {{t 'run'}}</a>
<a href="#/tools/migrations/skip" class="btn btn-warning" style="margin-top: -3px"><span class="fa-fw fa-close"></span> {{t 'skip'}}</a>
</div>
{{/if}}
</h2>
</div>
{{#if pending_migrations}}
<div class="list-group">
{{#pending_migrations}}
<div class="list-group-item clearfix">
<h3 class="list-group-item-heading" style="text-transform: capitalize;">
{{ number }}. {{ name }}
</h3>
<p id="description-migration-{{number}}" class="list-group-item-text">
{{ description }}
</p>
{{#if disclaimer }}
<hr>
<p id="disclaimer-migration-{{number}}" class="list-group-item-text">
{{{ disclaimer }}}
<div style="margin-left:20px">
<label style="" id="disclaimer-ack-migration-{{number}}" class="checkbox disclaimer-ack">
<input type="checkbox"> I read and understood this disclaimer
</label>
</div>
</p>
{{/if}}
</div>
{{/pending_migrations}}
</div>
{{else}}
<div class="panel-body">
<span class="text-success"><span class="fa-fw fa-check-circle"></span>{{t 'migrations_no_pending' }}</span>
</div>
{{/if}}
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title"><span class="fa-fw fa-cogs"></span> {{t 'migrations_done'}}
</h2>
</div>
{{#if done_migrations}}
<div class="list-group">
{{#done_migrations}}
<div class="list-group-item clearfix">
<h3 class="list-group-item-heading" style="text-transform: capitalize;">
<a data-toggle="collapse" href="#description-migration-{{number}}">
{{ number }}. {{ name }}
</a>
</h3>
<p id="description-migration-{{number}}" class="list-group-item-text collapse">
{{ description }}
</p>
</div>
{{/done_migrations}}
</div>
{{else}}
<div class="panel-body">
<span class="text-info">{{t 'migrations_no_done' }}</span>
</div>
{{/if}}
</div>