From e58ab60bd82ff1fb0f1af2ef23e1b78fe836e52d Mon Sep 17 00:00:00 2001 From: William Petit Date: Sat, 11 Feb 2017 11:51:01 +0100 Subject: [PATCH] Refactoring et mise en place des tests --- .gitignore | 1 + Makefile | 2 + package | 153 ++++++++++-------- .../debian/dummy-project/debian/changelog | 5 + test/data/debian/dummy-project/debian/compat | 1 + test/data/debian/dummy-project/debian/control | 13 ++ test/data/debian/dummy-project/debian/rules | 8 + .../debian/dummy-project/debian/source/format | 1 + test/package_test.py | 16 ++ 9 files changed, 137 insertions(+), 63 deletions(-) create mode 100644 Makefile create mode 100644 test/data/debian/dummy-project/debian/changelog create mode 100644 test/data/debian/dummy-project/debian/compat create mode 100644 test/data/debian/dummy-project/debian/control create mode 100644 test/data/debian/dummy-project/debian/rules create mode 100644 test/data/debian/dummy-project/debian/source/format create mode 100644 test/package_test.py diff --git a/.gitignore b/.gitignore index bab4f0f..0cc9317 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ packages *.log *~ __pycache__ +*.pyc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6f08439 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +test: + python3 -m unittest discover test "*_test.py" diff --git a/package b/package index b036bee..de6ab43 100755 --- a/package +++ b/package @@ -6,8 +6,8 @@ sys.path.append(os.path.dirname(__file__) + '/lib') import tamarin, system, rkt -def configure_args_parser(): - +def create_args_parser(): + '''Return a new configured ArgumentParser''' profile_names = tamarin.get_available_profile_names() parser = argparse.ArgumentParser(description="Generate packages for various GNU/Linux distributions") @@ -21,11 +21,87 @@ def configure_args_parser(): return parser +def download_and_extract_rkt(dest_dir, verbose=True): + '''Download and extract rkt to the given destination directory''' + rkt_archive_path = tamarin.download_rkt() + system.extract_tar(rkt_archive_path, workspace_tmp) + rkt_archive_dir = tamarin.get_rkt_achive_dest_dir() + shutil.rmtree(local_rkt_dir, ignore_errors=True) + os.rename(rkt_archive_dir, dest_dir) + +def download_and_extract_acbuild(dest_dir, verbose=True): + '''Download and extract acbuild to the given destination directory''' + acbuild_archive_path = tamarin.download_acbuild() + system.extract_tar(acbuild_archive_path, workspace_tmp) + acbuild_archive_dir = tamarin.get_acbuild_achive_dest_dir() + shutil.rmtree(local_acbuild_dir, ignore_errors=True) + os.rename(acbuild_archive_dir, dest_dir) + +def get_cached_image_path(profile): + '''Compute and return the path for an hypothetic cached image for the given profile''' + containerbuild_hooks = profile['containerbuild']['hooks'] + hasher = hashlib.sha1() + hasher.update(base_image.encode()) + hasher.update(containerbuild_hooks.encode()) + image_hash = hasher.hexdigest() + cache_dir = tamarin.get_workspace_subdir('cache') + return os.path.join(os.sep, cache_dir, '{:s}.aci'.format(image_hash[:12])); + +def build_image(build_workspace, aci_file, base_image, profile): + + acbuild_flags = ["--modify", aci_file, "--work-path", build_workspace] + + # Find and export base image from rkt' store + name_pattern = base_image.split('/')[-1] + '$' + image = rkt.find_image_by_name(name_pattern, rkt_flags=rkt_flags) + rkt.export_image(image['id'], aci_file, rkt_flags=rkt_flags); + + # Build image + tamarin.run_acbuild(acbuild_flags+["set-name", "image_{:d}".format(pid)]) + tamarin.run_acbuild(acbuild_flags+["mount", "add", "src", "/src", "--read-only"]) + tamarin.run_acbuild(acbuild_flags+["mount", "add", "dist", "/dist"]) + tamarin.run_acbuild(acbuild_flags+["mount", "add", "tamarin-hooks", "/tamarin/hooks", "--read-only"]) + tamarin.run_acbuild(acbuild_flags+["mount", "add", "tamarin-lib", "/tamarin/lib", "--read-only"]) + tamarin.run_acbuild(acbuild_flags+["mount", "add", "tamarin-profiles", "/tamarin/profiles", "--read-only"]) + + # Configure "containerbuild" hooks environment + hooks_env = os.environ.copy() + hooks_env["PATH"] = os.environ['PATH'] + ':' + tamarin.get_workspace_subdir('acbuild') + hooks_env["TAMARIN_ACBUILD"] = " ".join([system.which('acbuild', local_acbuild_dir)]+acbuild_flags) + hooks_env["TAMARIN_ACBUILD_ENGINE"] = "chroot" if not system.which('systemctl') else "systemd-nspawn" + + # Run hooks + tamarin.run_profile_hooks(profile, 'containerbuild', cwd=build_workspace, env=hooks_env) + + return aci_file + +def cleanup(build_workspace, rkt_flags): + + # Nettoyage des conteneurs + rkt.run([ + "gc", + "--grace-period=0" + ] + rkt_flags, as_root=True) + + # Nettoyage des images obsolètes du store + rkt.run([ + "image", + "gc" + ] + rkt_flags, as_root=True) + + # Suppression de l'espace de travail de build + shutil.rmtree(build_workspace, ignore_errors=True) + +def validate_args(args): + '''TODO''' + if __name__ == "__main__": - parser = configure_args_parser() + parser = create_args_parser() args = parser.parse_args() + validate_args(args) + # Verify project directory project_dir = os.path.abspath(args.project_directory) output_dir = os.path.abspath(args.output) @@ -38,21 +114,11 @@ if __name__ == "__main__": local_rkt_dir = tamarin.get_workspace_subdir('rkt') if not system.which('rkt', local_rkt_dir): - # Download and extract rkt - rkt_archive_path = tamarin.download_rkt() - system.extract_tar(rkt_archive_path, workspace_tmp) - rkt_archive_dir = tamarin.get_rkt_achive_dest_dir() - shutil.rmtree(local_rkt_dir, ignore_errors=True) - os.rename(rkt_archive_dir, local_rkt_dir) + download_and_extract_rkt(local_rkt_dir) local_acbuild_dir = tamarin.get_workspace_subdir('acbuild') if not system.which('acbuild', local_acbuild_dir): - # Download and extract acbuild - acbuild_archive_path = tamarin.download_acbuild() - system.extract_tar(acbuild_archive_path, workspace_tmp) - acbuild_archive_dir = tamarin.get_acbuild_achive_dest_dir() - shutil.rmtree(local_acbuild_dir, ignore_errors=True) - os.rename(acbuild_archive_dir, local_acbuild_dir) + download_and_extract_acbuild(local_acbuild_dir) pid = os.getpid() build_workspace = tamarin.get_workspace_subdir('tmp/build_{:d}'.format(pid)) @@ -61,7 +127,8 @@ if __name__ == "__main__": rkt_flags = ["--dir={:s}".format(rkt_store)] base_image = profile['profile']['default_image'] - # If the base image is Docker-based, preload it and get its name from the store + + # If the base image is Docker-based, download it if base_image.startswith('docker://'): rkt.run([ "fetch", @@ -70,44 +137,15 @@ if __name__ == "__main__": ] + rkt_flags) aci_file = os.path.join(os.sep, build_workspace, 'image.aci') - acbuild_flags = ["--modify", aci_file, "--work-path", build_workspace] - - # Use cached image base on base_image and containerbuild hooks - containerbuild_hooks = profile['containerbuild']['hooks'] - hasher = hashlib.sha1() - hasher.update(base_image.encode()) - hasher.update(containerbuild_hooks.encode()) - image_hash = hasher.hexdigest() - cache_dir = tamarin.get_workspace_subdir('cache') - cached_image_file = os.path.join(os.sep, cache_dir, '{:s}.aci'.format(image_hash[:12])); + cached_image_file = get_cached_image_path(profile) if not args.rebuild and os.path.exists(cached_image_file): - # Copy cached image - shutil.copyfile(cached_image_file, aci_file) + # Copy cached image + shutil.copyfile(cached_image_file, aci_file) else: - # Find and export base image from rkt' store - name_pattern = base_image.split('/')[-1] + '$' - image = rkt.find_image_by_name(name_pattern, rkt_flags=rkt_flags) - rkt.export_image(image['id'], aci_file, rkt_flags=rkt_flags); - - # Build image - tamarin.run_acbuild(acbuild_flags+["set-name", "image_{:d}".format(pid)]) - tamarin.run_acbuild(acbuild_flags+["mount", "add", "src", "/src", "--read-only"]) - tamarin.run_acbuild(acbuild_flags+["mount", "add", "dist", "/dist"]) - tamarin.run_acbuild(acbuild_flags+["mount", "add", "tamarin-hooks", "/tamarin/hooks", "--read-only"]) - tamarin.run_acbuild(acbuild_flags+["mount", "add", "tamarin-lib", "/tamarin/lib", "--read-only"]) - tamarin.run_acbuild(acbuild_flags+["mount", "add", "tamarin-profiles", "/tamarin/profiles", "--read-only"]) - - # Execute containerbuild hooks - cb_hooks_env = os.environ.copy() - cb_hooks_env["PATH"] = os.environ['PATH'] + ':' + local_acbuild_dir - cb_hooks_env["TAMARIN_ACBUILD"] = " ".join([system.which('acbuild', local_acbuild_dir)]+acbuild_flags) - cb_hooks_env["TAMARIN_ACBUILD_ENGINE"] = "chroot" if not system.which('systemctl') else "systemd-nspawn" - - tamarin.run_profile_hooks(profile, 'containerbuild', cwd=build_workspace, env=cb_hooks_env) - - # Cache image - shutil.copyfile(aci_file, cached_image_file) + build_image(build_workspace, aci_file, base_image, profile) + # Cache image + shutil.copyfile(aci_file, cached_image_file) # Start container rkt.run(rkt_flags+[ @@ -128,15 +166,4 @@ if __name__ == "__main__": ], as_root=True) # Cleanup - - rkt.run([ - "gc", - "--grace-period=0" - ] + rkt_flags, as_root=True) - - rkt.run([ - "image", - "gc" - ] + rkt_flags, as_root=True) - - shutil.rmtree(build_workspace, ignore_errors=True) + cleanup(build_workspace, rkt_flags) diff --git a/test/data/debian/dummy-project/debian/changelog b/test/data/debian/dummy-project/debian/changelog new file mode 100644 index 0000000..5c78aa0 --- /dev/null +++ b/test/data/debian/dummy-project/debian/changelog @@ -0,0 +1,5 @@ +dummy-project (0.0.1) unstable; urgency=low + + * Dev release + + -- William Petit Fri, 16 Oct 2015 15:57:03 +0200 diff --git a/test/data/debian/dummy-project/debian/compat b/test/data/debian/dummy-project/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/test/data/debian/dummy-project/debian/compat @@ -0,0 +1 @@ +9 diff --git a/test/data/debian/dummy-project/debian/control b/test/data/debian/dummy-project/debian/control new file mode 100644 index 0000000..a628610 --- /dev/null +++ b/test/data/debian/dummy-project/debian/control @@ -0,0 +1,13 @@ +Source: dummy-project +Section: unknown +Priority: optional +Maintainer: William Petit +Build-Depends: debhelper (>= 8.0.0) +Standards-Version: 3.9.4 +Homepage: +Vcs-Git: https://forge.cadoles.com/wpetit/tamarin.git +Vcs-Browser: https://forge.cadoles.com/wpetit/tamarin + +Package: dummy-project +Architecture: any +Description: Projet test pour la construction de paquets via Tamarin diff --git a/test/data/debian/dummy-project/debian/rules b/test/data/debian/dummy-project/debian/rules new file mode 100644 index 0000000..ecf4506 --- /dev/null +++ b/test/data/debian/dummy-project/debian/rules @@ -0,0 +1,8 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +# Uncomment this to turn on verbose mode. +export DH_VERBOSE=1 + +%: + dh $@ diff --git a/test/data/debian/dummy-project/debian/source/format b/test/data/debian/dummy-project/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/test/data/debian/dummy-project/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/test/package_test.py b/test/package_test.py new file mode 100644 index 0000000..034c925 --- /dev/null +++ b/test/package_test.py @@ -0,0 +1,16 @@ +import unittest, os +from importlib.machinery import SourceFileLoader + +package = SourceFileLoader('package', os.path.dirname(__file__) + '/../package').load_module() + +class TestPackage(unittest.TestCase): + + def test_args_parser(self): + parser = package.create_args_parser() + + def test_download_and_extract_rkt(self): + + + +if __name__ == '__main__': + unittest.main()