2019-09-20 10:13:41 +02:00
|
|
|
#!/usr/bin/python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
import argparse
|
2019-09-20 15:43:01 +02:00
|
|
|
import os
|
2019-09-20 10:13:41 +02:00
|
|
|
import sys
|
|
|
|
from lxcbuild.app import App
|
|
|
|
from lxcbuild.image import Image
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(description='VM application builder and packager')
|
2019-10-05 22:26:54 +02:00
|
|
|
group = parser.add_mutually_exclusive_group()
|
|
|
|
group.add_argument('-f', '--force', action='store_true', help='Force rebuild already built package')
|
|
|
|
group.add_argument('-s', '--scratch', action='store_true', help='Build container for testing purposes, i.e. without cleanup on failure and packaging')
|
|
|
|
group.add_argument('-r', '--remove-image', action='store_true', help='Delete image (including scratch) from build repository')
|
|
|
|
group.add_argument('-e', '--remove-app', action='store_true', help='Delete application from build repository')
|
|
|
|
parser.add_argument('buildarg', help='Either specific "lxcfile" or "meta" file or a directory containing at least one of them')
|
2019-09-20 10:13:41 +02:00
|
|
|
|
|
|
|
if len(sys.argv) < 2:
|
|
|
|
parser.print_usage()
|
|
|
|
sys.exit(1)
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
2019-10-05 23:09:30 +02:00
|
|
|
def build_and_pack_image(path, args):
|
2019-10-05 22:26:54 +02:00
|
|
|
image = Image()
|
|
|
|
image.force_build = args.force or args.scratch
|
|
|
|
image.scratch_build = args.scratch
|
|
|
|
image.build_and_pack(path)
|
|
|
|
|
|
|
|
def pack_app(path):
|
|
|
|
app = App()
|
|
|
|
app.pack(path)
|
|
|
|
|
|
|
|
if args.remove_image:
|
|
|
|
image = Image()
|
|
|
|
image.name = args.buildarg
|
|
|
|
image.remove()
|
|
|
|
elif args.remove_app:
|
|
|
|
app = App()
|
|
|
|
app.name = args.buildarg
|
|
|
|
app.remove()
|
2019-09-20 10:13:41 +02:00
|
|
|
else:
|
2019-10-05 22:26:54 +02:00
|
|
|
buildpath = os.path.realpath(args.buildarg)
|
|
|
|
# If the buildpath is a file, determine type from filename
|
|
|
|
if os.path.isfile(buildpath):
|
|
|
|
basename = os.path.basename(buildpath)
|
|
|
|
if basename == 'lxcfile' or basename.endswith('.lxcfile'):
|
2019-10-05 23:09:30 +02:00
|
|
|
build_and_pack_image(buildpath, args)
|
2019-10-05 22:26:54 +02:00
|
|
|
# Compose files needs to be ignored when performing scratch builds
|
|
|
|
elif not args.scratch and basename == 'meta':
|
|
|
|
pack_app(buildpath)
|
|
|
|
else:
|
|
|
|
print('Unknown file {} given, expected "lxcfile"{}'.format(buildpath, '' if args.scratch else ' or "meta"'))
|
|
|
|
sys.exit(1)
|
|
|
|
# If the buildpath is a directory, build as much as possible, unless scratch build was requested, in which case don't build anything
|
|
|
|
else:
|
|
|
|
if args.scratch:
|
2019-10-05 23:09:30 +02:00
|
|
|
lxcfile = os.path.join(buildpath, 'lxcfile')
|
|
|
|
if os.path.exists(lxcfile):
|
|
|
|
build_and_pack_image(lxcfile, args)
|
|
|
|
else:
|
|
|
|
print('Please specify an lxcfile for scratch build')
|
|
|
|
sys.exit(1)
|
|
|
|
else:
|
|
|
|
valid_dir = False
|
|
|
|
for entry in os.scandir(buildpath):
|
|
|
|
if entry.is_file() and (entry.name == 'lxcfile' or entry.name.endswith('.lxcfile')):
|
|
|
|
valid_dir = True
|
|
|
|
build_and_pack_image(entry.path, args)
|
|
|
|
meta = os.path.join(buildpath, 'meta')
|
|
|
|
if os.path.exists(meta):
|
2019-10-05 22:26:54 +02:00
|
|
|
valid_dir = True
|
2019-10-05 23:09:30 +02:00
|
|
|
pack_app(meta)
|
|
|
|
if not valid_dir:
|
|
|
|
print('Directory {} doesn\'t contain anything to build, skipping'.format(buildpath))
|