f20 - docker file & instructions for test_finder
BUG=b:200620192
TEST=./build-dockerimage.sh $chroot $sysroot local
Change-Id: I6a7668968ea0850d2a19dea5939005e94ccbca2f
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/3219659
Reviewed-by: Jesse McGuire <jessemcguire@google.com>
Reviewed-by: Seewai Fu <seewaifu@google.com>
Commit-Queue: Derek Beckett <dbeckett@chromium.org>
Tested-by: Derek Beckett <dbeckett@chromium.org>
diff --git a/src/chromiumos/test/test_finder/docker/Dockerfile b/src/chromiumos/test/test_finder/docker/Dockerfile
new file mode 100644
index 0000000..a2ac449
--- /dev/null
+++ b/src/chromiumos/test/test_finder/docker/Dockerfile
@@ -0,0 +1,16 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+FROM ubuntu:bionic
+COPY cros-test-finder /usr/bin/
+
+
+RUN mkdir -p /tmp/test
+# Bring in metadata to 1 location
+COPY *.pb /tmp/test/metadata/
+
+
+# Own cros-test-finder & metadata
+RUN chmod 755 /usr/bin/cros-test-finder
+RUN chmod 644 /tmp/test/metadata/*.pb
\ No newline at end of file
diff --git a/src/chromiumos/test/test_finder/docker/build-dockerimage.sh b/src/chromiumos/test/test_finder/docker/build-dockerimage.sh
new file mode 100755
index 0000000..0a847d8
--- /dev/null
+++ b/src/chromiumos/test/test_finder/docker/build-dockerimage.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+set -e
+readonly script_dir="$(dirname "$(realpath -e "${BASH_SOURCE[0]}")")"
+
+source "${script_dir}/../../../../../test/docker/util.sh"
+
+usage() {
+ echo "Usage: $0 <chroot> <sysroot> [options] [key=value...]"
+ echo
+ echo "Build a docker container for the cros-test-finder service."
+ echo
+ echo "Args:"
+ echo " chroot - Path to the ChromeOS chroot on the host system."
+ echo " sysroot - Path inside of the chroot to the board sysroot."
+ echo " labels - Zero or more key=value strings to apply as labels to container."
+ echo
+ echo "Options:"
+ echo " --tags/-t - Comma separated list of tag names to apply to container"
+ exit 1
+}
+
+if [[ $# -lt 3 ]]; then
+ usage
+fi
+
+prep_container() {
+ # Determine the full path to this script and use it to resolve the checkout src path.
+ readonly src="${script_dir}/../../../../../../../"
+
+ src_root="$(realpath "${src}")"
+
+ # Set the src/config/bin dir and load the common.sh src
+ readonly config_bin_dir="${src_root}/config/bin"
+ # shellcheck source=/dev/null
+ source "${config_bin_dir}/common.sh"
+
+ create_venv
+
+ python3 "${script_dir}"/metadata.py -chroot="${chroot_path}" -sysroot="${sysroot_path}" -path="${output_dir}" -force_path=True -src="${src_root}"
+}
+
+readonly chroot_path="$1"; shift
+readonly sysroot_path="$1"; shift
+
+tags=""
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ --tags|-t)
+ tags="$2"
+ shift
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+
+readonly output_dir="tmp/docker/crostestfinder"
+readonly full_output_dir="${chroot_path}/${sysroot_path}/${output_dir}"
+
+prep_container
+
+
+build_container_image \
+ "crostestfinder" \
+ "${full_output_dir}/Dockerfile" \
+ "${chroot_path}" \
+ "${tags}" \
+ "$@"
diff --git a/src/chromiumos/test/test_finder/docker/metadata.py b/src/chromiumos/test/test_finder/docker/metadata.py
new file mode 100644
index 0000000..526a777
--- /dev/null
+++ b/src/chromiumos/test/test_finder/docker/metadata.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python3
+
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Prep everything for for a Docker Build Context."""
+
+
+import argparse
+
+import os
+import pathlib
+import shutil
+import sys
+
+sys.path.insert(1, str(pathlib.Path(__file__).parent.resolve()/'../../'))
+
+def parse_local_arguments():
+ """Parse the CLI."""
+ parser = argparse.ArgumentParser(
+ description='Prep Tauto, Tast, & Services for DockerBuild.')
+ parser.add_argument('-chroot',
+ dest='chroot',
+ help='chroot (String): The chroot path to use.')
+ parser.add_argument('-sysroot',
+ dest='sysroot',
+ help=' sysroot (String): The sysroot path to use.')
+ parser.add_argument('-path',
+ dest='path',
+ help='path (String): Path to write artifacts to.')
+ parser.add_argument('-force_path',
+ dest='force_path',
+ default=False,
+ help='Delete anything conflicting in the outpath.')
+ parser.add_argument('-src',
+ dest='src',
+ help='path (String): The src tree path.')
+
+ args = parser.parse_args()
+ return args
+
+
+class DockerPrep():
+ """Prep Needed files for the Test Execution Container Docker Build."""
+
+ def __init__(self, args):
+ """@param args (ArgumentParser): .chroot, .sysroot, .path."""
+ self.args = args
+ self.full_autotest = ''
+ self.full_bin = ''
+ self.full_out = ''
+ self.build_path = ''
+ self.chroot_bin = ''
+ self.chroot = self.args.chroot
+ self.src_root = self.args.src
+ self.sysroot = self.args.sysroot
+ if self.sysroot.startswith('/'):
+ self.sysroot = self.sysroot[1:]
+
+ def config_paths(self):
+ """Build up the paths needed in local mem."""
+ self.build_path = os.path.join(self.chroot, self.sysroot)
+ self.full_autotest = os.path.join(self.build_path,
+ 'usr/local/build/autotest')
+ self.chroot_bin = os.path.join(self.chroot, 'usr/bin')
+ self.full_bin = os.path.join(self.build_path, 'usr/bin')
+ self.full_out = os.path.join(self.build_path, self.args.path)
+ self.validate_paths()
+ self.prep_artifact_dir()
+
+ def validate_paths(self):
+ """Verify the paths generated are valid/exist."""
+ if not os.path.isdir(self.full_autotest):
+ if not os.path.exists(self.full_autotest):
+ raise Exception('Autotest path %s does not exist' %
+ self.full_autotest)
+ raise Exception('Autotest path %s is not a directory' %
+ self.full_autotest)
+
+ if not os.path.isdir(self.build_path):
+ if not os.path.exists(self.build_path):
+ raise Exception('sysroot %s does not exist' % self.build_path)
+ raise Exception('sysroot %s is not a directory' % self.build_path)
+
+ def prep_artifact_dir(self):
+ """Prepare the artifact dir. If it does not exist, create it."""
+ if os.path.exists(self.full_out):
+ if self.args.force_path:
+ print('Deleting existing prepdir {}'.format(self.full_out))
+ shutil.rmtree(self.full_out)
+ else:
+ raise Exception('outpath %s exists and force is not set.' %
+ self.full_out)
+ os.makedirs(self.full_out, exist_ok=True)
+
+ def copy_services(self):
+ """Copy services needed for Docker."""
+ shutil.copy(os.path.join(self.chroot_bin, 'cros-test-finder'),
+ self.full_out)
+
+
+ def copy_metadata(self):
+ """Return the absolute path of the metadata files."""
+ # Relative to build
+ _BUILD_METADATA_FILES = [
+ ('usr/local/build/autotest/autotest_metadata.pb',
+ os.path.join(self.full_out, 'autotest_metadata.pb')),
+ ('usr/share/tast/metadata/local/cros.pb',
+ os.path.join(self.full_out, 'local_cros.pb')),
+ ('build/share/tast/metadata/local/crosint.pb',
+ os.path.join(self.full_out, 'crosint.pb'))
+ ]
+
+ # relative to chroot.
+ _CHROOT_METADATA_FILES = [('usr/share/tast/metadata/remote/cros.pb',
+ os.path.join(self.full_out,
+ 'remote_cros.pb'))]
+
+ for f, d in _BUILD_METADATA_FILES:
+ full_md_path = FromSysrootPath(self.build_path, f)
+ if not os.path.exists(full_md_path):
+ print('Path %s does not exist, skipping' % full_md_path)
+ continue
+ shutil.copyfile(full_md_path, os.path.join(self.full_out, d))
+
+ for f, d in _CHROOT_METADATA_FILES:
+ full_md_path = FromSysrootPath(self.chroot, f)
+ if not os.path.exists(full_md_path):
+ print('Path %s does not exist, skipping' % full_md_path)
+ continue
+ shutil.copyfile(full_md_path, os.path.join(self.full_out, d))
+
+ def copy_dockerfiles(self):
+ """Copy Dockerfiles needed to build the container to the output dir."""
+ dockerfile_relative_dir = 'platform/dev/src/chromiumos/test/test_finder/docker'
+
+ src = os.path.join(self.src_root, dockerfile_relative_dir)
+ for item in os.listdir(src):
+ s = os.path.join(src, item)
+ d = os.path.join(self.full_out, item)
+ shutil.copy2(s, d)
+
+
+def FromSysrootPath(sysroot, file):
+ return os.path.join(sysroot, file)
+
+def main():
+ """Entry point."""
+
+ if not (sys.version_info.major == 3 and sys.version_info.minor >= 6):
+ print('python3.6 or greater is required.')
+ sys.exit(1)
+
+ args = parse_local_arguments()
+ builder = DockerPrep(args)
+ builder.config_paths()
+ builder.copy_services()
+ builder.copy_metadata()
+ builder.copy_dockerfiles()
+
+
+if __name__ == '__main__':
+ main()