Add checks, fix build
This commit is contained in:
parent
7116566519
commit
bbfe11f557
@ -1 +1 @@
|
|||||||
Subproject commit c3b711850e02a6e228c4eb64ed82a4d1bc889ae9
|
Subproject commit 4c2616887f52b1265aa5943d1b6bd0f7d5e9f008
|
@ -2,6 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
from lxcbuild.app import App
|
from lxcbuild.app import App
|
||||||
from lxcbuild.image import Image
|
from lxcbuild.image import Image
|
||||||
@ -37,7 +38,7 @@ else:
|
|||||||
image.build_and_pack(args.force)
|
image.build_and_pack(args.force)
|
||||||
if os.path.exists(meta):
|
if os.path.exists(meta):
|
||||||
valid_dir = True
|
valid_dir = True
|
||||||
app = App(buildpath)
|
app = App(meta)
|
||||||
app.pack()
|
app.pack()
|
||||||
if not valid_dir:
|
if not valid_dir:
|
||||||
print('Directory {} doesn\'t contain anything to build, skipping'.format(buildpath))
|
print('Directory {} doesn\'t contain anything to build, skipping'.format(buildpath))
|
||||||
|
@ -1,16 +1,26 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from .builder import ImageNotFoundError
|
||||||
from .packer import Packer
|
from .packer import Packer
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
def __init__(self, metafile):
|
def __init__(self, metafile):
|
||||||
self.build_dir = os.path.dirname(metafile)
|
self.build_dir = os.path.dirname(metafile)
|
||||||
|
if os.path.basename(metafile) == 'meta':
|
||||||
self.name = os.path.basename(self.build_dir)
|
self.name = os.path.basename(self.build_dir)
|
||||||
|
else:
|
||||||
|
self.name = os.path.splitext(metafile)[0]
|
||||||
with open(metafile, 'r') as f:
|
with open(metafile, 'r') as f:
|
||||||
self.conf = json.load(f)
|
self.conf = json.load(f)
|
||||||
|
|
||||||
def pack(self):
|
def pack(self):
|
||||||
packer = Packer()
|
packer = Packer()
|
||||||
|
try:
|
||||||
packer.pack_app(self)
|
packer.pack_app(self)
|
||||||
|
except ImageNotFoundError as e:
|
||||||
|
print('Image {} not found, can\'t pack {}'.format(e, self.name))
|
||||||
|
sys.exit(1)
|
||||||
|
@ -6,7 +6,7 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from lxcmgr import lxcmgr
|
from lxcmgr import lxcmgr
|
||||||
from lxcmgr.paths import PKG_STORAGE_DIR
|
from lxcmgr.paths import LXC_STORAGE_DIR
|
||||||
|
|
||||||
class ImageExistsError(Exception):
|
class ImageExistsError(Exception):
|
||||||
pass
|
pass
|
||||||
@ -63,10 +63,10 @@ class Builder:
|
|||||||
self.set_ready(args)
|
self.set_ready(args)
|
||||||
|
|
||||||
def get_layer_path(self, layer):
|
def get_layer_path(self, layer):
|
||||||
return os.path.join(PKG_STORAGE_DIR, layer)
|
return os.path.join(LXC_STORAGE_DIR, layer)
|
||||||
|
|
||||||
def run_script(self, script):
|
def run_script(self, script):
|
||||||
lxcmgr.register_container(self.image.name, self.image.conf)
|
lxcmgr.create_container(self.image.name, self.image.conf)
|
||||||
sh = os.path.join(self.image.path, 'run.sh')
|
sh = os.path.join(self.image.path, 'run.sh')
|
||||||
with open(sh, 'w') as f:
|
with open(sh, 'w') as f:
|
||||||
f.write('#!/bin/sh\nset -ev\n\n{}\n'.format('\n'.join(script)))
|
f.write('#!/bin/sh\nset -ev\n\n{}\n'.format('\n'.join(script)))
|
||||||
@ -74,7 +74,7 @@ class Builder:
|
|||||||
os.chown(sh, 100000, 100000)
|
os.chown(sh, 100000, 100000)
|
||||||
subprocess.run(['lxc-execute', self.image.name, '--', '/bin/sh', '-lc', '/run.sh'], check=True)
|
subprocess.run(['lxc-execute', self.image.name, '--', '/bin/sh', '-lc', '/run.sh'], check=True)
|
||||||
os.unlink(sh)
|
os.unlink(sh)
|
||||||
lxcmgr.unregister_container(self.image.name)
|
lxcmgr.destroy_container(self.image.name)
|
||||||
|
|
||||||
def set_name(self, name):
|
def set_name(self, name):
|
||||||
self.image.name = name
|
self.image.name = name
|
||||||
|
@ -7,10 +7,10 @@ from cryptography.hazmat.primitives import hashes
|
|||||||
from cryptography.hazmat.primitives.asymmetric import ec
|
from cryptography.hazmat.primitives.asymmetric import ec
|
||||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||||
|
|
||||||
def sign_file(private_key, input_path):
|
def sign_file(private_key_path, input_path):
|
||||||
# Generate SHA512 signature of a file using EC private key
|
# Generate SHA512 signature of a file using EC private key
|
||||||
print('Signing packages')
|
print('Signing packages')
|
||||||
with open(private_key, 'rb') as f:
|
with open(private_key_path, 'rb') as f:
|
||||||
priv_key = load_pem_private_key(f.read(), None, default_backend())
|
priv_key = load_pem_private_key(f.read(), None, default_backend())
|
||||||
with open(input_path, 'rb') as f:
|
with open(input_path, 'rb') as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
|
@ -6,9 +6,11 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from lxcmgr.paths import LXC_STORAGE_DIR
|
from lxcmgr.paths import LXC_STORAGE_DIR
|
||||||
|
from lxcmgr.pkgmgr import PkgMgr
|
||||||
|
|
||||||
from . import crypto
|
from . import crypto
|
||||||
from .paths import APP_DIR, IMAGE_DIR, META_FILE, PRIVATE_KEY, ROOT_DIR, SIGNATURE_FILE
|
from .builder import ImageNotFoundError
|
||||||
|
from .paths import PRIVATE_KEY, REPO_APPS_DIR, REPO_IMAGES_DIR, REPO_META_FILE, REPO_SIG_FILE
|
||||||
|
|
||||||
class PackageExistsError(Exception):
|
class PackageExistsError(Exception):
|
||||||
pass
|
pass
|
||||||
@ -19,23 +21,20 @@ class Packer:
|
|||||||
self.image = None
|
self.image = None
|
||||||
self.tar_path = None
|
self.tar_path = None
|
||||||
self.xz_path = None
|
self.xz_path = None
|
||||||
|
if os.path.exists(REPO_META_FILE):
|
||||||
def load_packages_meta(self):
|
with open(REPO_META_FILE, 'r') as f:
|
||||||
if os.path.exists(PKG_META):
|
self.packages = json.load(f)
|
||||||
with open(PKG_META, 'r') as f:
|
|
||||||
return json.load(f)
|
|
||||||
else:
|
else:
|
||||||
return {'apps': {}, 'images': {}}
|
self.packages = {'apps': {}, 'images': {}}
|
||||||
|
|
||||||
def save_packages_meta(self, packages):
|
|
||||||
with open(PKG_META, 'w') as f:
|
|
||||||
json.dump(packages, f, sort_keys=True, indent=4)
|
|
||||||
|
|
||||||
|
def save_repo_meta(self):
|
||||||
|
with open(REPO_META_FILE, 'w') as f:
|
||||||
|
json.dump(self.packages, f, sort_keys=True, indent=4)
|
||||||
|
|
||||||
def pack_image(self, image, force):
|
def pack_image(self, image, force):
|
||||||
self.image = image
|
self.image = image
|
||||||
# Prepare package file names
|
# Prepare package file names
|
||||||
self.tar_path = os.path.join(IMAGE_DIR, '{}.tar'.format(self.image.name))
|
self.tar_path = os.path.join(REPO_IMAGES_DIR, '{}.tar'.format(self.image.name))
|
||||||
self.xz_path = '{}.xz'.format(self.tar_path)
|
self.xz_path = '{}.xz'.format(self.tar_path)
|
||||||
if os.path.exists(self.xz_path):
|
if os.path.exists(self.xz_path):
|
||||||
if force:
|
if force:
|
||||||
@ -60,30 +59,36 @@ class Packer:
|
|||||||
print('Compressed ', self.xz_path, '({:.2f} MB)'.format(os.path.getsize(self.xz_path)/1048576))
|
print('Compressed ', self.xz_path, '({:.2f} MB)'.format(os.path.getsize(self.xz_path)/1048576))
|
||||||
|
|
||||||
def register_image(self):
|
def register_image(self):
|
||||||
# Register package in global repository metadata file
|
# Register image in global repository metadata file
|
||||||
print('Registering package {}'.format(self.image.name))
|
print('Registering package {}'.format(self.image.name))
|
||||||
packages = self.load_packages_meta()
|
self.packages['images'][self.image.name] = self.image.conf.copy()
|
||||||
packages['images'][self.image.name] = self.image.conf.copy()
|
self.packages['images'][self.image.name]['size'] = os.path.getsize(self.xz_path)
|
||||||
packages['images'][self.image.name]['size'] = os.path.getsize(self.xz_path)
|
self.packages['images'][self.image.name]['sha512'] = crypto.hash_file(self.xz_path)
|
||||||
packages['images'][self.image.name]['sha512'] = crypto.hash_file(self.xz_path)
|
self.save_repo_meta()
|
||||||
self.save_packages_meta(packages)
|
# Register the image also to locally installed images for package manager
|
||||||
|
pm = PkgMgr()
|
||||||
|
pm.register_image(self.image.name, self.packages['images'][self.image.name])
|
||||||
|
|
||||||
def sign_packages(self):
|
def sign_packages(self):
|
||||||
signature = crypto.sign_file(PRIVATE_KEY, META_FILE)
|
signature = crypto.sign_file(PRIVATE_KEY, REPO_META_FILE)
|
||||||
with open(SIGNATURE_FILE, 'wb') as f:
|
with open(REPO_SIG_FILE, 'wb') as f:
|
||||||
f.write(signature)
|
f.write(signature)
|
||||||
|
|
||||||
def unregister_image(self):
|
def unregister_image(self):
|
||||||
# Removes package from global repository metadata file
|
# Removes package from global repository metadata file
|
||||||
packages = self.load_packages_meta()
|
if self.image.name in self.packages['images']:
|
||||||
if self.image.name in packages['images']:
|
del self.packages['images'][self.image.name]
|
||||||
del packages['images'][self.image.name]
|
self.save_repo_meta()
|
||||||
self.save_packages_meta(packages)
|
|
||||||
|
|
||||||
def pack_app(self, app):
|
def pack_app(self, app):
|
||||||
self.app = app
|
self.app = app
|
||||||
|
# Check if all images exist
|
||||||
|
for container in app.conf['containers']:
|
||||||
|
image = app.conf['containers'][container]['image']
|
||||||
|
if image not in self.packages['images']:
|
||||||
|
raise ImageNotFoundError(image)
|
||||||
# Prepare package file names
|
# Prepare package file names
|
||||||
self.tar_path = os.path.join(APP_DIR, '{}.tar'.format(self.image.name))
|
self.tar_path = os.path.join(REPO_APPS_DIR, '{}.tar'.format(self.app.name))
|
||||||
self.xz_path = '{}.xz'.format(self.tar_path)
|
self.xz_path = '{}.xz'.format(self.tar_path)
|
||||||
if os.path.exists(self.xz_path):
|
if os.path.exists(self.xz_path):
|
||||||
os.unlink(self.xz_path)
|
os.unlink(self.xz_path)
|
||||||
@ -96,14 +101,13 @@ class Packer:
|
|||||||
print('Archiving setup scripts for', self.app.name)
|
print('Archiving setup scripts for', self.app.name)
|
||||||
scripts = ('install', 'install.sh', 'upgrade', 'upgrade.sh', 'uninstall', 'uninstall.sh')
|
scripts = ('install', 'install.sh', 'upgrade', 'upgrade.sh', 'uninstall', 'uninstall.sh')
|
||||||
scripts = [s for s in scripts if os.path.exists(os.path.join(self.app.build_dir, s))]
|
scripts = [s for s in scripts if os.path.exists(os.path.join(self.app.build_dir, s))]
|
||||||
subprocess.run(['tar', '--xattrs', '-cpf', self.tar_path] + scripts, cwd=self.app.build_dir)
|
subprocess.run(['tar', '--xattrs', '-cpf', self.tar_path, '--transform', 's,^,{}/,'.format(self.app.name)] + scripts, cwd=self.app.build_dir)
|
||||||
self.compress_archive()
|
self.compress_archive()
|
||||||
|
|
||||||
def register_app(self):
|
def register_app(self):
|
||||||
# Register package in global repository metadata file
|
# Register package in global repository metadata file
|
||||||
print('Registering package {}'.format(self.app.name))
|
print('Registering package {}'.format(self.app.name))
|
||||||
packages = self.load_packages_meta()
|
self.packages['apps'][self.app.name] = self.app.conf.copy()
|
||||||
packages['apps'][self.image.name] = self.app.conf.copy()
|
self.packages['apps'][self.app.name]['size'] = os.path.getsize(self.xz_path)
|
||||||
packages['apps'][self.image.name]['size'] = os.path.getsize(self.xz_path)
|
self.packages['apps'][self.app.name]['sha512'] = crypto.hash_file(self.xz_path)
|
||||||
packages['apps'][self.image.name]['sha512'] = crypto.hash_file(self.xz_path)
|
self.save_repo_meta()
|
||||||
self.save_packages_meta(packages)
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
ROOT_DIR = '/srv/build/lxc'
|
|
||||||
IMAGE_DIR = os.path.join(ROOT_DIR, 'images')
|
|
||||||
APP_DIR = os.path.join(ROOT_DIR, 'apps')
|
|
||||||
META_FILE = os.path.join(ROOT_DIR, 'packages')
|
|
||||||
SIGNATURE_FILE = os.path.join(ROOT_DIR, 'packages.sig')
|
|
||||||
PRIVATE_KEY = '/srv/build/packages.key'
|
PRIVATE_KEY = '/srv/build/packages.key'
|
||||||
|
REPO_APPS_DIR = '/srv/build/lxc/apps'
|
||||||
|
REPO_IMAGES_DIR = '/srv/build/lxc/images'
|
||||||
|
REPO_META_FILE = '/srv/build/lxc/packages'
|
||||||
|
REPO_SIG_FILE = '/srv/build/lxc/packages.sig'
|
||||||
|
Loading…
Reference in New Issue
Block a user