From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54266) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTHWj-00025v-4k for qemu-devel@nongnu.org; Tue, 09 Feb 2016 18:16:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aTHWf-0000m5-MH for qemu-devel@nongnu.org; Tue, 09 Feb 2016 18:16:57 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57584) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTHWf-0000m0-Eb for qemu-devel@nongnu.org; Tue, 09 Feb 2016 18:16:53 -0500 References: <1454664263-25969-1-git-send-email-famz@redhat.com> <1454664263-25969-2-git-send-email-famz@redhat.com> <56B90D7C.70301@redhat.com> <20160209020140.GA7103@ad.usersys.redhat.com> From: John Snow Message-ID: <56BA7362.2050204@redhat.com> Date: Tue, 9 Feb 2016 18:16:50 -0500 MIME-Version: 1.0 In-Reply-To: <20160209020140.GA7103@ad.usersys.redhat.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH 01/12] tests: Add utilities for docker testing List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Fam Zheng Cc: kwolf@redhat.com, peter.maydell@linaro.org, sw@weilnetz.de, qemu-devel@nongnu.org, stefanha@redhat.com, Paolo Bonzini , =?UTF-8?Q?Alex_Benn=c3=a9e?= , david@gibson.dropbear.id.au 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." >=20 > If you have previously "sudo $something" and typed in the password, thi= s will > work. >=20 > You can also specify passworless for docker only: >=20 > fam ALL=3D(ALL) NOPASSWD: /usr/bin/docker >=20 > Fam >=20 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=3Dsubprocess.PIPE, >>> + stderr=3Dsubprocess.PIPE) =3D=3D 0: >>> + return c >>> + raise Exception("Cannot find working docker command") >>> + >>> + def get_image_dockerfile_checksum(self, tag): >>> + resp =3D self._output(["inspect", tag]) >>> + t =3D json.loads(resp)[0] >>> + return t["Config"].get("Labels", {}).get("com.qemu.dockerfil= e-checksum", "") >>> + >>> + def checksum(self, text): >>> + return hashlib.sha1(text).hexdigest() >>> + >>> + def build_image(self, tag, dockerfile, df, quiet=3DTrue): >>> + tmp =3D dockerfile + "\n" + \ >>> + "LABEL com.qemu.dockerfile-checksum=3D%s" % self.check= sum(dockerfile) >>> + tmp_df =3D df + ".tmp" >>> + f =3D open(tmp_df, "wb") >>> + f.write(tmp) >>> + f.close() >>> + self._do(["build", "-t", tag, "-f", tmp_df, os.path.dirname(= df)], >>> + quiet=3Dquiet) >>> + os.unlink(tmp_df) >>> + >>> + def image_matches_dockerfile(self, tag, dockerfile): >>> + try: >>> + a =3D self.get_image_dockerfile_checksum(tag) >>> + except: >>> + return False >>> + return a =3D=3D self.checksum(dockerfile) >>> + >>> + def run(self, cmd, quiet, **kwargs): >>> + label =3D uuid.uuid1().hex >>> + self._instances.append(label) >>> + r =3D self._do(["run", "--label", "com.qemu.instance.uuid=3D= " + label] + cmd, quiet=3Dquiet) >>> + 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 >>> +# >>> +# 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 =3D argparse.ArgumentParser() >>> + parser.add_argument("tag", >>> + help=3D"Image Tag") >>> + parser.add_argument("dockerfile", >>> + help=3D"Dockerfile name") >>> + parser.add_argument("--verbose", "-v", action=3D"store_true", >>> + help=3D"Print verbose information") >>> + args =3D parser.parse_args() >>> + >>> + dockerfile =3D open(args.dockerfile, "rb").read() >>> + tag =3D args.tag >>> + >>> + d =3D docker.Docker() >>> + if d.image_matches_dockerfile(tag, dockerfile): >>> + if args.verbose: >>> + print "Image is up to date." >>> + return 0 >>> + >>> + quiet =3D not args.verbose >>> + d.build_image(tag, dockerfile, args.dockerfile, quiet=3Dquiet) >>> + return 0 >>> + >>> +if __name__ =3D=3D "__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 >>> +# >>> +# 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__ =3D=3D "__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 executio= n is >>> +# iterrupted. >>> +# >>> +# Copyright (c) 2016 Red Hat Inc. >>> +# >>> +# Authors: >>> +# Fam Zheng >>> +# >>> +# 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 =3D argparse.ArgumentParser() >>> + parser.add_argument("--quiet", action=3D"store_true", >>> + help=3D"Run quietly unless an error occured"= ) >>> + args, argv =3D parser.parse_known_args() >>> + return docker.Docker().run(argv, quiet=3Dargs.quiet) >>> + >>> +if __name__ =3D=3D "__main__": >>> + sys.exit(main()) >>> >> >> --=20 >> =E2=80=94js