Description
In GitLab, projects have concrete image names that matches projects. The image name is provided to build script in environment variable CI_REGISTRY_IMAGE. However, variable also contains repository name so it does not work with container-image (I tested with JIB):
CI_REGISTRY_IMAGE=gitlab.company.hr:1111/group/subgroup/project
If this is used as image or registry, Quarkus throws exception.
Please add support for full image path in container-image configuration.
Exception:
[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:1.4.0.CR1:build (default) on project asc-api-service: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[ERROR] [error]: Build step io.quarkus.container.image.jib.deployment.JibProcessor#buildFromJar threw an exception: java.lang.IllegalArgumentException: The supplied container-image registry 'gitlab.company.hr:1111/group/subgroup/project' is invalid
[ERROR] at io.quarkus.container.image.jib.deployment.JibProcessor.getImageReference(JibProcessor.java:190)
[ERROR] at io.quarkus.container.image.jib.deployment.JibProcessor.createContainerizer(JibProcessor.java:138)
[ERROR] at io.quarkus.container.image.jib.deployment.JibProcessor.containerize(JibProcessor.java:121)
[ERROR] at io.quarkus.container.image.jib.deployment.JibProcessor.buildFromJar(JibProcessor.java:79)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR] at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[ERROR] at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:931)
[ERROR] at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
[ERROR] at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
[ERROR] at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2027)
[ERROR] at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1551)
[ERROR] at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1442)
[ERROR] at java.base/java.lang.Thread.run(Thread.java:834)
[ERROR] at org.jboss.threads.JBossThread.run(JBossThread.java:479)
Implementation ideas
@geoand I believe this is what we discussed in #8117
Yeah, exactly.
I'm open to suggestions :)
Similar, it was more about the number of subgroups ("groups" attribute can contain "/" so it is not an issue).
Spotify plugin accepts all values as-is. AFAIK they do not have group concept.
@zeljkot could you describe your workflow?
I would like to know more in order to see how best we can accommodate the largest amount of users.
So, we have GitLab script that runs on Maven image. In that script we use predefined environment variables provided by GitLab to build images. My application.yaml looks like this:
quarkus:
container-image:
group: atries-rx/asc
registry: ${CI_REGISTRY}
username: ${CI_REGISTRY_USER}
password: ${CI_REGISTRY_PASSWORD}
The application name and version are taken from pom.xml by Quarkus. Note that all CI_* variables are standard predefined variables provided by GitLab. The image name is built from the application name and quarkus.container-image.group. As image name must match what GitLab expects, there is a risk that something will be misconfigured (e.g. copy-pasted without fixing). It would be safer if I can write
quarkus:
container-image:
imageName: ${CI_REGISTRY_IMAGE}
registry: ${CI_REGISTRY}
username: ${CI_REGISTRY_USER}
password: ${CI_REGISTRY_PASSWORD}
This is how we configure the Spotify plugin that is used in other projects.
In CI script .gitlab-ci.yml I have something like this:
image: $CI_REGISTRY/docker/maven-build:latest
stages:
- build
variables:
...
build:
stage: build
script:
- mvn -Dquarkus.container-image.build=true -Dquarkus.container-image.push=true clean package
Please let me know if you need anything else.
Here is what I propose:
Provide the optional quarkus.container-image.image-name property, which if set, will take precedence of over the individual components (and we probably want to warn if both are used).
@Ladicek @iocanel does that sounds reasonable? Anything you see that could be an issue?
Hm... Even if we do that I am not sure that Jib supports it - I would need to check.
Agree. I don't think there's a better way.
Even if we do that I am not sure that Jib supports it
well, you could split things yourself, couldn't you?
Even if we do that I am not sure that Jib supports it
well, you could split things yourself, couldn't you?
Probably yeah. It could be super brittle of course. I'll hopefully give this a look tomorrow.
I am a little unclear on whether the proposed imageName would contain the tag or not.
Also it feels a little weird that t he registry is not part of the imageName... I think that might backfire.
Jib does allow for arbitrary levels in the image name without issue. So all we have to do is decide the proper configuration here.
Jib uses the term reference to include everything - the registry, the repository (which is the term jib uses for the groups + name) and the tag.
I propose we do the same - we keep the separate registry, group, name and tag we have now, but also introduce a property called reference that includes them all.
The other option would be to keep registry separate, but I think that would confusing.
WDYT?
Note that tag is not constant so I would keep it separate (and mapped to pom.xml version like it is now). That is called "image" in JIB documentation.
Another super-useful feature would be to allow multiple tags per image. For example, same PostgreSQL image can have tags "latest", "12" and "12.5". We also use multiple tags per image for our internal process. If that is not supported, I can open a separate issue.
the
repository(which is the term jib uses for the groups + name)
I think this is actually a standard terminology. E.g. https://docs.docker.com/registry/spec/api/#listing-repositories says:
Images are stored in collections, known as a _repository_
Or https://stackoverflow.com/questions/34004076/difference-between-docker-registry-and-repository -- actually if I google for "docker registry repository", I get almost 1 million results :-)
I don't know where the group/name thing comes from.
reference is a nice name, I like it.
Another super-useful feature would be to allow multiple tags per image. For example, same PostgreSQL image can have tags "latest", "12" and "12.5". We also use multiple tags per image for our internal process. If that is not supported, I can open a separate issue.
Sounds interesting indeed. Let's have another issue for that.
Since, the registry and tag are not part of it, the name we should use for this property is repository, which is what docker uses.
EDIT: Based on the output of docker images.
Agree that the correct name is repository, if it's supposed to only configure what is now configured with the group/name pair.
So we agree on adding a new property named repository that won't contain the registry and won't contain the tag either?
FWIW, there is a chance that the existing code base is misusing the word repository as a synonym of group and I can see that causing confusion if it is true.
I'll take that into account and rename wherever needed.
So we agree on adding a new property named
repositorythat won't contain the registry and won't contain the tag either?
We are back to square one then because GitLab CI_REGISTRY_IMAGE contains registry so it is not usable for this issue. You have support for group/name pair because group can be empty.
It is OK if you want to replace name with something else, but that still does not solve the original problem:
CI_REGISTRY_IMAGE=gitlab.company.hr:1111/group/subgroup/project
In JIB's documentation, this is called "image". Looking at the variable name, it is called "image" in GitLab, too.
Gitlab is really messing up here...
I wonder if other CI environments do the same... If they do, they I guess we should oblidge. If it's only Gitlab that has this behavior, I don't know if it makes sense to go down that route.
@geoand as discussed, I think this one is important.
Also see https://stackoverflow.com/questions/63813368/can-t-push-to-gitlab-registry-quarkus-jib-build
I'll try and carve out some time to play with GitLab and see how we can improve
I think we'll have to introduce a new (optional) property in container-image config which will basically contain the entire string.
This is a good opportunity to consolidate the container image resolution and information passing - so I'll pick it up on Monday
Yeah or you could imagine it being some string template with placeholders.
My initial intention was to do as little work as possible on this (and that is rather quick to do), but I think that it presents a good opportunity to clear out some technical debt
https://github.com/quarkusio/quarkus/pull/12070 should take care of this
There is a small issue with this fix: it overrides the default tag value (version) with the "latest". So I get only "latest" and additional-tags and not x.y.z-SNAPSHOT and additional-tags. Whatever I put in container-image.tag is ignored and the "latest" is used.
Note that JIB's and GitLab's definition of an image is different: JIB's contains a version while GitLab's does not.
Can you please open a new issue about this?
No problem.
Most helpful comment
So we agree on adding a new property named
repositorythat won't contain the registry and won't contain the tag either?