Populate App definition members dynamically

This commit is contained in:
Disassembler 2020-03-29 14:58:16 +02:00
parent 2de52c525b
commit 7cf9a10b46
No known key found for this signature in database
GPG Key ID: 524BD33A0EE29499
3 changed files with 36 additions and 13 deletions

View File

@ -14,6 +14,8 @@ from .config import APPS_DIR, ONLINE_APPS_URL, PUB_APPS_DIR, TMP_APPS_DIR, LAYER
from .container import Container
from .image import Image
DEFINITION_MEMBERS = {'version', 'meta', 'autostart', 'containers'}
class App:
def __init__(self, name, define_containers=True, load_from_repo=True):
self.name = name
@ -26,20 +28,25 @@ class App:
self.set_definition(repo_local.get_app(name), define_containers)
def set_definition(self, definition, define_containers):
self.version = definition['version']
self.meta = definition['meta']
self.autostart = definition['autostart']
# Set attributes given by definition
for key in DEFINITION_MEMBERS.intersection(definition):
setattr(self, key, definition[key])
# Populate containers property with actual container objects
self.containers = [Container(container, define_containers) for container in definition['containers']]
def get_definition(self):
return {
'version': self.version,
'meta': self.meta.copy(),
'autostart': self.autostart,
'containers': [container.name for container in self.containers]
}
# Return shallow copy of image definition as dictionary
definition = {}
for key in DEFINITION_MEMBERS:
value = getattr(self, key)
if value:
definition[key] = copy.copy(value)
# Overwrite containers key with list of container names
definition['containers'] = [container.name for container in self.containers]
return definition
def download(self, observer):
# Download the archive with application scripts and install data
os.makedirs(TMP_APPS_DIR, 0o700, True)
archive_url = urllib.parse.urljoin(ONLINE_APPS_URL, f'{self.name}.tar.xz')
archive_path = os.path.join(TMP_APPS_DIR, f'{self.name}.tar.xz')
@ -48,6 +55,7 @@ class App:
repo_online.download_archive(archive_url, archive_path, definition['hash'], observer)
def unpack_downloaded(self, observer):
# Unpack downloaded archive with application scripts and install data
archive_path = os.path.join(TMP_APPS_DIR, f'{self.name}.tar.xz')
definition = repo_online.get_app(self.name)
observer.units_total = definition['size']
@ -66,6 +74,7 @@ class App:
subprocess.run(script_path, cwd=cwd, env=env, check=True)
def create_container(self, name, definition):
# Create container and enhance its definition (typically mounts) based on application requirements
container = Container(name, False)
container.set_definition(Image(definition['image']).get_definition())
if 'depends' in definition:
@ -78,6 +87,7 @@ class App:
self.containers.append(container)
def install(self):
# Install the application
definition = repo_online.get_app(self.name)
self.version = definition['version']
self.meta = definition['meta']
@ -121,17 +131,26 @@ class App:
pass
def start(self):
# Start all application containers
for container in self.containers:
container.start()
def stop(self):
# Stop all application containers
for container in self.containers:
container.stop()
def status(self):
# Return status fo all application containers
return {container.name:container.get_state() for container in sorted(self.containers)}
def set_autostart(self, autostart):
# Configure if the application should be automatically started after boot
self.autostart = autostart
repo_local.register_app(self.name, self.get_definition())
def publish(self, filename):
# Create application archive and register to publish repository
builddir = os.path.dirname(filename)
os.makedirs(PUB_APPS_DIR, 0o755, True)
files = repo_publish.TarSizeCounter()
@ -150,13 +169,10 @@ class App:
return (definition['size'], definition['dlsize'])
def unpublish(self):
# Remove the application from publish repository
repo_publish.unregister_app(self.name)
archive_path = os.path.join(PUB_APPS_DIR, f'{self.name}.tar.xz')
try:
os.unlink(archive_path)
except FileNotFoundError:
pass
def set_autostart(self, autostart):
self.autostart = autostart
repo_local.register_app(self.name, self.get_definition())

View File

@ -53,6 +53,7 @@ class Container:
self.set_definition(repo_local.get_container(name))
def set_definition(self, definition):
# Set attributes given by definition
for key in DEFINITION_MEMBERS.intersection(definition):
setattr(self, key, definition[key])

View File

@ -29,6 +29,7 @@ class Image:
self.set_definition(repo_local.get_image(name))
def set_definition(self, definition):
# Set attributes given by definition
for key in DEFINITION_MEMBERS.intersection(definition):
setattr(self, key, definition[key])
@ -50,6 +51,7 @@ class Image:
repo_local.register_image(self.name, self.get_definition())
def delete(self):
# Remove the layer from local repository and filesystem
repo_local.unregister_image(self.name)
try:
shutil.rmtree(self.layer_path)
@ -57,6 +59,7 @@ class Image:
pass
def download(self, observer):
# Download the archive with layer data
os.makedirs(TMP_LAYERS_DIR, 0o700, True)
archive_url = urllib.parse.urljoin(ONLINE_LAYERS_URL, f'{self.name}.tar.xz')
archive_path = os.path.join(TMP_LAYERS_DIR, f'{self.name}.tar.xz')
@ -65,6 +68,7 @@ class Image:
repo_online.download_archive(archive_url, archive_path, definition['hash'], observer)
def unpack_downloaded(self, observer):
# Unpack downloaded archive with layer data
archive_path = os.path.join(TMP_LAYERS_DIR, f'{self.name}.tar.xz')
definition = repo_online.get_image(self.name)
observer.units_total = definition['size']
@ -73,6 +77,7 @@ class Image:
repo_local.register_image(self.name, definition)
def publish(self):
# Create layer archive and register to publish repository
os.makedirs(PUB_LAYERS_DIR, 0o755, True)
files = repo_publish.TarSizeCounter()
archive_path = os.path.join(PUB_LAYERS_DIR, f'{self.name}.tar.xz')
@ -86,6 +91,7 @@ class Image:
return (definition['size'], definition['dlsize'])
def unpublish(self):
# Remove the layer from publish repository
repo_publish.unregister_image(self.name)
archive_path = os.path.join(PUB_LAYERS_DIR, f'{self.name}.tar.xz')
try: