diff --git a/usr/lib/python3.6/vmmgr/appmgr.py b/usr/lib/python3.6/vmmgr/appmgr.py
index 622d2cf..5b73005 100644
--- a/usr/lib/python3.6/vmmgr/appmgr.py
+++ b/usr/lib/python3.6/vmmgr/appmgr.py
@@ -65,6 +65,12 @@ class AppMgr:
self.update_app_autostart(app, False)
self.pkgmgr.uninstall_app(app)
+ def update_app(self, item):
+ # Main update function. Wrapper for download and update script
+ self.stop_app(item)
+ item.data = Pkg()
+ self.pkgmgr.update_app(item.key, item.data)
+
def get_services_deps(self):
# Fisrt, build a dictionary of {app: [needs]}
needs = {}
diff --git a/usr/lib/python3.6/vmmgr/pkgmgr.py b/usr/lib/python3.6/vmmgr/pkgmgr.py
index 67e4cde..5dcf815 100644
--- a/usr/lib/python3.6/vmmgr/pkgmgr.py
+++ b/usr/lib/python3.6/vmmgr/pkgmgr.py
@@ -7,6 +7,7 @@ import shutil
import subprocess
from enum import Enum
+from packaging.version import Version
from werkzeug.exceptions import BadRequest, NotFound, Unauthorized
from . import crypto
@@ -82,6 +83,12 @@ class PkgMgr:
self.purge_package(dep)
self.unregister_package(dep)
+ def update_app(self, app, item):
+ # Main update function.
+ # TODO: Implement actual update
+ uninstall_app(app)
+ install_app(app, item)
+
def download_package(self, name, item):
# Download tar.xz package and verify its hash. Can raise InvalidSignature
pkg_archive = '{}_{}-{}.tar.xz'.format(name, self.online_packages[name]['version'], self.online_packages[name]['release'])
@@ -164,3 +171,8 @@ class PkgMgr:
for d in self.conf['packages'][name]['depends']:
deps.setdefault(d, []).append(name)
return deps
+
+ def has_update(self, app):
+ if not self.online_packages:
+ return False
+ return Version(self.conf['packages'][app]['version']) < Version(self.online_packages[app]['version'])
diff --git a/usr/lib/python3.6/vmmgr/wsgiapp.py b/usr/lib/python3.6/vmmgr/wsgiapp.py
index 058f195..f09dcf7 100644
--- a/usr/lib/python3.6/vmmgr/wsgiapp.py
+++ b/usr/lib/python3.6/vmmgr/wsgiapp.py
@@ -62,6 +62,7 @@ class WSGIApp:
Rule('/get-app-status', endpoint='get_app_status_action'),
Rule('/clear-app-status', endpoint='clear_app_status_action'),
Rule('/uninstall-app', endpoint='uninstall_app_action'),
+ Rule('/update-app', endpoint='update_app_action'),
Rule('/update-password', endpoint='update_password_action'),
Rule('/shutdown-vm', endpoint='shutdown_vm_action'),
Rule('/reboot-vm', endpoint='reboot_vm_action'),
@@ -247,12 +248,15 @@ class WSGIApp:
if not installed:
status = lang.status_not_installed()
actions = '{}'.format(lang.action_install())
- elif self.appmgr.is_service_started(app):
- status = '{}'.format(lang.status_started())
- actions = '{}'.format(lang.action_stop())
else:
- status = '{}'.format(lang.status_stopped())
- actions = '{}, {}'.format(lang.action_start(), lang.action_uninstall())
+ if self.appmgr.is_service_started(app):
+ status = '{}'.format(lang.status_started())
+ actions = '{}'.format(lang.action_stop())
+ else:
+ status = '{}'.format(lang.status_stopped())
+ actions = '{}, {}'.format(lang.action_start(), lang.action_uninstall())
+ if self.appmgr.pkgmgr.has_update(app):
+ actions = '{}, {}'.format(actions, lang.action_update())
app_data[app] = {'title': title, 'visible': visible, 'installed': installed, 'autostarted': autostarted, 'status': status, 'actions': actions}
return self.render_template('setup-apps-table.html', request, app_data=app_data)
@@ -385,6 +389,10 @@ class WSGIApp:
# Queues application uninstallation
return self.enqueue_app_action(request, self.appmgr.uninstall_app)
+ def update_app_action(self, request):
+ # Queues application update
+ return self.enqueue_app_action(request, self.appmgr.update_app)
+
def get_app_status_action(self, request):
# Gets application and queue status
return self.render_json({'ok': self.render_setup_apps_table(request)})
diff --git a/usr/lib/python3.6/vmmgr/wsgilang.py b/usr/lib/python3.6/vmmgr/wsgilang.py
index 010feb7..7a247eb 100644
--- a/usr/lib/python3.6/vmmgr/wsgilang.py
+++ b/usr/lib/python3.6/vmmgr/wsgilang.py
@@ -50,6 +50,7 @@ class WSGILang:
'action_stop': 'Zastavit',
'action_install': 'Instalovat',
'action_uninstall': 'Odinstalovat',
+ 'action_update': 'Aktualizovat',
'ssh_keys_installed': 'SSH klíče byly úspěšně změněny.',
'vpn_updated': 'Nastavení VPN bylo úspěšně změněno.',
}
diff --git a/usr/share/vmmgr/static/js/admin.js b/usr/share/vmmgr/static/js/admin.js
index e7b4c76..c339f71 100644
--- a/usr/share/vmmgr/static/js/admin.js
+++ b/usr/share/vmmgr/static/js/admin.js
@@ -15,6 +15,7 @@ $(function() {
.on('click', '.app-stop', stop_app)
.on('click', '.app-install', install_app)
.on('click', '.app-uninstall', uninstall_app)
+ .on('click', '.app-update', update_app)
.on('click', '.app-clear-status', clear_app_status);
$('#update-password').on('submit', update_password);
$('#reboot-vm').on('click', reboot_vm);
@@ -165,6 +166,10 @@ function uninstall_app(ev) {
return false;
}
+function update_app(ev) {
+ return _do_app('/update-app', ev);
+}
+
function clear_app_status(ev) {
return _do_app('/clear-app-status', ev);
}