googleapis / google-cloud-java

Google Cloud Client Library for Java
https://cloud.google.com/java/docs/reference
Apache License 2.0
1.89k stars 1.06k forks source link

Get image by tag #9567

Closed SvetaAndriyanchik closed 1 year ago

SvetaAndriyanchik commented 1 year ago

Hi,

I am using your library for performing scanning in google Artifact Registry. Version I am using is: implementation("com.google.cloud:google-cloud-artifact-registry:1.18.0")

With the following code I was able to get image metadata:

GetDockerImageRequest request = GetDockerImageRequest.newBuilder()
                    .setName(
                        DockerImageName.of("my-project",
                                "europe", "repository", "imageName@sha256:0a4994d8f9b0aba9e142e9bf09cf140798dde2f22a31ab41645aee41b8f24b16")
                            .toString())
                    .build();
                DockerImage dockerImage = artifactRegistryClient.getDockerImage(request);

Here I had to use digest of the image to be able to access it. I tried to get the same image by tag. Like this:

GetDockerImageRequest request = GetDockerImageRequest.newBuilder()
                    .setName(
                        DockerImageName.of("my-project",
                                "europe", "repository", "imageName:1.0.0")
                            .toString())
                    .build();

but then I got an error: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Request contains an invalid argument.

Is there a possibility to get image by tag using your library?

Thank you in advance

suztomo commented 1 year ago

Would you share the entire stacktrace of the error message?

Also, this is a reference document for the client library. https://cloud.google.com/java/docs/reference/google-cloud-artifact-registry/latest/com.google.devtools.artifactregistry.v1.

GetDockerImageRequest.newBuilder()
                   .setName(
                      DockerImageName.of("my-project",
                               "europe", "repository", "imageName:1.0.0")
                          .toString())

I suspect that the value from ".toString()" is not a valid name for Docker image.

SvetaAndriyanchik commented 1 year ago

Here is the stack trace of the following request (if I replace the last parameter application:100.33.4 with digest, it will work fine):

GetDockerImageRequest request = GetDockerImageRequest.newBuilder()
                    .setName(
                        DockerImageName.of("my-project",
                                "europe", "docker", "application:100.33.4")
                            .toString())
                    .build();
                DockerImage dockerImage2 = artifactRegistryClient.getDockerImage(request);

io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Request contains an invalid argument. com.google.api.gax.rpc.InvalidArgumentException: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Request contains an invalid argument. at app//com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:92) at app//com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:41) at app//com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:86) at app//com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:66) at app//com.google.api.gax.grpc.GrpcExceptionCallable$ExceptionTransformingFuture.onFailure(GrpcExceptionCallable.java:97) at app//com.google.api.core.ApiFutures$1.onFailure(ApiFutures.java:84) at app//com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1132) at app//com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31) at app//com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1270) at app//com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1038) at app//com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:808) at app//io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:574) at app//io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:544) at app//io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39) at app//io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23) at app//io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40) at app//com.google.api.gax.grpc.ChannelPool$ReleasingClientCall$1.onClose(ChannelPool.java:541) at app//io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:567) at app//io.grpc.internal.ClientCallImpl.access$300(ClientCallImpl.java:71) at app//io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:735) at app//io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:716) at app//io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37) at app//io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133) at java.base@17.0.7/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base@17.0.7/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base@17.0.7/java.lang.Thread.run(Thread.java:833) Suppressed: com.google.api.gax.rpc.AsyncTaskException: Asynchronous task failed at app//com.google.api.gax.rpc.ApiExceptions.callAndTranslateApiException(ApiExceptions.java:57) at app//com.google.api.gax.rpc.UnaryCallable.call(UnaryCallable.java:112) at app//com.google.devtools.artifactregistry.v1.ArtifactRegistryClient.getDockerImage(ArtifactRegistryClient.java:453) at app//com.king.ctl.auth.AuthContextValidatorTest.test(AuthContextValidatorTest.java:78) at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base@17.0.7/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568) at app//org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727) at app//org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at app//org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156) at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147) at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base@17.0.7/java.util.ArrayList.forEach(ArrayList.java:1511) at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base@17.0.7/java.util.ArrayList.forEach(ArrayList.java:1511) at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at app//org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62) at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base@17.0.7/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) at jdk.proxy2/jdk.proxy2.$Proxy5.stop(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65) at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) Caused by: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Request contains an invalid argument. at app//io.grpc.Status.asRuntimeException(Status.java:539) ... 14 more

suztomo commented 1 year ago

Thank you for stacktrace. Reassigning to Lawrence.

lqiu96 commented 1 year ago

Hi @SvetaAndriyanchik, thanks for providing a snippet. I was able to reproduce this locally.

I took a look at the underlying proto and found that it seems to suggest that we're supposed to be providing a digest for docker image parameter: https://github.com/googleapis/googleapis/blob/974c49f05ed50ba22fa471a29eabb5959581e3ac/google/devtools/artifactregistry/v1/artifact.proto#L51

I uploaded a sample hello-world container to my local artifact registry and pulled it down to see what the server is responding with. I see that the DockerImage's name is returned as projects/{MY_PROJECT}/locations/us-east4/repositories/test-repository/dockerImages/hello-world@sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3

Do you have a constraint with including the digest as part of the name in the request?

SvetaAndriyanchik commented 1 year ago

hi @lqiu96 thank you for the update. yes, I also noticed that name has a digest part in it. so there is no way to pull image by tag?

lqiu96 commented 1 year ago

Unfortunately, I don't think so (my local tests also haven't been able to find a way). It seems that the server is expecting a digest in the URL path.

lqiu96 commented 1 year ago

Feel free to comment or re-open if you have further questions. Going to close this.