diff --git a/usr/bin/vmmgr b/usr/bin/vmmgr
index 8076257..a8dc8b0 100755
--- a/usr/bin/vmmgr
+++ b/usr/bin/vmmgr
@@ -38,7 +38,6 @@ parser_unregister_container.set_defaults(action='unregister-container')
parser_register_proxy = subparsers.add_parser('register-proxy')
parser_register_proxy.set_defaults(action='register-proxy')
parser_register_proxy.add_argument('app', help='Application name')
-parser_register_proxy.add_argument('host', help='Application subdomain')
parser_unregister_proxy = subparsers.add_parser('unregister-proxy')
parser_unregister_proxy.set_defaults(action='unregister-proxy')
@@ -66,7 +65,7 @@ elif args.action == 'unregister-container':
lxcmgr.unregister_container()
elif args.action == 'register-proxy':
# Used in init scripts on application startup
- vmmgr.register_proxy(args.app, args.host)
+ vmmgr.register_proxy(args.app)
elif args.action == 'unregister-proxy':
# Used in init scripts on application stop
vmmgr.unregister_proxy(args.app)
diff --git a/usr/lib/python3.6/vmmgr/crypto.py b/usr/lib/python3.6/vmmgr/crypto.py
index 6c8c42f..5236d74 100644
--- a/usr/lib/python3.6/vmmgr/crypto.py
+++ b/usr/lib/python3.6/vmmgr/crypto.py
@@ -2,6 +2,7 @@
import bcrypt
import datetime
+import hashlib
import os
from cryptography import x509
@@ -19,7 +20,7 @@ def verify_signature(file, signature):
pub_key = serialization.load_pem_public_key(f.read(), default_backend())
pub_key.verify(signature, file, ec.ECDSA(hashes.SHA512()))
-def verify_hash(file, hash):
+def verify_hash(file, expected_hash):
# Verifies SHA512 hash of a file against expected hash
sha512 = hashlib.sha512()
with open(file, 'rb') as f:
diff --git a/usr/lib/python3.6/vmmgr/pkgmgr.py b/usr/lib/python3.6/vmmgr/pkgmgr.py
index 9fbb63f..b637fd0 100644
--- a/usr/lib/python3.6/vmmgr/pkgmgr.py
+++ b/usr/lib/python3.6/vmmgr/pkgmgr.py
@@ -6,7 +6,7 @@ import requests
import shutil
import subprocess
-from werkzeug.exceptions import BadRequest, Unauthorized
+from werkzeug.exceptions import BadRequest, NotFound, Unauthorized
from . import crypto
from .paths import LXC_ROOT
@@ -28,14 +28,16 @@ class Pkg:
class PkgMgr:
def __init__(self, conf):
- self.repo_url = repo_url
self.conf = conf
self.online_packages = {}
def get_repo_resource(self, resource_url, stream=False):
- r = requests.get('{}/{}'.format(self.repo_url, resource_url), auth=self.repo_auth, timeout=5, stream=stream)
+ # Download requested repository resource
+ r = requests.get('{}/{}'.format(self.conf['repo']['url'], resource_url), auth=(self.conf['repo']['user'], self.conf['repo']['pwd']), timeout=5, stream=stream)
if r.status_code == 401:
raise Unauthorized(r.url)
+ elif r.status_code == 404:
+ raise NotFound(r.url)
elif r.status_code != 200:
raise BadRequest(r.url)
return r
@@ -45,11 +47,11 @@ class PkgMgr:
packages = self.get_repo_resource('packages').content
packages_sig = self.get_repo_resource('packages.sig').content
crypto.verify_signature(packages, packages_sig)
- return json.loads(packages)
+ self.online_packages = json.loads(packages)
def install_app(self, app, item):
# Main installation function. Wrapper for download, registration and install script
- self.online_packages = self.fetch_online_packages()
+ self.fetch_online_packages()
# Get all packages on which the app depends and which have not been installed yet
deps = [d for d in self.get_install_deps(app) if d not in self.conf['packages']]
item.bytes_total = sum(self.online_packages[d]['size'] for d in deps)
@@ -135,7 +137,7 @@ class PkgMgr:
def get_install_deps(self, name, online=True):
# Flatten dependency tree for a package while preserving the dependency order
packages = self.online_packages if online else self.conf['packages']
- deps = packages[name]['deps'].copy()
+ deps = packages[name]['depends'].copy()
for dep in deps[::-1]:
deps[:0] = [d for d in self.get_install_deps(dep, online)]
deps = list(dict.fromkeys(deps + [name]))
@@ -145,6 +147,6 @@ class PkgMgr:
# Create reverse dependency tree for all installed packages
deps = {}
for name in self.conf['packages'].copy():
- for d in self.conf['packages'][name]['deps']:
+ for d in self.conf['packages'][name]['depends']:
deps.setdefault(d, []).append(name)
return deps
diff --git a/usr/lib/python3.6/vmmgr/validator.py b/usr/lib/python3.6/vmmgr/validator.py
index cb90d11..7d199f7 100644
--- a/usr/lib/python3.6/vmmgr/validator.py
+++ b/usr/lib/python3.6/vmmgr/validator.py
@@ -25,7 +25,7 @@ def is_valid_repo_url(url):
# Check if URL is valid http(s) and doesn't contain extra parts
try:
parsed = urlparse(url)
- return parsed.scheme in ('http', 'https') and not parsed.parameters and not parsed.query and not parsed.fragment
+ return parsed.scheme in ('http', 'https') and not parsed.params and not parsed.query and not parsed.fragment
except:
pass
return False
diff --git a/usr/lib/python3.6/vmmgr/wsgiapp.py b/usr/lib/python3.6/vmmgr/wsgiapp.py
index 00d32b2..8c3d9d2 100644
--- a/usr/lib/python3.6/vmmgr/wsgiapp.py
+++ b/usr/lib/python3.6/vmmgr/wsgiapp.py
@@ -124,7 +124,7 @@ class WSGIApp:
message = request.session['msg']
del request.session['msg']
# Message is in format location:type:text
- return message.split(':', 3)
+ return message.split(':', 2)
def login_view(self, request):
redir = request.args.get('redir', '')
@@ -164,21 +164,22 @@ class WSGIApp:
# Application manager view.
repo_error = None
try:
- online_packages = self.appmgr.pkgmgr.fetch_online_packages()
+ self.appmgr.pkgmgr.fetch_online_packages()
except InvalidSignature:
repo_error = request.session.lang.invalid_packages_signature()
except Unauthorized:
repo_error = request.session.lang.repo_invalid_credentials()
except:
repo_error = request.session.lang.repo_unavailable()
- table = self.render_setup_apps_table(request, online_packages)
+ table = self.render_setup_apps_table(request)
message = self.get_session_message(request)
return self.render_html('setup-apps.html', request, repo_error=repo_error, table=table, message=message)
- def render_setup_apps_table(self, request, online_packages):
+ def render_setup_apps_table(self, request):
lang = request.session.lang
+ online_packages = self.appmgr.pkgmgr.online_packages
pending_actions = self.queue.get_actions()
- actionable_apps = sorted(set([k for k, v in online_packages.items() if 'host' in v] + list(self.conf['apps'].keys())))
+ actionable_apps = sorted(set([k for k, v in online_packages.items() if 'title' in v] + list(self.conf['apps'].keys())))
app_data = {}
for app in actionable_apps:
installed = app in self.conf['apps']
@@ -207,12 +208,18 @@ class WSGIApp:
elif item.action == self.appmgr.install_app:
if not item.started:
status = '{} ({})'.format(lang.status_downloading(), lang.status_queued())
+ elif isinstance(item.data, InvalidSignature):
+ status = '{} OK'.format(lang.repo_package_invalid_signature())
+ actions = None
+ elif isinstance(item.data, NotFound):
+ status = '{} OK'.format(lang.repo_package_missing())
+ actions = None
elif isinstance(item.data, BaseException):
status = '{} OK'.format(lang.package_manager_error())
actions = None
else:
if item.data.stage == 0:
- status = '{} ({} %)'.format(lang.status_downloading(), item.data)
+ status = '{} ({} %)'.format(lang.status_downloading(), item.data.percent_downloaded)
elif item.data.stage == 1:
status = lang.status_installing_deps()
else:
@@ -320,7 +327,7 @@ class WSGIApp:
# Update repository URL and credentials
url = request.form['repourl']
if not validator.is_valid_repo_url(url):
- request.session['msg'] = 'repo:error:{}'.format(request.session.lang.invalid_url(request.form['repourl']))
+ request.session['msg'] = 'repo:error:{}'.format(request.session.lang.invalid_url(url))
else:
self.appmgr.update_repo_settings(url, request.form['repousername'], request.form['repopassword'])
request.session['msg'] = 'repo:info:{}'.format(request.session.lang.repo_updated())
diff --git a/usr/lib/python3.6/vmmgr/wsgilang.py b/usr/lib/python3.6/vmmgr/wsgilang.py
index b6f967f..16310a3 100644
--- a/usr/lib/python3.6/vmmgr/wsgilang.py
+++ b/usr/lib/python3.6/vmmgr/wsgilang.py
@@ -26,6 +26,8 @@ class WSGILang:
'invalid_packages_signature': 'Digitální podpis seznamu balíků není platný. Kontaktujte správce distribučního serveru.',
'repo_invalid_credentials': 'Přístupové údaje k distribučnímu serveru nejsou správné.',
'repo_unavailable': 'Distribuční server není dostupný. Zkontroluje připojení k síti',
+ 'repo_package_missing': 'Požadovaný balík nebyl na distribučním serveru nalezen. Kontaktujte správce distribučního serveru.',
+ 'repo_package_invalid_hash': 'Požadovaný balík nemá spráný kontrolní součet. Zkuste akci opakovat nebo kKontaktujte správce distribučního serveru.',
'bad_password': 'Nesprávné heslo',
'password_mismatch': 'Zadaná hesla se neshodují',
'password_empty': 'Nové heslo nesmí být prázdné',