Use methods as argparse actions, return definitions as shallow copies

This commit is contained in:
Disassembler 2020-02-18 12:33:54 +01:00
parent 5e1b153c3d
commit 9e9b3da0dd
No known key found for this signature in database
GPG Key ID: 524BD33A0EE29499
6 changed files with 59 additions and 79 deletions

View File

@ -7,16 +7,6 @@ import os
from spoc import publisher from spoc import publisher
from spoc.cli import readable_size from spoc.cli import readable_size
ACTION_LIST = 1
ACTION_INSTALL = 2
ACTION_UPGRADE = 3
ACTION_UNINSTALL = 4
ACTION_START = 5
ACTION_STOP = 6
ACTION_STATUS = 7
ACTION_PUBLISH = 8
ACTION_UNPUBLISH = 9
def listing(): def listing():
raise NotImplementedException() raise NotImplementedException()
@ -61,61 +51,61 @@ parser.set_defaults(action=None)
subparsers = parser.add_subparsers() subparsers = parser.add_subparsers()
parser_list = subparsers.add_parser('list') parser_list = subparsers.add_parser('list')
parser_list.set_defaults(action=ACTION_LIST) 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', 'upgrades', 'published'), default='installed', const='installed', nargs='?')
parser_install = subparsers.add_parser('install') parser_install = subparsers.add_parser('install')
parser_install.set_defaults(action=ACTION_INSTALL) parser_install.set_defaults(action=install)
parser_install.add_argument('app') parser_install.add_argument('app')
parser_upgrade = subparsers.add_parser('upgrade') parser_upgrade = subparsers.add_parser('upgrade')
parser_upgrade.set_defaults(action=ACTION_UPGRADE) parser_upgrade.set_defaults(action=upgrade)
parser_upgrade.add_argument('app') parser_upgrade.add_argument('app')
parser_uninstall = subparsers.add_parser('uninstall') parser_uninstall = subparsers.add_parser('uninstall')
parser_uninstall.set_defaults(action=ACTION_UNINSTALL) parser_uninstall.set_defaults(action=uninstall)
parser_uninstall.add_argument('app') parser_uninstall.add_argument('app')
parser_start = subparsers.add_parser('start') parser_start = subparsers.add_parser('start')
parser_start.set_defaults(action=ACTION_START) parser_start.set_defaults(action=start)
parser_start.add_argument('app') parser_start.add_argument('app')
parser_stop = subparsers.add_parser('stop') parser_stop = subparsers.add_parser('stop')
parser_stop.set_defaults(action=ACTION_STOP) parser_stop.set_defaults(action=stop)
parser_stop.add_argument('app') parser_stop.add_argument('app')
parser_status = subparsers.add_parser('status') parser_status = subparsers.add_parser('status')
parser_status.set_defaults(action=ACTION_STATUS) parser_status.set_defaults(action=status)
parser_status.add_argument('app') parser_status.add_argument('app')
parser_publish = subparsers.add_parser('publish') parser_publish = subparsers.add_parser('publish')
parser_publish.set_defaults(action=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('file')
parser_unpublish = subparsers.add_parser('unpublish') parser_unpublish = subparsers.add_parser('unpublish')
parser_unpublish.set_defaults(action=ACTION_UNPUBLISH) parser_unpublish.set_defaults(action=unpublish)
parser_unpublish.add_argument('app') parser_unpublish.add_argument('app')
args = parser.parse_args() args = parser.parse_args()
if args.action == ACTION_LIST: if args.action is listing:
listing(args.type) listing(args.type)
elif args.action == ACTION_INSTALL: elif args.action is install:
install(args.app) install(args.app)
elif args.action == ACTION_UPGRADE: elif args.action is upgrade:
upgrade(args.app) upgrade(args.app)
elif args.action == ACTION_UNINSTALL: elif args.action is uninstall:
uninstall(args.app) uninstall(args.app)
elif args.action == ACTION_START: elif args.action is start:
start(args.app) start(args.app)
elif args.action == ACTION_STOP: elif args.action is stop:
stop(args.app) stop(args.app)
elif args.action == ACTION_STATUS: elif args.action is status:
status(args.app) status(args.app)
elif args.action == ACTION_PUBLISH: elif args.action is publish:
publish(args.file, args.force) publish(args.file, args.force)
elif args.action == ACTION_UNPUBLISH: elif args.action is unpublish:
unpublish(args.app) unpublish(args.app)
else: else:
parser.print_usage() parser.print_usage()

View File

@ -10,15 +10,6 @@ from spoc.container import Container, STATE_RUNNING, STATE_STOPPED
from spoc.image import Image from spoc.image import Image
from spoc.config import VOLUME_DIR from spoc.config import VOLUME_DIR
ACTION_LIST = 1
ACTION_CREATE = 2
ACTION_MODIFY = 3
ACTION_DESTROY = 4
ACTION_START = 5
ACTION_STOP = 6
ACTION_STATUS = 7
ACTION_EXEC = 8
def listing(state): def listing(state):
if state == 'all': if state == 'all':
containers = repo_local.get_containers().keys() containers = repo_local.get_containers().keys()
@ -115,11 +106,11 @@ parser.set_defaults(action=None)
subparsers = parser.add_subparsers() subparsers = parser.add_subparsers()
parser_list = subparsers.add_parser('list') parser_list = subparsers.add_parser('list')
parser_list.set_defaults(action=ACTION_LIST) parser_list.set_defaults(action=listing)
parser_list.add_argument('type', choices=('all', 'running', 'stopped'), default='all', const='all', nargs='?') parser_list.add_argument('type', choices=('all', 'running', 'stopped'), default='all', const='all', nargs='?')
parser_create = subparsers.add_parser('create') parser_create = subparsers.add_parser('create')
parser_create.set_defaults(action=ACTION_CREATE) parser_create.set_defaults(action=create)
parser_create.add_argument('-d', '--depends', action='append', default=[], help='Add another container as a start dependency') parser_create.add_argument('-d', '--depends', action='append', default=[], help='Add another container as a start dependency')
parser_create.add_argument('-m', '--mount', action='append', default=[], help='Add mount to the container - format volume:mountpoint') parser_create.add_argument('-m', '--mount', action='append', default=[], help='Add mount to the container - format volume:mountpoint')
parser_create.add_argument('-e', '--env', action='append', default=[], help='Add environment variable for the container - format KEY=value') parser_create.add_argument('-e', '--env', action='append', default=[], help='Add environment variable for the container - format KEY=value')
@ -134,7 +125,7 @@ parser_create.add_argument('container')
parser_create.add_argument('image') parser_create.add_argument('image')
parser_modify = subparsers.add_parser('modify') parser_modify = subparsers.add_parser('modify')
parser_modify.set_defaults(action=ACTION_MODIFY) parser_modify.set_defaults(action=modify)
parser_modify.add_argument('-d', '--depends', action='append', default=[], help='Add another container as a start dependency - prepend the name with ! to remove the dependency') parser_modify.add_argument('-d', '--depends', action='append', default=[], help='Add another container as a start dependency - prepend the name with ! to remove the dependency')
parser_modify.add_argument('-m', '--mount', action='append', default=[], help='Add mount to the container - format volume:mountpoint - specify empty mountpoint to remove the mount') parser_modify.add_argument('-m', '--mount', action='append', default=[], help='Add mount to the container - format volume:mountpoint - specify empty mountpoint to remove the mount')
parser_modify.add_argument('-e', '--env', action='append', default=[], help='Add environment variable for the container - format KEY=value - specify empty value to remove the env') parser_modify.add_argument('-e', '--env', action='append', default=[], help='Add environment variable for the container - format KEY=value - specify empty value to remove the env')
@ -148,23 +139,23 @@ parser_modify.add_argument('-a', '--autostart', choices=('on', 'off'), help='Set
parser_modify.add_argument('container') parser_modify.add_argument('container')
parser_destroy = subparsers.add_parser('destroy') parser_destroy = subparsers.add_parser('destroy')
parser_destroy.set_defaults(action=ACTION_DESTROY) parser_destroy.set_defaults(action=destroy)
parser_destroy.add_argument('container') parser_destroy.add_argument('container')
parser_start = subparsers.add_parser('start') parser_start = subparsers.add_parser('start')
parser_start.set_defaults(action=ACTION_START) parser_start.set_defaults(action=start)
parser_start.add_argument('container') parser_start.add_argument('container')
parser_stop = subparsers.add_parser('stop') parser_stop = subparsers.add_parser('stop')
parser_stop.set_defaults(action=ACTION_STOP) parser_stop.set_defaults(action=stop)
parser_stop.add_argument('container') parser_stop.add_argument('container')
parser_status = subparsers.add_parser('status') parser_status = subparsers.add_parser('status')
parser_status.set_defaults(action=ACTION_STATUS) parser_status.set_defaults(action=status)
parser_status.add_argument('container') parser_status.add_argument('container')
parser_exec = subparsers.add_parser('exec') parser_exec = subparsers.add_parser('exec')
parser_exec.set_defaults(action=ACTION_EXEC) parser_exec.set_defaults(action=execute)
parser_exec.add_argument('-u', '--uid', help='Sets the command UID') parser_exec.add_argument('-u', '--uid', help='Sets the command UID')
parser_exec.add_argument('-g', '--gid', help='Sets the command GID') parser_exec.add_argument('-g', '--gid', help='Sets the command GID')
parser_exec.add_argument('container') parser_exec.add_argument('container')
@ -172,21 +163,21 @@ parser_exec.add_argument('command', nargs=argparse.REMAINDER)
args = parser.parse_args() args = parser.parse_args()
if args.action == ACTION_LIST: if args.action is listing:
listing(args.type) listing(args.type)
elif args.action == ACTION_CREATE: elif args.action is create:
create(args.container, args.image, args.depends, args.mount, args.env, args.uid, args.gid, args.cmd, args.workdir, args.ready, args.stopsig, args.autostart) create(args.container, args.image, args.depends, args.mount, args.env, args.uid, args.gid, args.cmd, args.workdir, args.ready, args.stopsig, args.autostart)
elif args.action == ACTION_MODIFY: elif args.action is modify:
modify(args.container, args.depends, args.mount, args.env, args.uid, args.gid, args.cmd, args.workdir, args.ready, args.stopsig, args.autostart) modify(args.container, args.depends, args.mount, args.env, args.uid, args.gid, args.cmd, args.workdir, args.ready, args.stopsig, args.autostart)
elif args.action == ACTION_DESTROY: elif args.action is destroy:
destroy(args.container) destroy(args.container)
elif args.action == ACTION_START: elif args.action is start:
start(args.container) start(args.container)
elif args.action == ACTION_STOP: elif args.action is stop:
stop(args.container) stop(args.container)
elif args.action == ACTION_STATUS: elif args.action is status:
status(args.container) status(args.container)
elif args.action == ACTION_EXEC: elif args.action is execute:
execute(args.container, args.command, args.uid, args.gid) execute(args.container, args.command, args.uid, args.gid)
else: else:
parser.print_usage() parser.print_usage()

View File

@ -13,14 +13,6 @@ from spoc.image import Image
from spoc.imagebuilder import ImageBuilder from spoc.imagebuilder import ImageBuilder
from spoc.cli import ActionQueue, readable_size from spoc.cli import ActionQueue, readable_size
ACTION_LIST = 1
ACTION_DOWNLOAD = 2
ACTION_DELETE = 3
ACTION_CLEAN = 4
ACTION_BUILD = 5
ACTION_PUBLISH = 6
ACTION_UNPUBLISH = 7
def get_image_name(file_path): def get_image_name(file_path):
# Read and return image name from image file # Read and return image name from image file
with open(file_path) as f: with open(file_path) as f:
@ -116,50 +108,50 @@ parser.set_defaults(action=None)
subparsers = parser.add_subparsers() subparsers = parser.add_subparsers()
parser_list = subparsers.add_parser('list') parser_list = subparsers.add_parser('list')
parser_list.set_defaults(action=ACTION_LIST) parser_list.set_defaults(action=listing)
parser_list.add_argument('type', choices=('installed', 'online', 'published'), default='installed', const='installed', nargs='?') parser_list.add_argument('type', choices=('installed', 'online', 'published'), default='installed', const='installed', nargs='?')
parser_download = subparsers.add_parser('download') parser_download = subparsers.add_parser('download')
parser_download.set_defaults(action=ACTION_DOWNLOAD) parser_download.set_defaults(action=download)
parser_download.add_argument('image') parser_download.add_argument('image')
parser_delete = subparsers.add_parser('delete') parser_delete = subparsers.add_parser('delete')
parser_delete.set_defaults(action=ACTION_DELETE) parser_delete.set_defaults(action=delete)
parser_delete.add_argument('image') parser_delete.add_argument('image')
parser_clean = subparsers.add_parser('clean') parser_clean = subparsers.add_parser('clean')
parser_clean.set_defaults(action=ACTION_CLEAN) parser_clean.set_defaults(action=clean)
parser_build = subparsers.add_parser('build') parser_build = subparsers.add_parser('build')
parser_build.set_defaults(action=ACTION_BUILD) parser_build.set_defaults(action=build)
parser_build.add_argument('-f', '--force', action='store_true', help='Force rebuild already existing image') parser_build.add_argument('-f', '--force', action='store_true', help='Force rebuild already existing image')
parser_build.add_argument('-p', '--publish', action='store_true', help='Publish the image after successful build') parser_build.add_argument('-p', '--publish', action='store_true', help='Publish the image after successful build')
parser_build.add_argument('file') parser_build.add_argument('file')
parser_publish = subparsers.add_parser('publish') parser_publish = subparsers.add_parser('publish')
parser_publish.set_defaults(action=ACTION_PUBLISH) parser_publish.set_defaults(action=publish)
parser_publish.add_argument('-f', '--force', action='store_true', help='Force republish already published image') parser_publish.add_argument('-f', '--force', action='store_true', help='Force republish already published image')
parser_publish.add_argument('image') parser_publish.add_argument('image')
parser_unpublish = subparsers.add_parser('unpublish') parser_unpublish = subparsers.add_parser('unpublish')
parser_unpublish.set_defaults(action=ACTION_UNPUBLISH) parser_unpublish.set_defaults(action=unpublish)
parser_unpublish.add_argument('image') parser_unpublish.add_argument('image')
args = parser.parse_args() args = parser.parse_args()
if args.action == ACTION_LIST: if args.action is listing:
listing(args.type) listing(args.type)
elif args.action == ACTION_DOWNLOAD: elif args.action is download:
download(args.image) download(args.image)
elif args.action == ACTION_DELETE: elif args.action is delete:
delete(args.image) delete(args.image)
elif args.action == ACTION_CLEAN: elif args.action is clean:
clean() clean()
elif args.action == ACTION_BUILD: elif args.action is build:
build(args.file, args.force, args.publish) build(args.file, args.force, args.publish)
elif args.action == ACTION_PUBLISH: elif args.action is publish:
publish(args.image, args.force) publish(args.image, args.force)
elif args.action == ACTION_UNPUBLISH: elif args.action is unpublish:
unpublish(args.image) unpublish(args.image)
else: else:
parser.print_usage() parser.print_usage()

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import copy
import os import os
import shlex import shlex
import shutil import shutil
@ -56,11 +57,12 @@ class Container:
setattr(self, key, definition[key]) setattr(self, key, definition[key])
def get_definition(self): def get_definition(self):
# Return shallow copy of container definition as dictionary
definition = {} definition = {}
for key in DEFINITION_MEMBERS: for key in DEFINITION_MEMBERS:
value = getattr(self, key) value = getattr(self, key)
if value: if value:
definition[key] = value definition[key] = copy.copy(value)
return definition return definition
def get_state(self): def get_state(self):

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import copy
import os import os
import shutil import shutil
import tarfile import tarfile
@ -35,11 +36,16 @@ class Image:
setattr(self, key, definition[key]) setattr(self, key, definition[key])
def get_definition(self, including_self_layer=False): def get_definition(self, including_self_layer=False):
# Return shallow copy of image definition as dictionary
definition = {} definition = {}
for key in DEFINITION_MEMBERS: for key in DEFINITION_MEMBERS:
value = getattr(self, key) value = getattr(self, key)
if value: if value:
definition[key] = value definition[key] = copy.copy(value)
# Always add layers in definition even if there are none to ease processing elsewhere
if 'layers' not in definition:
definition['layers'] = []
# Add the image's layer as tompost, if requested (useful for container creation)
if including_self_layer: if including_self_layer:
definition['layers'].append(self.name) definition['layers'].append(self.name)
return definition return definition

View File

@ -42,7 +42,6 @@ class ImageBuilder:
elif 'FROM' == directive: elif 'FROM' == directive:
# Set the values of image from which this one inherits # Set the values of image from which this one inherits
self.image.set_definition(Image(args).get_definition(True)) self.image.set_definition(Image(args).get_definition(True))
self.image.layers.append(self.image.name)
elif 'COPY' == directive: elif 'COPY' == directive:
srcdst = args.split() srcdst = args.split()
self.copy_files(srcdst[0], srcdst[1] if len(srcdst) > 1 else '') self.copy_files(srcdst[0], srcdst[1] if len(srcdst) > 1 else '')
@ -99,7 +98,7 @@ class ImageBuilder:
if not uid.isdigit() or not gid.isdigit(): if not uid.isdigit() or not gid.isdigit():
# Resolve the UID/GID from container if either of them is entered as string # Resolve the UID/GID from container if either of them is entered as string
container = Container(self.image.name, False) container = Container(self.image.name, False)
container.set_definition(self.image.get_definition()) container.set_definition(self.image.get_definition(True))
container.create() container.create()
uid,gid = container.get_uidgid(uid, gid) uid,gid = container.get_uidgid(uid, gid)
container.destroy() container.destroy()