Skip to content
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

Multi-tag support for push operation and convention plugins #867

Merged
merged 7 commits into from
Oct 14, 2019

Conversation

bmuschko
Copy link
Owner

@bmuschko bmuschko commented Oct 6, 2019

This change takes a step-wise approach for the work started in #835.

This is a breaking change and will be delivered with the next major version. The property for defining a single tag has been removed without a deprecation cycle. Unify other custom tasks to simplify and unify API.

  • In its current implementation there's a one to one map from built tags to pushed tags. A later PR might introduce logic to make the push operation more selective about which tags to push.
  • The API of the push task didn't align with the build task. Separating the repository from the tag led to misunderstandings from end users. Unifying both APIs makes a much easier to hand over the tags property values. The same goes for other tasks.
  • Removed the method DockerPullImage.getImageId(). The returned value didn't really represent the image ID and therefore wasn't accurate. In fact you'd have to represent a list of image IDs if done right. You can simply ask for the Provider value of the tag property if required.

This is a breaking change. The property for defining a single tag has been removed without a deprecation cycle. Unify other custom tasks to simplify and unify API.
@bmuschko bmuschko added this to the v6.0.0 milestone Oct 6, 2019
@bmuschko bmuschko requested review from cdancy and orzeh October 6, 2019 14:47
@bmuschko bmuschko self-assigned this Oct 6, 2019
Just use one String to represent both values. In most cases, users are use to that notation anyway.
Copy link
Collaborator

@orzeh orzeh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern with this feature is that we break an assumption that each task is an atomic interaction with Docker API. If we have 3 tags and pushing the second one fails, the build ends up in inconsistent state, meaning you don't know which tags were pushed successfully. I guess we have to provide some hook for users to compensate in case of an error. But probably we can add this later if someone asks for this.

logger.quiet "Pushing image with name '${imageName.get()}'."
}
if(registryCredentials) {
AuthConfig authConfig = new AuthConfig()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AuthConfig can be created only once outside each loop?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to look into it.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -47,49 +41,45 @@ class DockerPushImage extends AbstractDockerRemoteApiTask implements RegistryCre

@Override
void runRemoteCommand() {
PushImageCmd pushImageCmd = dockerClient.pushImageCmd(imageName.get())
tags.get().each { currentTag ->
logger.quiet "Pushing image with name '${currentTag}'."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should change name to tag.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Will change that. Technically, tag is the wrong term here as well as we are talking about <repository>/<image-name>:<tag>. I don't think there's really a blanket term in Docker that would cover all of this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would argue just to say Pulling image ${currentImage} (goes inline with comments I made above).

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@bmuschko
Copy link
Owner Author

bmuschko commented Oct 7, 2019

My only concern with this feature is that we break an assumption that each task is an atomic interaction with Docker API. If we have 3 tags and pushing the second one fails, the build ends up in inconsistent state, meaning you don't know which tags were pushed successfully. I guess we have to provide some hook for users to compensate in case of an error. But probably we can add this later if someone asks for this.

Docker Java doesn't offer an API for providing multiple tags at the moment. I am not sure how we'd make this atomic. Let's say the first push worked but the second push failed, I am not sure how we'd properly handle the situation. I am not aware of a call that can delete a remote Docker image so there's no real rollback or atomic commit functionality.

I am not sure how a user-facing callback could help. There's nothing a user can do to delete a remote image either. Maaaaybe write out a custom error message but I am hoping that Docker Java provides a useful message here.

Let's me know how you think this could work as atomic operation and we can discuss options.

@orzeh
Copy link
Collaborator

orzeh commented Oct 7, 2019

Docker Java doesn't offer an API for providing multiple tags at the moment. I am not sure how we'd make this atomic. Let's say the first push worked but the second push failed, I am not sure how we'd properly handle the situation. I am not aware of a call that can delete a remote Docker image so there's no real rollback or atomic commit functionality.

Probably that's the reason why this option is not built into Docker itself :)

I guess we don't have to worry about it that much, but maybe we should just add one sentence to the User Guide so that people are aware.

@@ -12,7 +12,7 @@ docker {
baseImage = 'dockerfile/java:openjdk-7-jre'
maintainer = 'Benjamin Muschko "benjamin.muschko@gmail.com"'
ports = [9090, 5701]
tag = 'jettyapp:1.115'
tags = ['jettyapp:1.115']
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe provide multiple tags here so that users will know how things work? Possibly the same comment for other doc-related changes.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

*/
@Input
@Optional
final Property<String> repository = project.objects.property(String)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're removing this property a "better" name might be to just use image as that technically encompasses the entire URL. It's at least what is used within the docker docs all over the place.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@cdancy
Copy link
Collaborator

cdancy commented Oct 11, 2019

LGTM and I like the new functionality. Have at least one place we'll be able to take advantage of this internally for which we have custom code to do this (though admittedly not as clean :) )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants