-
Notifications
You must be signed in to change notification settings - Fork 52
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
Split image name into snapshot and release registries, with a separate path parameter #645
Conversation
@@ -28,7 +28,7 @@ | |||
|
|||
private File dockerFile; | |||
private File dockerBuildDirectory; | |||
private Property<String> imageName; | |||
private Provider<String> imageName; |
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.
re-assigning a provider like this will give you quite weird behaviour if anyone uses the getImageName
accessor and tries to .map
it or access it later:
1. someone sets up a .map
2. someone else calls setImageName(..) which _replaces_ the internal provider field
3. the new value never makes it to person (1)
I'd recommend creating a private final Property here instead.
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.
The problem is that the imageName
is derived from the other fields in the extension (both registries + image path), and thus is not a property that can be set directly in the extension. We can set the three properties in each place we need the image name (this task, the tag-all task, and push task). But that would require deriving the image name from those fields each time. And Property#flatMap
returns a Provider
, not a Property
. Thoughts?
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.
Property has a setter which takes a provider, so it should be fine to set up all the derivation once (which should produce a provider) and then set this task's property to be hooked up to that imageName provider.
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.
Ah, missed that - makes sense that these can remain as Property
fields backed by the deriving Provider
then. (Seems weird to keep having to go back and forth between Property
and Provider
and back to Property
again.)
@@ -53,7 +53,7 @@ public final void setDockerBuildDirectory(File dockerBuildDirectory) { | |||
this.dockerBuildDirectory = dockerBuildDirectory; | |||
} | |||
|
|||
public final void setImageName(Property<String> imageName) { | |||
public final void setImageName(Provider<String> imageName) { | |||
this.imageName = imageName; |
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.
when the imageName is a Property, you can use .set instead of assignment. This allows anyone who is observing the original value to notice when a new value has been 'set'.
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.
But ImageName
will not be initialized to anything (null
) on the no-arg constructor of this task. I think it's fine to use setter for now - again looking to minimize changes from the original.
@@ -19,28 +19,28 @@ | |||
import java.util.List; | |||
import java.util.stream.Collectors; | |||
import org.gradle.api.DefaultTask; | |||
import org.gradle.api.provider.Property; | |||
import org.gradle.api.provider.Provider; | |||
import org.gradle.api.tasks.Input; | |||
import org.gradle.api.tasks.TaskAction; | |||
|
|||
public class LazyExecTask extends DefaultTask { |
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 think bog-standard exec tasks have a CommandLineArgumentProvider abstraction which might obviate this class?
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'm not too keen on trying to use this PR to do refactors and cleanups as well - only the minimal necessary to complete the task at hand.
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 can file this as a TODO
project, | ||
imagePath, | ||
snapshotRegistry, | ||
releaseRegistry)))); |
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 think it might be useful to put this logic as a read-only provider on the extension, because won't people need to grab the derived value you create and template it into their configuration.yml?
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.
That could make sense, although we're having concerns about using a Provider in these fields at all, right? See #645 (comment). But this is what I meant about needing a Provider
and not a Property
because of the derivation matter.
@iamdanfox I switched to using a |
project, | ||
resolvedImagePath, | ||
resolvedSnapshotRegistry, | ||
resolvedReleaseRegistry))))); |
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 think all the flatmaps and casting is a little more complicated than necessary. Why not just construct a fresh provider which just happens to call .get()
on all the others?
project.provider(() -> {
return ImageResolver.resolveImageName(p, imagePath.get(), snapshotRegistry.get() ... );
}
} | ||
imageNameBuilder.append(imagePath); | ||
return imageNameBuilder.toString(); | ||
} |
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.
Do you think it's worth doing some regex validation on the imagePath, just so that people don't leave values like docker.palantir/foo/bar
in there and get some bizarre concatenation of everything?
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'm ok with not having validation here, again, keeping parity to how things were before - we weren't validating the scheme of the URI for the full image field.
@iamdanfox any further comments here? |
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.
Looks great, thanks @mccheah!
In the docker image generator, we were originally publishing all built images to the same registry. It is however useful to publish snapshot versions of one's Spark images to one registry, and release versions to another registry. As such, the schema for the configuration is now as follows:
We follow the SLS versioning specification to determine whether or not an image is being built on a release version or a snapshot version.