Implement App basics and publish/unpublish
This commit is contained in:
parent
8a39528773
commit
e71514c6f9
@ -3,12 +3,26 @@
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
from pkg_resources import parse_version
|
||||||
|
|
||||||
from spoc import publisher
|
from spoc import repo_local
|
||||||
|
from spoc import repo_online
|
||||||
|
from spoc import repo_publish
|
||||||
|
from spoc.app import App
|
||||||
from spoc.cli import readable_size
|
from spoc.cli import readable_size
|
||||||
|
|
||||||
def listing():
|
def listing(list_type):
|
||||||
raise NotImplementedException()
|
if list_type == 'installed':
|
||||||
|
apps = repo_local.get_apps()
|
||||||
|
elif list_type == 'online':
|
||||||
|
apps = repo_online.get_apps()
|
||||||
|
elif list_type == 'updates':
|
||||||
|
online_apps = repo_online.get_apps()
|
||||||
|
apps = [a for a,d in repo_local.get_apps() if a in online_apps and parse_version(online_apps[a]['version']) > parse_version(d['version'])]
|
||||||
|
elif list_type == 'published':
|
||||||
|
apps = repo_publish.get_apps()
|
||||||
|
for app in apps:
|
||||||
|
print(app)
|
||||||
|
|
||||||
def install():
|
def install():
|
||||||
raise NotImplementedException()
|
raise NotImplementedException()
|
||||||
@ -28,23 +42,20 @@ def stop():
|
|||||||
def status():
|
def status():
|
||||||
raise NotImplementedException()
|
raise NotImplementedException()
|
||||||
|
|
||||||
def publish(composefile, do_publish):
|
def publish(filename, force):
|
||||||
|
app_name = os.path.basename(os.path.dirname(os.path.abspath(filename)))
|
||||||
# Check if publishing is needed and attempt to publish the application
|
# Check if publishing is needed and attempt to publish the application
|
||||||
app_name = os.path.basename(os.path.dirname(filepath))
|
if force or app_name not in repo_publish.get_apps():
|
||||||
if not do_publish:
|
app = App(app_name, False)
|
||||||
try:
|
print(f'Publishing application {app_name} from file {os.path.abspath(filename)}')
|
||||||
publisher.get_app(app_name)
|
app.unpublish()
|
||||||
except KeyError:
|
size, dlsize = app.publish(filename)
|
||||||
do_publish = True
|
print(f'Application {app_name} compressed from {readable_size(size)} to {readable_size(dlsize)} and published successfully')
|
||||||
if do_publish:
|
|
||||||
print(f'Publishing application "{app_name}"')
|
|
||||||
package = publisher.publish_app(app_name)['package']
|
|
||||||
print(f'Application "{app_name}" compressed from {readable_size(package["size"])} to {readable_size(package["dlsize"])}')
|
|
||||||
else:
|
else:
|
||||||
print(f'Application "{app_name}" already published, skipping publishing')
|
print(f'Application {app_name} already published, skipping publish task')
|
||||||
|
|
||||||
def unpublish():
|
def unpublish(app_name):
|
||||||
raise NotImplementedException()
|
App(app_name, False).unpublish()
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='SPOC application manager')
|
parser = argparse.ArgumentParser(description='SPOC application manager')
|
||||||
parser.set_defaults(action=None)
|
parser.set_defaults(action=None)
|
||||||
@ -52,7 +63,7 @@ subparsers = parser.add_subparsers()
|
|||||||
|
|
||||||
parser_list = subparsers.add_parser('list')
|
parser_list = subparsers.add_parser('list')
|
||||||
parser_list.set_defaults(action=listing)
|
parser_list.set_defaults(action=listing)
|
||||||
parser_list.add_argument('type', choices=('installed', 'online', 'upgrades', 'published'), default='installed', const='installed', nargs='?')
|
parser_list.add_argument('type', choices=('installed', 'online', 'updates', 'published'), default='installed', const='installed', nargs='?')
|
||||||
|
|
||||||
parser_install = subparsers.add_parser('install')
|
parser_install = subparsers.add_parser('install')
|
||||||
parser_install.set_defaults(action=install)
|
parser_install.set_defaults(action=install)
|
||||||
@ -81,7 +92,7 @@ parser_status.add_argument('app')
|
|||||||
parser_publish = subparsers.add_parser('publish')
|
parser_publish = subparsers.add_parser('publish')
|
||||||
parser_publish.set_defaults(action=publish)
|
parser_publish.set_defaults(action=publish)
|
||||||
parser_publish.add_argument('-f', '--force', action='store_true', help='Force republish already published application')
|
parser_publish.add_argument('-f', '--force', action='store_true', help='Force republish already published application')
|
||||||
parser_publish.add_argument('file')
|
parser_publish.add_argument('filename')
|
||||||
|
|
||||||
parser_unpublish = subparsers.add_parser('unpublish')
|
parser_unpublish = subparsers.add_parser('unpublish')
|
||||||
parser_unpublish.set_defaults(action=unpublish)
|
parser_unpublish.set_defaults(action=unpublish)
|
||||||
@ -104,9 +115,8 @@ elif args.action is stop:
|
|||||||
elif args.action is status:
|
elif args.action is status:
|
||||||
status(args.app)
|
status(args.app)
|
||||||
elif args.action is publish:
|
elif args.action is publish:
|
||||||
publish(args.file, args.force)
|
publish(args.filename, args.force)
|
||||||
elif args.action is unpublish:
|
elif args.action is unpublish:
|
||||||
unpublish(args.app)
|
unpublish(args.app)
|
||||||
else:
|
else:
|
||||||
parser.print_usage()
|
parser.print_usage()
|
||||||
|
|
||||||
|
@ -1,6 +1,57 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import tarfile
|
||||||
|
|
||||||
|
from . import repo_local
|
||||||
|
from . import repo_publish
|
||||||
|
from .config import PUB_APPS_DIR
|
||||||
|
from .container import Container
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
def __init__(self):
|
def __init__(self, name, load_from_repo=True):
|
||||||
self.name - None
|
self.name = name
|
||||||
self.version = None
|
self.version = None
|
||||||
self.meta = {}
|
self.meta = {}
|
||||||
self.containers = []
|
self.containers = []
|
||||||
|
if load_from_repo:
|
||||||
|
self.set_definition(repo_local.get_app(name))
|
||||||
|
|
||||||
|
def set_definition(self, definition):
|
||||||
|
self.version = definition['version']
|
||||||
|
self.meta = definition['meta']
|
||||||
|
self.containers = [Container(container) for container in definition['containers']]
|
||||||
|
|
||||||
|
def get_definition(self):
|
||||||
|
return {
|
||||||
|
'version': self.version,
|
||||||
|
'meta': self.meta.copy(),
|
||||||
|
'containers': [container.name for container in self.containers]
|
||||||
|
}
|
||||||
|
|
||||||
|
def publish(self, filename):
|
||||||
|
builddir = os.path.dirname(filename)
|
||||||
|
os.makedirs(PUB_APPS_DIR, 0o700, True)
|
||||||
|
files = repo_publish.TarSizeCounter()
|
||||||
|
archive_path = os.path.join(PUB_APPS_DIR, f'{self.name}.tar.xz')
|
||||||
|
with tarfile.open(archive_path, 'w:xz') as tar:
|
||||||
|
for content in ('install', 'install.sh', 'update', 'update.sh', 'uninstall', 'uninstall.sh'):
|
||||||
|
content_path = os.path.join(builddir, content)
|
||||||
|
if os.path.exists(content_path):
|
||||||
|
tar.add(content_path, os.path.join(self.name, content), filter=files.add_file)
|
||||||
|
with open(filename) as f:
|
||||||
|
definition = json.load(f)
|
||||||
|
definition['size'] = files.size
|
||||||
|
definition['dlsize'] = os.path.getsize(archive_path)
|
||||||
|
definition['hash'] = repo_publish.sign_file(archive_path).hex()
|
||||||
|
repo_publish.register_app(self.name, definition)
|
||||||
|
return (definition['size'], definition['dlsize'])
|
||||||
|
|
||||||
|
def unpublish(self):
|
||||||
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user