Populate App definition members dynamically
This commit is contained in:
parent
2de52c525b
commit
7cf9a10b46
@ -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())
|
||||
|
@ -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])
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user