privatestaticvoidadjustLimits( ResourceLimits limits, Command command, String workerName, int defaultMaxCores, boolean onlyMulticoreTests, boolean limitGlobalExecution, int executeStageWidth, boolean allowBringYourOwnContainer, SandboxSettings sandbox) { // store worker name limits.workerName = workerName;
// ...
// Decide whether the action will run in a container if (allowBringYourOwnContainer && !limits.containerSettings.containerImage.isEmpty()) { // enable container execution limits.containerSettings.enabled = true;
// Adjust additional flags for when a container is being used. adjustContainerFlags(limits); }
// we choose to resolve variables after the other variable values have been decided resolveEnvironmentVariables(limits); }
privatestaticvoidadjustContainerFlags(ResourceLimits limits) { // bazelbuild/bazel-toolchains provides container images that start with "docker://". // However, docker is unable to fetch images that have this as a prefix in the URI. // Our solution is to remove the prefix when we see it. // https://github.com/bazelbuild/bazel-buildfarm/issues/1060 limits.containerSettings.containerImage = StringUtils.removeStart(limits.containerSettings.containerImage, "docker://");
// Avoid using the existing execution policies when running actions under docker. // The programs used in the execution policies likely won't exist in the container images. limits.useExecutionPolicies = false; limits.description.add("configured execution policies skipped because of choosing docker");
// avoid limiting resources as cgroups may not be available in the container. // in fact, we will use docker's cgroup settings explicitly. // TODO(thickey): use docker's cgroup settings given existing resource limitations. limits.cpu.limit = false; limits.mem.limit = false; limits.description.add("resource limiting disabled because of choosing docker"); }
/** * @brief Setup the container for the action. * @details This ensures the image is fetched, the container is started, and that the container * has proper visibility to the action's execution root. After this call it should be safe to * spawn an action inside the container. * @param dockerClient Client used to interact with docker. * @param settings Settings used to perform action execition. * @return The ID of the started container. * @note Suggested return identifier: containerId. */ privatestatic String prepareRequestedContainer( DockerClient dockerClient, DockerExecutorSettings settings)throws InterruptedException { // this requires network access. Once complete, "docker image ls" will show the downloaded // image fetchImageIfMissing( dockerClient, settings.limits.containerSettings.containerImage, settings.fetchTimeout);
// build and start the container. Once complete, "docker container ls" will show the started // container StringcontainerId= createContainer(dockerClient, settings); dockerClient.startContainerCmd(containerId).exec();
// copy files into it populateContainer(dockerClient, containerId, settings.execDir);
// container is ready for running actions return containerId; }
/** * @brief Fetch the user requested image for running the action. * @details The image will not be fetched if it already exists. * @param dockerClient Client used to interact with docker. * @param imageName The name of the image to fetch. * @param fetchTimeout When to timeout on fetching the container image. */ privatestaticvoidfetchImageIfMissing( DockerClient dockerClient, String imageName, Duration fetchTimeout) throws InterruptedException { if (!isLocalImagePresent(dockerClient, imageName)) { dockerClient .pullImageCmd(imageName) .exec(newPullImageResultCallback()) .awaitCompletion(fetchTimeout.getSeconds(), TimeUnit.SECONDS); } }
/** * @brief Check to see if the image was already available. * @details Checking to see if the image is already available can avoid having to re-fetch it. * @param dockerClient Client used to interact with docker. * @param imageName The name of the image to check for. * @return Whether or not the container image is already present. * @note Suggested return identifier: isPresent. */ privatestaticbooleanisLocalImagePresent(DockerClient dockerClient, String imageName) { // Check if image is already downloaded. Is this the most efficient way? It would be better to // not use exceptions for control flow. try { dockerClient.inspectImageCmd(imageName).exec(); } catch (NotFoundException e) { returnfalse; } returntrue; }