-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Consolidate docker availability build logic #52548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consolidate docker availability build logic #52548
Conversation
Signed-off-by: Mark Vieira <[email protected]>
Pinging @elastic/es-core-infra (:Core/Infra/Build) |
throwDockerRequiredException(message); | ||
} | ||
|
||
private boolean isBlacklistedOs() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should stay away from terms like "blacklist" and "whitelist".
private boolean isBlacklistedOs() { | |
private boolean isExcludedOs() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I've renamed this.
distribution/docker/build.gradle
Outdated
flavor = distroFlavor | ||
type = 'docker' | ||
version = VersionProperties.getElasticsearch() | ||
required = false // This ensures we skip this testing if Docker is unavailable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this only skip testing? Docker is required for a successful overall build on supported OSs, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This skips building the upstream docker images that are consumed by the tests. I realize now that comment isn't great, I'll improve it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the comment text to make it clear this simply makes building the images optional. The logic for actually skipping the tests themselves lives in TestFixturesPlugin
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one thing I'd like to see changed and one question, but LGTM. This approach looks a lot tidier.
@pugnascotia could you provide some context on the necessity of |
Signed-off-by: Mark Vieira <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great. Just a few comments in addition to the terminology change of "required" to "failifUnavailable" we discussed offline.
import java.util.stream.Collectors; | ||
|
||
/** | ||
* <p>Plugin providing {@link DockerSupportService} for detecting Docker installations and determining requirements for Docker-based |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This shouldn't start with <p>
, as the first line of a javadoc is the short description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
* <p>Plugin providing {@link DockerSupportService} for detecting Docker installations and determining requirements for Docker-based | ||
* Elasticsearch build tasks.</p> | ||
* | ||
* <p>Additionally registers a task graph listener used to assert a compatible Docker installation exists when task requiring Docker are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it is whacky, but <p>
should basically be used as a paragraph break, without a closing tag, in javadocs. From oracle docs (https://www.oracle.com/technetwork/articles/java/index-137868.html):
If you have more than one paragraph in the doc comment, separate the paragraphs with a
paragraph tag
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stupid javadocs. Done.
project.getGradle().getTaskGraph().whenReady(graph -> { | ||
List<String> dockerTasks = graph.getAllTasks().stream().filter(task -> { | ||
ExtraPropertiesExtension ext = task.getExtensions().getExtraProperties(); | ||
return ext.has(REQUIRES_DOCKER_ATTRIBUTE) && ext.get(REQUIRES_DOCKER_ATTRIBUTE).equals("true"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we setting the property to a boolean string instead of an actual boolean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were indeed setting to a boolean
but were checking for a String
. I've fixed this.
* | ||
* @throws GradleException if Docker is not available. The exception message gives the reason. | ||
*/ | ||
void assertDockerIsAvailable(List<String> tasks) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: since we are using assert
s, maybe call use check
or ensure
terminology?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed.
|
||
private void throwDockerRequiredException(final String message, Exception e) { | ||
throw new GradleException( | ||
message + "\nyou can address this by attending to the reported issue, " + "removing the offending tasks from being executed.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removing -> or removing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reworded this message.
return project.getTasks().register(destructiveDistroTestTaskName(distribution), Test.class, t -> { | ||
// Disable Docker distribution tests unless a Docker installation is available | ||
t.onlyIf(t2 -> distribution.getType() != Type.DOCKER || dockerSupport.get().getDockerAvailability().isAvailable); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why onlyIf here instead of using the requiresDocker property?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, using requiresDocker
is strict. It fails the build if docker is unavailable. We want to simply skip that task in that scenario.
Signed-off-by: Mark Vieira <[email protected]>
Signed-off-by: Mark Vieira <[email protected]>
@rjernst I believe I've addressed you feedback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@@ -270,6 +276,11 @@ void finalizeValues() { | |||
"platform not allowed for elasticsearch distribution [" + name + "] of type [" + getType() + "]" | |||
); | |||
} | |||
if (getType() == Type.DOCKER && bundledJdk.isPresent()) { | |||
throw new IllegalArgumentException( | |||
"bundledJdk not allowed for elasticsearch distribution [" + name + "] of type [docker]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bundledJdk setting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or property or something like that? as it is written it sounds like docker can't use the bundledJdk, when in face it only uses it.
Signed-off-by: Mark Vieira <[email protected]>
There were / are some CI machines that can't run Docker for better or worse reasons. I settled on assuming Docker is available unless we know otherwise. I didn't want to rely on detection in case, say, a Packer build went wrong and failed to include Docker or broke it. |
Right, I guess my thought is that now that we look for Docker, and try and execute it, we could just rely on that logic for the most part. The risk there though is that should all our Packer builds suddenly stop installing Docker, we'd simply start silently skipping all these tests. |
I would rather keep the exclusion list until we can expect docker on all CI images at some future time. We should expect docker to work, and error if it doesn't, except in these edge cases. |
Works for me. It's not particularly costly to maintain the status quo. |
Signed-off-by: Mark Vieira <[email protected]>
(cherry picked from commit c1a1047)
This pull request consolidates and standardizes the mechanisms by which we determine the availability of a compatible Docker installation on the build host, as well as conditionally avoid certain tasks based on that availability. The latter has been refactored such that it is always deferred to task execution or graph calculation time so that in the majority case, when a build does not request any docker-related tasks, we don't make any such attempt to determine if Docker exists on the system.
Prior to this refactoring we have 3 main sources of docker availability logic:
DockerUtils
which is quite robust and actually checks that Docker exists, can be executed with privileged commands and meets a minimum version requirement. This was used only for the purpose of determining whether we could build the Docker distributions.BuildPlugin
for throwing an exception if any task declared it required a Docker installation meeting the requirements defined in (1). Again, only the:distribution:docker
project leveraged this.DistroTestPlugin
to determine whether or not Docker distribution tests could be executed. This used a different, and more simple implementation thanDockerUtils
, only assuming Windows never works, Mac always works, and Linux works, unless it's a variant that has been explicitly blacklisted in CI.TestFixturesPlugins
for the purposes of determining whetherdocker-compose
exists on the system. This was another relatively simple implementation, simply looking for the executable from a known list of locations.This pull request solves some of the inconsistencies listed above via:
DockerSupportService
that is used in all instances where a determination on whether a compatible Docker installation is needed. This includes building our Docker images, testing them and spinning up Docker-based test fixtures.ElasticsearchDistribution
such that we can depend on a "lenient" distribution. If a distribution setsrequired = false
and Docker is unavailable we simply skip building it. This allows testing that uses a locally build Docker distribution to be gracefully skipped in the absence of a Docker installation. This was previously done by checking for Docker availability at configuration time and omitting task dependencies (or entire tasks altogether) to avoid trying to build the Docker images.DistributionDownloadPlugin
and lenient distributions described in (2).