VMMgr - Install app + consolidate apps table
This commit is contained in:
parent
396653c9a6
commit
c6954816be
@ -77,6 +77,7 @@ class WSGIApp(object):
|
|||||||
Rule('/update-app-autostart', endpoint='update_app_autostart_action'),
|
Rule('/update-app-autostart', endpoint='update_app_autostart_action'),
|
||||||
Rule('/start-app', endpoint='start_app_action'),
|
Rule('/start-app', endpoint='start_app_action'),
|
||||||
Rule('/stop-app', endpoint='stop_app_action'),
|
Rule('/stop-app', endpoint='stop_app_action'),
|
||||||
|
Rule('/install-app', endpoint='install_app_action'),
|
||||||
Rule('/update-password', endpoint='update_password_action'),
|
Rule('/update-password', endpoint='update_password_action'),
|
||||||
Rule('/shutdown-vm', endpoint='shutdown_vm_action'),
|
Rule('/shutdown-vm', endpoint='shutdown_vm_action'),
|
||||||
Rule('/reboot-vm', endpoint='reboot_vm_action'),
|
Rule('/reboot-vm', endpoint='reboot_vm_action'),
|
||||||
@ -138,9 +139,13 @@ class WSGIApp(object):
|
|||||||
# Application manager view.
|
# Application manager view.
|
||||||
pkgmgr = PackageManager()
|
pkgmgr = PackageManager()
|
||||||
pkgmgr.fetch_online_packages()
|
pkgmgr.fetch_online_packages()
|
||||||
all_apps = sorted(set([p for p in pkgmgr.online_packages if 'title' in p] + self.vmmgr.conf['apps'].keys()))
|
all_apps = sorted(set([k for k,v in pkgmgr.online_packages.items() if 'host' in v] + list(self.vmmgr.conf['apps'].keys())))
|
||||||
return self.render_template('setup-apps.html', request, all_apps=all_apps, online_packages=pkgmgr.online_packages)
|
return self.render_template('setup-apps.html', request, all_apps=all_apps, online_packages=pkgmgr.online_packages)
|
||||||
|
|
||||||
|
def render_setup_apps_row(self, app, app_title):
|
||||||
|
t = self.jinja_env.get_template('setup-apps-row.html')
|
||||||
|
return t.render({'app': app, 'app_title': app_title, 'conf': self.vmmgr.conf})
|
||||||
|
|
||||||
def update_host_action(self, request):
|
def update_host_action(self, request):
|
||||||
# Update domain and port, then restart nginx
|
# Update domain and port, then restart nginx
|
||||||
try:
|
try:
|
||||||
@ -250,22 +255,39 @@ class WSGIApp(object):
|
|||||||
def start_app_action(self, request):
|
def start_app_action(self, request):
|
||||||
# Starts application along with its dependencies
|
# Starts application along with its dependencies
|
||||||
try:
|
try:
|
||||||
self.vmmgr.start_app(request.form['app'])
|
app = request.form['app']
|
||||||
|
self.vmmgr.start_app(app)
|
||||||
except (BadRequest, InvalidValueException):
|
except (BadRequest, InvalidValueException):
|
||||||
return self.render_json({'error': request.session.lang.malformed_request()})
|
return self.render_json({'error': request.session.lang.malformed_request()})
|
||||||
except:
|
except:
|
||||||
return self.render_json({'error': request.session.lang.stop_start_error()})
|
return self.render_json({'error': request.session.lang.stop_start_error()})
|
||||||
return self.render_json({'ok': request.session.lang.app_started()})
|
app_title = self.vmmgr.conf['apps'][app]['title']
|
||||||
|
return self.render_json({'ok': self.render_setup_apps_row(app, app_title)})
|
||||||
|
|
||||||
def stop_app_action(self, request):
|
def stop_app_action(self, request):
|
||||||
# Stops application along with its dependencies
|
# Stops application along with its dependencies
|
||||||
try:
|
try:
|
||||||
self.vmmgr.stop_app(request.form['app'])
|
app = request.form['app']
|
||||||
|
self.vmmgr.stop_app(app)
|
||||||
except (BadRequest, InvalidValueException):
|
except (BadRequest, InvalidValueException):
|
||||||
return self.render_json({'error': request.session.lang.malformed_request()})
|
return self.render_json({'error': request.session.lang.malformed_request()})
|
||||||
except:
|
except:
|
||||||
return self.render_json({'error': request.session.lang.stop_start_error()})
|
return self.render_json({'error': request.session.lang.stop_start_error()})
|
||||||
return self.render_json({'ok': request.session.lang.app_stopped()})
|
app_title = self.vmmgr.conf['apps'][app]['title']
|
||||||
|
return self.render_json({'ok': self.render_setup_apps_row(app, app_title)})
|
||||||
|
|
||||||
|
def install_app_action(self, request):
|
||||||
|
# Installs application
|
||||||
|
try:
|
||||||
|
app = request.form['app']
|
||||||
|
pkgmgr = PackageManager()
|
||||||
|
pkgmgr.install_package(app)
|
||||||
|
except (BadRequest, InvalidValueException):
|
||||||
|
return self.render_json({'error': request.session.lang.malformed_request()})
|
||||||
|
except:
|
||||||
|
return self.render_json({'error': request.session.lang.package_manager_error()})
|
||||||
|
app_title = self.vmmgr.conf['apps'][app]['title']
|
||||||
|
return self.render_json({'ok': self.render_setup_apps_row(app, app_title)})
|
||||||
|
|
||||||
def update_password_action(self, request):
|
def update_password_action(self, request):
|
||||||
# Updates password for both HDD encryption (LUKS-on-LVM) and web interface admin account
|
# Updates password for both HDD encryption (LUKS-on-LVM) and web interface admin account
|
||||||
|
@ -18,9 +18,8 @@ class WSGILang:
|
|||||||
'cert_request_error': 'Došlo k chybě při žádosti o certifikát. Zkontrolujte, zda je virtuální stroj dostupný z internetu na portu 80.',
|
'cert_request_error': 'Došlo k chybě při žádosti o certifikát. Zkontrolujte, zda je virtuální stroj dostupný z internetu na portu 80.',
|
||||||
'cert_installed': 'Certifikát byl úspěšně nainstalován. Přejděte na URL <a href="{}">{}</a> nebo restartujte webový prohlížeč pro jeho načtení.',
|
'cert_installed': 'Certifikát byl úspěšně nainstalován. Přejděte na URL <a href="{}">{}</a> nebo restartujte webový prohlížeč pro jeho načtení.',
|
||||||
'common_updated': 'Nastavení aplikací bylo úspěšně změněno.',
|
'common_updated': 'Nastavení aplikací bylo úspěšně změněno.',
|
||||||
'app_started': '<span class="info">Spuštěna</span> (<a href="#" class="app-stop">zastavit</a>)',
|
|
||||||
'app_stopped': '<span class="error">Zastavena</span> (<a href="#" class="app-start">spustit</a>)',
|
|
||||||
'stop_start_error': 'Došlo k chybě při spouštění/zastavování. Zkuste akci opakovat nebo restartuje virtuální stroj.',
|
'stop_start_error': 'Došlo k chybě při spouštění/zastavování. Zkuste akci opakovat nebo restartuje virtuální stroj.',
|
||||||
|
'package_manager_error': 'Došlo k chybě při instalaci aplikace',
|
||||||
'bad_password': 'Nesprávné heslo',
|
'bad_password': 'Nesprávné heslo',
|
||||||
'password_mismatch': 'Zadaná hesla se neshodují',
|
'password_mismatch': 'Zadaná hesla se neshodují',
|
||||||
'password_empty': 'Nové heslo nesmí být prázdné',
|
'password_empty': 'Nové heslo nesmí být prázdné',
|
||||||
|
@ -8,7 +8,10 @@ $(function() {
|
|||||||
$('#update-common').on('submit', update_common);
|
$('#update-common').on('submit', update_common);
|
||||||
$('.app-visible').on('click', update_app_visibility);
|
$('.app-visible').on('click', update_app_visibility);
|
||||||
$('.app-autostart').on('click', update_app_autostart);
|
$('.app-autostart').on('click', update_app_autostart);
|
||||||
$('tr[data-app]').on('click', '.app-start', start_app).on('click', '.app-stop', stop_app);
|
$('#app-manager')
|
||||||
|
.on('click', '.app-start', start_app)
|
||||||
|
.on('click', '.app-stop', stop_app)
|
||||||
|
.on('click', '.app-install', install_app);
|
||||||
$('#update-password').on('submit', update_password);
|
$('#update-password').on('submit', update_password);
|
||||||
$('#reboot-vm').on('click', reboot_vm);
|
$('#reboot-vm').on('click', reboot_vm);
|
||||||
$('#shutdown-vm').on('click', shutdown_vm);
|
$('#shutdown-vm').on('click', shutdown_vm);
|
||||||
@ -139,14 +142,14 @@ function update_app_autostart(ev) {
|
|||||||
|
|
||||||
function start_app(ev) {
|
function start_app(ev) {
|
||||||
var el = $(ev.target);
|
var el = $(ev.target);
|
||||||
var app = el.closest('tr').data('app');
|
var tr = el.closest('tr');
|
||||||
var td = el.closest('td');
|
var td = el.closest('td');
|
||||||
td.html('<div class="loader"></div>');
|
td.html('<div class="loader"></div>');
|
||||||
$.post('/start-app', {'app': app}, function(data) {
|
$.post('/start-app', {'app': tr.data('app')}, function(data) {
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
td.attr('class','error').html(data.error);
|
td.attr('class','error').html(data.error);
|
||||||
} else {
|
} else {
|
||||||
td.removeAttr('class').html(data.ok);
|
tr.replaceWith(data.ok);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
@ -154,14 +157,29 @@ function start_app(ev) {
|
|||||||
|
|
||||||
function stop_app(ev) {
|
function stop_app(ev) {
|
||||||
var el = $(ev.target);
|
var el = $(ev.target);
|
||||||
var app = el.closest('tr').data('app');
|
var tr = el.closest('tr');
|
||||||
var td = el.closest('td');
|
var td = el.closest('td');
|
||||||
td.html('<div class="loader"></div>');
|
td.html('<div class="loader"></div>');
|
||||||
$.post('/stop-app', {'app': app}, function(data) {
|
$.post('/stop-app', {'app': tr.data('app')}, function(data) {
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
td.attr('class','error').html(data.error);
|
td.attr('class','error').html(data.error);
|
||||||
} else {
|
} else {
|
||||||
td.removeAttr('class').html(data.ok);
|
tr.replaceWith(data.ok);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_app(ev) {
|
||||||
|
var el = $(ev.target);
|
||||||
|
var tr = el.closest('tr');
|
||||||
|
var td = el.closest('td');
|
||||||
|
td.html('<div class="loader"></div>');
|
||||||
|
$.post('/install-app', {'app': tr.data('app')}, function(data) {
|
||||||
|
if (data.error) {
|
||||||
|
td.attr('class','error').html(data.error);
|
||||||
|
} else {
|
||||||
|
tr.replaceWith(data.ok);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
|
7
basic/srv/vm/templates/setup-apps-row.html
Normal file
7
basic/srv/vm/templates/setup-apps-row.html
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<tr data-app="{{ app }}">
|
||||||
|
<td>{{ app_title }}</td>
|
||||||
|
<td class="center"><input type="checkbox" class="app-visible"{% if app not in conf['apps'] %} disabled{% elif conf['apps'][app]['visible'] %} checked{% endif %}></td>
|
||||||
|
<td class="center"><input type="checkbox" class="app-autostart"{% if app not in conf['apps'] %} disabled{% elif is_service_autostarted(app) %} checked{% endif %}></td>
|
||||||
|
<td>{% if app not in conf['apps'] %} Není nainstalována{% elif is_service_started(app) %}<span class="info">Spuštěna</span>{% else %}<span class="error">Zastavena</span>{% endif %}</td>
|
||||||
|
<td>{% if app not in conf['apps'] %}<a href="#" class="app-install">Instalovat</a>{% else %}{% if is_service_started(app) %}<a href="#" class="app-stop">Zastavit</a>{% else %}<a href="#" class="app-start">Spustit</a>{% endif %}, <a href="#" class="app-uninstall">Odinstalovat</a>{% endif %}</td>
|
||||||
|
</tr>
|
@ -34,50 +34,20 @@
|
|||||||
<div class="setup-box">
|
<div class="setup-box">
|
||||||
<h2>Správce aplikací</h2>
|
<h2>Správce aplikací</h2>
|
||||||
<p>Vyberte které aplikace mají být nainstalovány, které se mají zobrazovat na hlavní straně portálu a které mají být automaticky spuštěny při startu virtuálního stroje.</p>
|
<p>Vyberte které aplikace mají být nainstalovány, které se mají zobrazovat na hlavní straně portálu a které mají být automaticky spuštěny při startu virtuálního stroje.</p>
|
||||||
<table>
|
<table id="app-manager">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Aplikace</td>
|
<td>Aplikace</td>
|
||||||
<td>Nainstalována</td>
|
|
||||||
<td>Zobrazena</td>
|
<td>Zobrazena</td>
|
||||||
<td>Autostart</td>
|
<td>Autostart</td>
|
||||||
<td>Stav</td>
|
<td>Stav</td>
|
||||||
|
<td>Akce</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for app in all_apps %}
|
{% for app in all_apps %}
|
||||||
<tr data-app="{{ app }}">
|
{% set app_title = conf['apps'][app]['title'] if app in conf['apps'] else online_packages[app]['title'] %}
|
||||||
<td>{{ conf['apps'][app]['title'] if app in conf['apps'] else online_packages[app]['title'] }}</td>
|
{% include 'setup-apps-row.html' %}
|
||||||
<td class="center"><input type="checkbox" class="app-installed"{% if app in conf['apps'] %} checked{% endif %}></td>
|
|
||||||
<td class="center"><input type="checkbox" class="app-visible"{% if conf['apps'][app]['visible'] %} checked{% endif %}></td>
|
|
||||||
<td class="center"><input type="checkbox" class="app-autostart"{% if is_service_autostarted(app) %} checked{% endif %}></td>
|
|
||||||
<td>{% if is_service_started(app) %}<span class="info">Spuštěna</span> (<a href="#" class="app-stop">zastavit</a>){% else %}<span class="error">Zastavena</span> (<a href="#" class="app-start">spustit</a>){% endif %}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setup-box">
|
|
||||||
<h2>Správce balíků</h2>
|
|
||||||
<p>Vyberte které aplikace mají být nainstalovány nebo aktualizovány z distribučního serveru.</p>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>Aplikace</td>
|
|
||||||
<td>Nainstalována</td>
|
|
||||||
<td>Stav</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for pkg in online_packages|sort %}
|
|
||||||
{% if 'title' in online_packages[pkg] %}
|
|
||||||
<tr data-app="{{ pkg }}">
|
|
||||||
<td>{{ online_packages[pkg]['title'] }}</td>
|
|
||||||
<td class="center"><input type="checkbox" class="pkg-installed"{% if pkg in conf['packages'] %} checked{% endif %}></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user