From: "Alex Bennée" <alex.bennee@linaro.org>
To: Fam Zheng <famz@redhat.com>
Cc: qemu-devel@nongnu.org, peter.maydell@linaro.org,
neil.williams@linaro.org, steve.mcintyre@linaro.org,
riku.voipio@linaro.org
Subject: Re: [Qemu-devel] [RFC PATCH 1/2] tests/docker/docker.py: support --qemu option
Date: Tue, 31 May 2016 16:23:38 +0100 [thread overview]
Message-ID: <87wpma6ykl.fsf@linaro.org> (raw)
In-Reply-To: <20160527112840.GA7880@ad.usersys.redhat.com>
Fam Zheng <famz@redhat.com> writes:
> On Thu, 05/26 15:27, Alex Bennée wrote:
>> When passed the name of a qemu-$arch binary we copy it and any linked
>> libraries into the docker build context. These can then be included by a
>> dockerfile with the line:
>>
>> # Copy all of context into container
>> ADD . /
>>
>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>
> Looks good in general except a few nitpicks below, most important one being the
> binary path lookup.
>
>> ---
>> tests/docker/docker.py | 58 ++++++++++++++++++++++++++++++++++++++++++++------
>> 1 file changed, 52 insertions(+), 6 deletions(-)
>>
>> diff --git a/tests/docker/docker.py b/tests/docker/docker.py
>> index fe73de7..e9242f3 100755
>> --- a/tests/docker/docker.py
>> +++ b/tests/docker/docker.py
>> @@ -20,6 +20,8 @@ import atexit
>> import uuid
>> import argparse
>> import tempfile
>> +import re
>> +from shutil import copyfile
>>
>> def _text_checksum(text):
>> """Calculate a digest string unique to the text content"""
>> @@ -37,6 +39,27 @@ def _guess_docker_command():
>> raise Exception("Cannot find working docker command. Tried:\n%s" % \
>> commands_txt)
>>
>> +def _find_user_binary(binary_name):
>> + """ Find a binary in the QEMU source tree. Used for finding qemu-$arch."""
>> + top = os.path.abspath("%s/../../.." % sys.argv[0])
>
> What if this is an out of tree build?
Yes I kinda avoided the complexity here. Do we have a programatic way of
finding this out or should we just assume we get based a resolvable path?
>
>> + linux_user = [ x for x in os.listdir(top) if x.endswith("-linux-user") ]
>> + for x in linux_user:
>> + check_path = "%s/%s/%s" % (top, x, binary_name)
>
> os.path.join()?
Ack.
>
>> + if os.path.isfile(check_path):
>> + print ("found %s" % check_path)
>> + return check_path
>> + return None
>> +
>> +def _copy_with_mkdir(src, root_dir, sub_path):
>> + """Copy src into root_dir, creating sub_path as needed."""
>> + full_path = "%s/%s" % (root_dir, sub_path)
>> + try:
>> + os.makedirs(full_path)
>> + except OSError:
>> + print "skipping %s" % (full_path)
>
> Print the error message too? Also do you want to "return"?
It's really a NOP to behave in a mkdir -p type way. Python 3 provides an
exist_ok parameter but I assume we aren't ready to drop python 2 just
yet ;-)
>
>> +
>> + copyfile(src, "%s/%s" % (full_path, os.path.basename(src)))
>> +
>> class Docker(object):
>> """ Running Docker commands """
>> def __init__(self):
>> @@ -86,18 +109,36 @@ class Docker(object):
>> labels = json.loads(resp)[0]["Config"].get("Labels", {})
>> return labels.get("com.qemu.dockerfile-checksum", "")
>>
>> - def build_image(self, tag, dockerfile, df_path, quiet=True, argv=None):
>> + def build_image(self, tag, dockerfile, quiet=True, qemu=None, argv=None):
>> if argv == None:
>> argv = []
>> +
>> + # Create a temporary docker context to build in
>> + tmp_dir = tempfile.mkdtemp(prefix="docker_build")
>> +
>> + # Copy the dockerfile into our work space
>> tmp = dockerfile + "\n" + \
>> "LABEL com.qemu.dockerfile-checksum=%s" % \
>> _text_checksum(dockerfile)
>> - dirname = os.path.dirname(df_path)
>> - tmp_df = tempfile.NamedTemporaryFile(dir=dirname)
>> + tmp_df = tempfile.NamedTemporaryFile(dir=tmp_dir, suffix=".docker")
>> tmp_df.write(tmp)
>> tmp_df.flush()
>> +
>> + # Do we want to copy QEMU into here?
>> + if qemu:
>> + _copy_with_mkdir(qemu, tmp_dir, "/usr/bin")
>
> Looks like "/usr/bin" is combined with tmp_dir as "FOO//usr/bin",
> superfluous?
Yeah, also a bit hacky. In my original shell script it actually searched
the output of Debian's binfmt_update script to see where it was set to
search for the qemu binary from.
>
>> + # do ldd bit here
>> + ldd_output = subprocess.check_output(["ldd", qemu])
>> + for l in ldd_output.split("\n"):
>> + s = re.search("(/.*/)(\S*)", l)
>> + if s and len(s.groups())==2:
>> + so_path=s.groups()[0]
>> + so_lib=s.groups()[1]
>> + _copy_with_mkdir("%s/%s" % (so_path, so_lib),
>> + tmp_dir, so_path)
>> +
>> self._do(["build", "-t", tag, "-f", tmp_df.name] + argv + \
>> - [dirname],
>> + [tmp_dir],
>> quiet=quiet)
>>
>> def image_matches_dockerfile(self, tag, dockerfile):
>> @@ -148,6 +189,7 @@ class BuildCommand(SubCommand):
>> """ Build docker image out of a dockerfile. Arguments: <tag> <dockerfile>"""
>> name = "build"
>> def args(self, parser):
>> + parser.add_argument("--qemu", help="Include qemu-user binaries")
>
> Can I ask for a rename of this and the variable names in this patch, to a more
> generic name (to reflect that it is inherently orthorgonal to the type of the
> binary we are copying)? How about:
>
> parser.add_argument("--executable-inject", "-e",
> help="""Specify a binary that will be copied to the
> container together with all its dependent
> libraries""")
>
> And I think it is reasonable to expect the user (or the calling Makefile) to
> designate a working absolute or relative path, instead of looking up it
> ourselves.
Makes sense.
>
>> parser.add_argument("tag",
>> help="Image Tag")
>> parser.add_argument("dockerfile",
>> @@ -157,14 +199,18 @@ class BuildCommand(SubCommand):
>> dockerfile = open(args.dockerfile, "rb").read()
>> tag = args.tag
>>
>> + # find qemu binary
>> + qbin=None
>
> Add whitespaces around "="?
Ack.
>
>> + if args.qemu:
>> + qbin=_find_user_binary(args.qemu)
>
> Ditto, and some more occasions above.
Ack.
>
>> +
>> dkr = Docker()
>> if dkr.image_matches_dockerfile(tag, dockerfile):
>> if not args.quiet:
>> print "Image is up to date."
>> return 0
>>
>> - dkr.build_image(tag, dockerfile, args.dockerfile,
>> - quiet=args.quiet, argv=argv)
>> + dkr.build_image(tag, dockerfile, quiet=args.quiet, qemu=qbin, argv=argv)
>> return 0
>>
>> class CleanCommand(SubCommand):
>> --
>> 2.7.4
>>
>
> Thanks,
>
> Fam
--
Alex Bennée
next prev parent reply other threads:[~2016-05-31 15:23 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-26 14:27 [Qemu-devel] [RFC PATCH 0/2] Support building qemu-user powered docker test images Alex Bennée
2016-05-26 14:27 ` [Qemu-devel] [RFC PATCH 1/2] tests/docker/docker.py: support --qemu option Alex Bennée
2016-05-27 11:28 ` Fam Zheng
2016-05-31 15:23 ` Alex Bennée [this message]
2016-06-01 3:00 ` Fam Zheng
2016-05-26 14:27 ` [Qemu-devel] [RFC PATCH 2/2] add debian-bootstrap.docker target Alex Bennée
2016-05-27 12:23 ` Fam Zheng
2016-05-31 15:27 ` Alex Bennée
2016-06-01 1:47 ` Fam Zheng
2016-06-01 4:27 ` [Qemu-devel] [RFC PATCH] docker: Support ".pre" script when building image Fam Zheng
2016-05-27 12:27 ` [Qemu-devel] [RFC PATCH 0/2] Support building qemu-user powered docker test images Fam Zheng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87wpma6ykl.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=famz@redhat.com \
--cc=neil.williams@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=riku.voipio@linaro.org \
--cc=steve.mcintyre@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).