Add support for installation from definition file
This commit is contained in:
parent
d2e17c8d49
commit
c2cd5b12a0
@ -40,20 +40,20 @@ def list_updates():
|
||||
return dict(sorted(apps.items()))
|
||||
|
||||
@locked()
|
||||
def install(app_name):
|
||||
def install(app_name, from_file=None):
|
||||
if app_name in podman.get_apps():
|
||||
raise AppAlreadyInstalledError(app_name)
|
||||
if app_name not in repo.get_apps():
|
||||
if not from_file and app_name not in repo.get_apps():
|
||||
raise AppNotInRepoError(app_name)
|
||||
app.install(app_name)
|
||||
app.install(app_name, from_file=from_file)
|
||||
|
||||
@locked()
|
||||
def update(app_name):
|
||||
def update(app_name, from_file=None):
|
||||
if app_name not in podman.get_apps():
|
||||
raise AppNotInstalledError(app_name)
|
||||
if app_name not in list_updates():
|
||||
if not from_file and app_name not in list_updates():
|
||||
raise AppNotUpdateableError(app_name)
|
||||
app.update(app_name)
|
||||
app.update(app_name, from_file=from_file)
|
||||
|
||||
@locked()
|
||||
def uninstall(app_name):
|
||||
|
@ -1,4 +1,5 @@
|
||||
import os
|
||||
import json
|
||||
|
||||
from . import autostart
|
||||
from . import config
|
||||
@ -11,8 +12,14 @@ class App:
|
||||
self.app_name = app_name
|
||||
self.env_file = os.path.join(config.DATA_DIR, f'{app_name}.env')
|
||||
|
||||
def install(self, is_update=False):
|
||||
definition = repo.get_apps()[self.app_name]
|
||||
def get_definition(self, from_file=None):
|
||||
if from_file:
|
||||
with open(from_file, encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
return repo.get_apps()[self.app_name]
|
||||
|
||||
def install(self, is_update=False, from_file=None):
|
||||
definition = self.get_definition(from_file)
|
||||
version = definition['version']
|
||||
containers = definition['containers']
|
||||
|
||||
@ -44,8 +51,8 @@ class App:
|
||||
self.create_pod(version)
|
||||
self.create_containers(containers)
|
||||
|
||||
def update(self):
|
||||
self.install(is_update=True)
|
||||
def update(self, from_file=None):
|
||||
self.install(is_update=True, from_file=from_file)
|
||||
|
||||
def uninstall(self):
|
||||
autostart.set_app(self.app_name, False)
|
||||
@ -124,11 +131,11 @@ class App:
|
||||
podman.create_container(self.app_name, name, image, env_file=self.env_file,
|
||||
volumes=volumes, requires=requires, hosts=hosts)
|
||||
|
||||
def install(app_name):
|
||||
App(app_name).install()
|
||||
def install(app_name, from_file=None):
|
||||
App(app_name).install(from_file=from_file)
|
||||
|
||||
def update(app_name):
|
||||
App(app_name).update()
|
||||
def update(app_name, from_file=None):
|
||||
App(app_name).update(from_file=from_file)
|
||||
|
||||
def uninstall(app_name):
|
||||
App(app_name).uninstall()
|
||||
|
@ -42,11 +42,11 @@ def listing(list_type):
|
||||
for app_name, app_version in apps.items():
|
||||
print(app_name, app_version)
|
||||
|
||||
def install(app_name):
|
||||
spoc.install(app_name)
|
||||
def install(app_name, from_file):
|
||||
spoc.install(app_name, from_file)
|
||||
|
||||
def update(app_name):
|
||||
spoc.update(app_name)
|
||||
def update(app_name, from_file):
|
||||
spoc.update(app_name, from_file)
|
||||
|
||||
def uninstall(app_name):
|
||||
spoc.uninstall(app_name)
|
||||
@ -93,10 +93,16 @@ def parse_args(args=None):
|
||||
parser_install = subparsers.add_parser('install')
|
||||
parser_install.set_defaults(action=install)
|
||||
parser_install.add_argument('app', help='Name of the application to install')
|
||||
parser_install.add_argument('--from-file',
|
||||
help='Filename containing the application definition ' \
|
||||
'to be used instead of online repository')
|
||||
|
||||
parser_update = subparsers.add_parser('update')
|
||||
parser_update.set_defaults(action=update)
|
||||
parser_update.add_argument('app', help='Name of the application to update')
|
||||
parser_update.add_argument('--from-file',
|
||||
help='Filename containing the application definition ' \
|
||||
'to be used instead of online repository')
|
||||
|
||||
parser_uninstall = subparsers.add_parser('uninstall')
|
||||
parser_uninstall.set_defaults(action=uninstall)
|
||||
@ -143,9 +149,9 @@ def main(): # pylint: disable=too-many-branches
|
||||
if args.action is listing:
|
||||
listing(args.type)
|
||||
elif args.action is install:
|
||||
install(args.app)
|
||||
install(args.app, args.from_file)
|
||||
elif args.action is update:
|
||||
update(args.app)
|
||||
update(args.app, args.from_file)
|
||||
elif args.action is uninstall:
|
||||
uninstall(args.app)
|
||||
elif args.action is start:
|
||||
|
@ -28,6 +28,26 @@ def test_init():
|
||||
assert instance.env_file == os.path.join(config.DATA_DIR, 'someapp.env')
|
||||
|
||||
@patch('spoc.repo.get_apps', return_value=MOCK_REPODATA)
|
||||
def test_get_definition(repo_get_apps):
|
||||
instance = app.App('someapp')
|
||||
definition = instance.get_definition()
|
||||
|
||||
assert definition == MOCK_REPODATA['someapp']
|
||||
|
||||
repo_get_apps.assert_called_once()
|
||||
|
||||
@patch('spoc.repo.get_apps')
|
||||
@patch('builtins.open', new_callable=mock_open, read_data=json.dumps(MOCK_REPODATA['someapp']))
|
||||
def test_get_definition_from_file(file_open, repo_get_apps):
|
||||
instance = app.App('someapp')
|
||||
definition = instance.get_definition('somefile')
|
||||
|
||||
assert definition == MOCK_REPODATA['someapp']
|
||||
|
||||
file_open.assert_called_once_with('somefile', encoding='utf-8')
|
||||
repo_get_apps.assert_not_called()
|
||||
|
||||
@patch('spoc.app.App.get_definition', return_value=MOCK_REPODATA['someapp'])
|
||||
@patch('spoc.app.App.get_existing_volumes', return_value=set('somevol'))
|
||||
@patch('spoc.app.App.remove_volumes')
|
||||
@patch('spoc.app.App.create_volumes')
|
||||
@ -37,11 +57,11 @@ def test_init():
|
||||
@patch('spoc.app.App.create_containers')
|
||||
def test_install(create_containers, create_pod, write_env_vars, #pylint: disable=too-many-arguments
|
||||
read_env_vars, create_volumes, remove_volumes,
|
||||
get_existing_volumes, repo_get_apps):
|
||||
get_existing_volumes, get_definition):
|
||||
instance = app.App('someapp')
|
||||
instance.install()
|
||||
|
||||
repo_get_apps.assert_called_once()
|
||||
get_definition.assert_called_once()
|
||||
get_existing_volumes.assert_called_once()
|
||||
remove_volumes.assert_called_once_with(set('somevol'))
|
||||
create_volumes.assert_called_once_with(set(('migrate', 'storage', 'uploads', 'postgres-data')))
|
||||
@ -50,7 +70,7 @@ def test_install(create_containers, create_pod, write_env_vars, #pylint: disable
|
||||
create_pod.assert_called_once_with('0.23.5-210416')
|
||||
create_containers.assert_called_once_with(MOCK_REPODATA['someapp']['containers'])
|
||||
|
||||
@patch('spoc.repo.get_apps', return_value=MOCK_REPODATA)
|
||||
@patch('spoc.app.App.get_definition', return_value=MOCK_REPODATA['someapp'])
|
||||
@patch('spoc.app.App.get_existing_volumes', return_value=set(('somevol', 'migrate', 'storage')))
|
||||
@patch('spoc.app.App.remove_volumes')
|
||||
@patch('spoc.app.App.create_volumes')
|
||||
@ -60,11 +80,11 @@ def test_install(create_containers, create_pod, write_env_vars, #pylint: disable
|
||||
@patch('spoc.app.App.create_containers')
|
||||
def test_update(create_containers, create_pod, write_env_vars, #pylint: disable=too-many-arguments
|
||||
read_env_vars, create_volumes, remove_volumes,
|
||||
get_existing_volumes, repo_get_apps):
|
||||
get_existing_volumes, get_definition):
|
||||
instance = app.App('someapp')
|
||||
instance.update()
|
||||
instance.update(from_file='somefile')
|
||||
|
||||
repo_get_apps.assert_called_once()
|
||||
get_definition.assert_called_once()
|
||||
get_existing_volumes.assert_called_once()
|
||||
remove_volumes.assert_called_once_with(set(('somevol',)))
|
||||
create_volumes.assert_called_once_with(set(('uploads', 'postgres-data')))
|
||||
@ -229,14 +249,14 @@ def test_module_install(instance):
|
||||
app.install('someapp')
|
||||
|
||||
instance.assert_called_once_with('someapp')
|
||||
instance.return_value.install.assert_called_once()
|
||||
instance.return_value.install.assert_called_once_with(from_file=None)
|
||||
|
||||
@patch('spoc.app.App')
|
||||
def test_module_update(instance):
|
||||
app.update('someapp')
|
||||
app.update('someapp', from_file='somefile')
|
||||
|
||||
instance.assert_called_once_with('someapp')
|
||||
instance.return_value.update.assert_called_once_with()
|
||||
instance.return_value.update.assert_called_once_with(from_file='somefile')
|
||||
|
||||
@patch('spoc.app.App')
|
||||
def test_module_uninstall(instance):
|
||||
|
@ -97,15 +97,15 @@ def test_listing_invalid(list_updates, list_online, list_installed, capsys):
|
||||
|
||||
@patch('spoc.install')
|
||||
def test_install(install):
|
||||
spoc_cli.install('someapp')
|
||||
spoc_cli.install('someapp', 'somefile')
|
||||
|
||||
install.assert_called_once_with('someapp')
|
||||
install.assert_called_once_with('someapp', 'somefile')
|
||||
|
||||
@patch('spoc.update')
|
||||
def test_update(update):
|
||||
spoc_cli.update('someapp')
|
||||
spoc_cli.update('someapp', None)
|
||||
|
||||
update.assert_called_once_with('someapp')
|
||||
update.assert_called_once_with('someapp', None)
|
||||
|
||||
@patch('spoc.uninstall')
|
||||
def test_uninstall(uninstall):
|
||||
@ -212,14 +212,14 @@ def test_main_listing_online(listing):
|
||||
def test_main_install(install):
|
||||
spoc_cli.main()
|
||||
|
||||
install.assert_called_once_with('someapp')
|
||||
install.assert_called_once_with('someapp', None)
|
||||
|
||||
@patch('sys.argv', ['foo', 'update', 'someapp'])
|
||||
@patch('sys.argv', ['foo', 'update', '--from-file', 'somefile', 'someapp'])
|
||||
@patch('spoc_cli.update')
|
||||
def test_main_update(update):
|
||||
spoc_cli.main()
|
||||
|
||||
update.assert_called_once_with('someapp')
|
||||
update.assert_called_once_with('someapp', 'somefile')
|
||||
|
||||
@patch('sys.argv', ['foo', 'uninstall', 'someapp'])
|
||||
@patch('spoc_cli.uninstall')
|
||||
|
@ -66,11 +66,20 @@ def test_list_updates(podman_get_apps, repo_get_apps):
|
||||
@patch('spoc.app.install')
|
||||
def test_install(app_install, podman_get_apps, repo_get_apps):
|
||||
spoc.install.__wrapped__('someapp')
|
||||
#spoc.install('someapp')
|
||||
|
||||
podman_get_apps.assert_called_once()
|
||||
repo_get_apps.assert_called_once()
|
||||
app_install.assert_called_once_with('someapp')
|
||||
app_install.assert_called_once_with('someapp', from_file=None)
|
||||
|
||||
@patch('spoc.repo.get_apps')
|
||||
@patch('spoc.podman.get_apps', return_value={})
|
||||
@patch('spoc.app.install')
|
||||
def test_install_from_file(app_install, podman_get_apps, repo_get_apps):
|
||||
spoc.install.__wrapped__('someapp', 'somefile')
|
||||
|
||||
podman_get_apps.assert_called_once()
|
||||
repo_get_apps.assert_not_called()
|
||||
app_install.assert_called_once_with('someapp', from_file='somefile')
|
||||
|
||||
@patch('spoc.repo.get_apps', return_value={'someapp': {'version': '0.1'}})
|
||||
@patch('spoc.podman.get_apps', return_value={'someapp': '0.1'})
|
||||
@ -102,7 +111,7 @@ def test_update(app_update, podman_get_apps, list_updates):
|
||||
|
||||
podman_get_apps.assert_called_once()
|
||||
list_updates.assert_called_once()
|
||||
app_update.assert_called_once_with('someapp')
|
||||
app_update.assert_called_once_with('someapp', from_file=None)
|
||||
|
||||
@patch('spoc.list_updates', return_value={})
|
||||
@patch('spoc.podman.get_apps', return_value={})
|
||||
|
Loading…
Reference in New Issue
Block a user