Package: piuparts Version: 0.84 Severity: normal Tags: patch I have written a patch for adding docker support on piuparts. A new option is introduced `--docker-image` e.g.
$ piuparts --docker-image debian:unstable package.deb Honestly I didn't do too much testing on this, I just have tried using the new feature of course and I have tried using schroot to check it's not breaking something. I am willing to help you if you need/want to do extra testing on this. The patch attached is made against origin/master. Cheers, -- TiN
diff --git a/piuparts.py b/piuparts.py
index 3daba797..a13bd9fc 100644
--- a/piuparts.py
+++ b/piuparts.py
@@ -47,6 +47,7 @@ import os
import tarfile
import stat
import re
+import json
import pickle
import subprocess
import traceback
@@ -191,6 +192,7 @@ class Settings:
self.skip_minimize = True
self.minimize = False
self.debfoster_options = None
+ self.docker_image = None
# tests and checks
self.no_install_purge_test = False
self.no_upgrade_test = False
@@ -769,7 +771,7 @@ class Chroot:
def create(self, temp_tgz=None):
"""Create a chroot according to user's wishes."""
self.panic_handler_id = do_on_panic(self.remove)
- if not settings.schroot:
+ if not settings.schroot and not settings.docker_image:
self.create_temp_dir()
if temp_tgz:
@@ -782,10 +784,12 @@ class Chroot:
self.setup_from_dir(settings.existing_chroot)
elif settings.schroot:
self.setup_from_schroot(settings.schroot)
+ elif settings.docker_image:
+ self.setup_from_docker(settings.docker_image)
else:
self.setup_minimal_chroot()
- if not settings.schroot:
+ if not settings.schroot and not settings.docker_image:
self.mount_proc()
self.configure_chroot()
@@ -807,7 +811,7 @@ class Chroot:
self.run_scripts("post_chroot_unpack")
self.run(["apt-get", "update"])
- if settings.basetgz or settings.schroot or settings.existing_chroot:
+ if settings.basetgz or settings.docker_image or settings.schroot or settings.existing_chroot:
self.run(["apt-get", "-yf", "dist-upgrade"])
self.minimize()
self.remember_available_md5()
@@ -832,7 +836,10 @@ class Chroot:
if settings.schroot:
logging.debug("Terminate schroot session '%s'" % self.name)
run(['schroot', '--end-session', '--chroot', "session:" + self.schroot_session])
- if not settings.schroot:
+ if settings.docker_image:
+ logging.debug("Destroy docker container '%s'" % self.docker_container)
+ run(['docker', 'rm', '-f', self.docker_container])
+ if not settings.schroot and not settings.docker_image:
run(['rm', '-rf', '--one-file-system', self.name])
if os.path.exists(self.name):
create_file(os.path.join(self.name, ".piuparts.tmpdir"), "removal failed")
@@ -840,6 +847,8 @@ class Chroot:
elif settings.keep_tmpdir:
if settings.schroot:
logging.debug("Keeping schroot session %s at %s" % (self.schroot_session, self.name))
+ elif settings.docker_image:
+ logging.debug("Keeping container %s" % self.docker_container)
else:
logging.debug("Keeping directory tree at %s" % self.name)
dont_do_on_panic(self.panic_handler_id)
@@ -892,6 +901,25 @@ class Chroot:
self.name = output.strip()
logging.info("New schroot session in '%s'" % self.name)
+ @staticmethod
+ def check_if_docker_storage_driver_is_supported():
+ ret_code, output = run(['docker', 'info'])
+ if 'overlay2' not in output:
+ logging.error('Only overlay2 storage driver is supported')
+ panic()
+
+ def setup_from_docker(self, docker_image):
+ self.check_if_docker_storage_driver_is_supported()
+ ret_code, output = run(['docker', 'run', '-d', '-it', docker_image, 'bash'])
+ if ret_code != 0:
+ logging.error("Couldn't start the container from '%s'" % docker_image)
+ panic()
+ self.docker_container = output.strip()
+ ret_code, output = run(['docker', 'inspect', self.docker_container])
+ container_data = json.loads(output)[0]
+ self.name = container_data['GraphDriver']['Data']['MergedDir']
+ logging.info("New container created '%s'" % self.docker_container)
+
def setup_from_lvm(self, lvm_volume):
"""Create a chroot by creating an LVM snapshot."""
self.lvm_base = os.path.dirname(lvm_volume)
@@ -938,6 +966,12 @@ class Chroot:
["schroot", "--preserve-environment", "--run-session", "--chroot", "session:" +
self.schroot_session, "--directory", "/", "-u", "root", "--"] + prefix + command,
ignore_errors=ignore_errors, timeout=settings.max_command_runtime)
+ elif settings.docker_image:
+ return run(
+ ['docker', 'exec', self.docker_container,] + prefix + command,
+ ignore_errors=ignore_errors,
+ timeout=settings.max_command_runtime
+ )
else:
return run(["chroot", self.name] + prefix + command,
ignore_errors=ignore_errors, timeout=settings.max_command_runtime)
@@ -1042,6 +1076,9 @@ class Chroot:
def create_resolv_conf(self):
"""Update resolv.conf based on the current configuration in the host system. Strip comments and whitespace."""
+ if settings.docker_image:
+ # Do nothing, docker already takes care of this
+ return
full_name = self.relative("etc/resolv.conf")
resolvconf = ""
with open("/etc/resolv.conf", "r") as f:
@@ -1624,8 +1661,12 @@ class Chroot:
def check_for_no_processes(self, fail=None):
"""Check there are no processes running inside the chroot."""
- (status, output) = run(["lsof", "-w", "+D", self.name], ignore_errors=True)
- count = len(output.split("\n")) - 1
+ if settings.docker_image:
+ (status, output) = run(["docker", "top", self.docker_container])
+ count = len(output.strip().split("\n")) - 2 # header + bash launched on container creation
+ else:
+ (status, output) = run(["lsof", "-w", "+D", self.name], ignore_errors=True)
+ count = len(output.split("\n")) - 1
if count > 0:
if fail is None:
fail = not settings.allow_database
@@ -1637,6 +1678,9 @@ class Chroot:
def terminate_running_processes(self):
"""Terminate all processes running in the chroot."""
+ if settings.docker_image:
+ # docker takes care of this
+ return
seen = []
while True:
p = subprocess.Popen(["lsof", "-t", "+D", self.name],
@@ -2726,6 +2770,10 @@ def parse_command_line():
help="Use schroot session named SCHROOT-NAME for the chroot, instead of building " +
"a new one with debootstrap.")
+ parser.add_option("--docker-image", metavar="DOCKER-IMAGE", action="store",
+ help="Use docker image DOCKER-IMAGE for the chroot, instead of building " +
+ "a new one with debootstrap.")
+
parser.add_option("-m", "--mirror", action="append", metavar="URL",
default=[],
help="Which Debian mirror to use.")
@@ -2948,6 +2996,7 @@ def parse_command_line():
if settings.minimize:
settings.skip_minimize = False
settings.debfoster_options = opts.debfoster_options.split()
+ settings.docker_image = opts.docker_image
# tests and checks
settings.no_install_purge_test = opts.no_install_purge_test
settings.no_upgrade_test = opts.no_upgrade_test
signature.asc
Description: OpenPGP digital signature

