VMMgr: Unify config, add pkg size

This commit is contained in:
Disassembler 2018-10-21 10:09:02 +02:00
parent efdd1b1c68
commit 7abe6af068
Signed by: Disassembler
GPG Key ID: 524BD33A0EE29499
4 changed files with 35 additions and 24 deletions

View File

@ -1,16 +1,15 @@
# -*- coding: utf-8 -*-
import json
import os
import shutil
import subprocess
from . import config
from . import tools
from . import validator
VERSION = '0.0.1'
CONF_FILE = '/srv/vm/config.json'
ISSUE_FILE = '/etc/issue'
NGINX_DIR = '/etc/nginx/conf.d'
ACME_CRON = '/etc/periodic/daily/acme-sh'
@ -124,16 +123,10 @@ subjectAltName=DNS:{domain},DNS:*.{domain}"
class VMMgr:
def __init__(self):
# Load JSON configuration
with open(CONF_FILE, 'r') as f:
self.conf = json.load(f)
self.conf = config.Config()
self.domain = self.conf['host']['domain']
self.port = self.conf['host']['port']
def save_conf(self):
# Save a sorted JSON configuration object with indentation
with open(CONF_FILE, 'w') as f:
json.dump(self.conf, f, sort_keys=True, indent=4)
def update_login(self, app, login, password):
# Update login and password for an app in the configuration
if not validator.is_valid_app(app, self.conf):
@ -142,21 +135,21 @@ class VMMgr:
self.conf['apps'][app]['login'] = login
if password is not None:
self.conf['apps'][app]['password'] = password
self.save_conf()
self.conf.save()
def show_tiles(self, app):
# Update visibility for the app in the configuration
if not validator.is_valid_app(app, self.conf):
raise validator.InvalidValueException('app', app)
self.conf['apps'][app]['visible'] = True
self.save_conf()
self.conf.save()
def hide_tiles(self, app):
# Update visibility for the app in the configuration
if not validator.is_valid_app(app, self.conf):
raise validator.InvalidValueException('app', app)
self.conf['apps'][app]['visible'] = False
self.save_conf()
self.conf.save()
def start_app(self, app):
# Start the actual app service
@ -268,7 +261,7 @@ class VMMgr:
raise validator.InvalidValueException('port', port)
self.domain = self.conf['host']['domain'] = domain
self.port = self.conf['host']['port'] = port
self.save_conf()
self.conf.save()
# Restart all apps to trigger configuration refresh
for app in self.conf['apps']:
if tools.is_service_started(app):
@ -309,7 +302,7 @@ class VMMgr:
# Update Google Maps API key
self.conf['common']['gmaps-api-key'] = gmaps_api_key
# Save config to file
self.save_conf()
self.conf.save()
for app in self.conf['apps']:
# Restart currently running apps in order to update their config
if tools.is_service_started(app):
@ -322,7 +315,7 @@ class VMMgr:
# Update bcrypt-hashed password in config
self.conf['host']['adminpwd'] = tools.adminpwd_hash(newpassword)
# Save config to file
self.save_conf()
self.conf.save()
def create_selfsigned(self):
# Create selfsigned certificate with wildcard alternative subject name

View File

@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
import json
CONF_FILE = '/srv/vm/config.json'
class Config:
def __init__(self):
with open(CONF_FILE, 'r') as f:
self.data = json.load(f)
def save(self):
with open(CONF_FILE, 'w') as f:
json.dump(self.data, f, sort_keys=True, indent=4)
def __getitem__(self, attr):
return self.data[attr]

View File

@ -14,23 +14,18 @@ from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.serialization import load_pem_public_key
CONF_FILE = '/srv/vm/config.json'
from . import config
PUB_FILE = '/srv/vm/packages.pub'
LXC_ROOT = '/var/lib/lxc'
class PackageManager:
def __init__(self):
# Load JSON configuration
with open(CONF_FILE, 'r') as f:
self.conf = json.load(f)
self.conf = config.Config()
self.repo_url = self.conf['host']['repo']
self.online_packages = {}
def save_conf(self):
# Save a sorted JSON configuration object with indentation
with open(CONF_FILE, 'w') as f:
json.dump(self.conf, f, sort_keys=True, indent=4)
def fetch_online_packages(self):
# Fetches and verifies online packages. Can raise InvalidSignature
packages = requests.get('{}/packages'.format(self.repo_url)).content
@ -41,6 +36,7 @@ class PackageManager:
self.online_packages = json.loads(packages)
def install_package(self, name):
# Main installation function. Wrapper for download, registration and setup
self.fetch_online_packages()
for dep in self.get_deps(name):
if dep not in self.conf['packages']:
@ -64,10 +60,12 @@ class PackageManager:
os.unlink(tmp_archive)
def register_package(self, name):
# Registers a package in local configuration
metadata = self.online_packages[name]
self.conf['packages'][name] = {
'version': metadata['version'],
}
# If host definition is present, register the package as application
if 'host' in metadata:
self.conf['apps'][name] = {
'title': metadata['title'],
@ -76,9 +74,10 @@ class PackageManager:
'password': 'N/A',
'visible': False
}
self.save_conf()
self.conf.save()
def setup_package(self):
# Runs setup.sh for a package, if the script is present
setup_dir = os.path.join(LXC_ROOT, 'setup')
setup_script = os.path.join(LXC_ROOT, 'setup.sh')
if os.path.exists(setup_script):
@ -88,6 +87,7 @@ class PackageManager:
shutil.rmtree(setup_dir)
def get_deps(self, name):
# Flatten dependency tree for a package
deps = self.online_packages[name]['deps'].copy()
for dep in deps:
deps[:0] = [d for d in self.get_deps(dep) if d not in deps]

View File

@ -54,6 +54,7 @@ def pack(pkg_file):
with open(packages_file, 'r') as f:
packages = json.load(f)
packages[pkg_name] = meta
packages[pkg_name]['size'] = os.path.getsize(xz_path)
packages[pkg_name]['sha512'] = hash_file(xz_path)
with open(packages_file, 'w') as f:
json.dump(packages, f, sort_keys=True, indent=4)