On 02/08/2016 09:01 PM, Fam Zheng wrote: > On Mon, 02/08 16:49, John Snow wrote: >>> + def _guess_command(self): >>> + for c in [["docker"], ["sudo", "-n", "docker"]]: >> >> If the sudo version fails (Say, because a password prompt shows up) we >> get the unhelpful error "Cannot find working docker command." > > If you have previously "sudo $something" and typed in the password, this will > work. > > You can also specify passworless for docker only: > > fam ALL=(ALL) NOPASSWD: /usr/bin/docker > > Fam >
Sure, but the failure here is not particularly obvious, because it makes it seem as if docker has failed instead of a sudo privilege situation. --js >> >>> + if subprocess.call(c + ["images"], >>> + stdout=subprocess.PIPE, >>> + stderr=subprocess.PIPE) == 0: >>> + return c >>> + raise Exception("Cannot find working docker command") >>> + >>> + def get_image_dockerfile_checksum(self, tag): >>> + resp = self._output(["inspect", tag]) >>> + t = json.loads(resp)[0] >>> + return t["Config"].get("Labels", >>> {}).get("com.qemu.dockerfile-checksum", "") >>> + >>> + def checksum(self, text): >>> + return hashlib.sha1(text).hexdigest() >>> + >>> + def build_image(self, tag, dockerfile, df, quiet=True): >>> + tmp = dockerfile + "\n" + \ >>> + "LABEL com.qemu.dockerfile-checksum=%s" % >>> self.checksum(dockerfile) >>> + tmp_df = df + ".tmp" >>> + f = open(tmp_df, "wb") >>> + f.write(tmp) >>> + f.close() >>> + self._do(["build", "-t", tag, "-f", tmp_df, os.path.dirname(df)], >>> + quiet=quiet) >>> + os.unlink(tmp_df) >>> + >>> + def image_matches_dockerfile(self, tag, dockerfile): >>> + try: >>> + a = self.get_image_dockerfile_checksum(tag) >>> + except: >>> + return False >>> + return a == self.checksum(dockerfile) >>> + >>> + def run(self, cmd, quiet, **kwargs): >>> + label = uuid.uuid1().hex >>> + self._instances.append(label) >>> + r = self._do(["run", "--label", "com.qemu.instance.uuid=" + label] >>> + cmd, quiet=quiet) >>> + self._instances.remove(label) >>> + return r >>> + >>> diff --git a/tests/docker/docker_build b/tests/docker/docker_build >>> new file mode 100755 >>> index 0000000..b4f0dec >>> --- /dev/null >>> +++ b/tests/docker/docker_build >>> @@ -0,0 +1,42 @@ >>> +#!/usr/bin/env python2 >>> +# >>> +# Compare to Dockerfile and rebuild a docker image if necessary. >>> +# >>> +# Copyright (c) 2016 Red Hat Inc. >>> +# >>> +# Authors: >>> +# Fam Zheng <f...@redhat.com> >>> +# >>> +# This work is licensed under the terms of the GNU GPL, version 2 >>> +# or (at your option) any later version. See the COPYING file in >>> +# the top-level directory. >>> + >>> +import sys >>> +import docker >>> +import argparse >>> + >>> +def main(): >>> + parser = argparse.ArgumentParser() >>> + parser.add_argument("tag", >>> + help="Image Tag") >>> + parser.add_argument("dockerfile", >>> + help="Dockerfile name") >>> + parser.add_argument("--verbose", "-v", action="store_true", >>> + help="Print verbose information") >>> + args = parser.parse_args() >>> + >>> + dockerfile = open(args.dockerfile, "rb").read() >>> + tag = args.tag >>> + >>> + d = docker.Docker() >>> + if d.image_matches_dockerfile(tag, dockerfile): >>> + if args.verbose: >>> + print "Image is up to date." >>> + return 0 >>> + >>> + quiet = not args.verbose >>> + d.build_image(tag, dockerfile, args.dockerfile, quiet=quiet) >>> + return 0 >>> + >>> +if __name__ == "__main__": >>> + sys.exit(main()) >>> diff --git a/tests/docker/docker_clean b/tests/docker/docker_clean >>> new file mode 100755 >>> index 0000000..88cdba6 >>> --- /dev/null >>> +++ b/tests/docker/docker_clean >>> @@ -0,0 +1,22 @@ >>> +#!/usr/bin/env python2 >>> +# >>> +# Clean up uselsee containers. >>> +# >>> +# Copyright (c) 2016 Red Hat Inc. >>> +# >>> +# Authors: >>> +# Fam Zheng <f...@redhat.com> >>> +# >>> +# This work is licensed under the terms of the GNU GPL, version 2 >>> +# or (at your option) any later version. See the COPYING file in >>> +# the top-level directory. >>> + >>> +import sys >>> +import docker >>> + >>> +def main(): >>> + docker.Docker().clean() >>> + return 0 >>> + >>> +if __name__ == "__main__": >>> + sys.exit(main()) >>> diff --git a/tests/docker/docker_run b/tests/docker/docker_run >>> new file mode 100755 >>> index 0000000..5cf9d04 >>> --- /dev/null >>> +++ b/tests/docker/docker_run >>> @@ -0,0 +1,28 @@ >>> +#!/usr/bin/env python2 >>> +# >>> +# Wrapper for "docker run" with automatical clean up if the execution is >>> +# iterrupted. >>> +# >>> +# Copyright (c) 2016 Red Hat Inc. >>> +# >>> +# Authors: >>> +# Fam Zheng <f...@redhat.com> >>> +# >>> +# This work is licensed under the terms of the GNU GPL, version 2 >>> +# or (at your option) any later version. See the COPYING file in >>> +# the top-level directory. >>> + >>> +import os >>> +import sys >>> +import argparse >>> +import docker >>> + >>> +def main(): >>> + parser = argparse.ArgumentParser() >>> + parser.add_argument("--quiet", action="store_true", >>> + help="Run quietly unless an error occured") >>> + args, argv = parser.parse_known_args() >>> + return docker.Docker().run(argv, quiet=args.quiet) >>> + >>> +if __name__ == "__main__": >>> + sys.exit(main()) >>> >> >> -- >> —js