Fixes to pre-abuild way of package handling

This commit is contained in:
Disassembler 2019-02-25 22:20:41 +01:00
parent 65f5bc18c0
commit d64e57ba69
No known key found for this signature in database
GPG Key ID: 524BD33A0EE29499
6 changed files with 29 additions and 18 deletions

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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 = '<span class="error">{}</span> <a href="#" class="app-clear-status">OK</a>'.format(lang.repo_package_invalid_signature())
actions = None
elif isinstance(item.data, NotFound):
status = '<span class="error">{}</span> <a href="#" class="app-clear-status">OK</a>'.format(lang.repo_package_missing())
actions = None
elif isinstance(item.data, BaseException):
status = '<span class="error">{}</span> <a href="#" class="app-clear-status">OK</a>'.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())

View File

@ -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é',