orlangure/gnomock

Unable to start image stored in private Docker repo

Closed this issue · 2 comments

jf647 commented

Describe the bug

I am trying to bring up a custom container using gnomock.StartContainer(). The image is hosted on Google Container Registry (gcr.io), which requires authentication.

The container fails to start with the error:

can't start container: can't pull image: can't pull image: Error response from daemon: unauthorized: You don't have the needed permissions to perform this operation, and you may have invalid credentials. To authenticate your request, follow the steps in: https://cloud.google.com/container-registry/docs/advanced-authentication

docker pull for the same image works just fine however:

$ docker pull gcr.io/nadt-184401/bnet-fake-apiserver-0.1.5-2021-06-08
Using default tag: latest
latest: Pulling from nadt-184401/bnet-fake-apiserver-0.1.5-2021-06-08
5dea5ec2316d: Pull complete
cc6ee50445b3: Pull complete
Digest: sha256:3d16cbb203efac08a83022f2517e89e124c3425c62db1905dd9dc2f2721f9ec3
Status: Downloaded newer image for gcr.io/nadt-184401/bnet-fake-apiserver-0.1.5-2021-06-08:latest
gcr.io/nadt-184401/bnet-fake-apiserver-0.1.5-2021-06-08:latest

To Reproduce

func TestGetCharacter(t *testing.T) {
	ctx := context.Background()

	// Spin up a fake for the Battle.Net API server
	bn, err := gnomock.StartCustom(
		"gcr.io/nadt-184401/bnet-fake-apiserver-0.1.5-2021-06-08",
		map[string]gnomock.Port{
			"http": {Protocol: "TCP", Port: 8080},
		},
		gnomock.WithDebugMode(),
	)
	if err != nil {
		t.Fatalf("starting gnomock bnet api fake: %v", err)
	}
	defer gnomock.Stop(bn)
}

Expected behavior

If docker pull works for a given image, gnomock should also be able to start that image.

System (please complete the following information):

  • OS: Ubuntu
  • Version 20.04
  • Docker version 20.10.6 (CE)

Additional context

The root cause is likely that Gnomock passes a fixed, empty set of pull options to the Docker client. If there were an way to pass ImagePullOptions to .StartCustom, then I could probably get around this by base64 encoding the required config.

Ideally, it would be nice if the docker client just used my ~/docker/config.json and "did the right thing", but that doesn't seem to be part of the docker client package. Another option would be to allow the HTTP client to be passed via a Gnomock option, but that's just asking the user to manage the crafting of the X-Registry-Auth header (which is what passing an ImagePullOptions struct with a populated RegistryAuth does for you.)

Hi @jf647, thanks for the report. I'll take a look in the next few days. Your research and recommendations will certainly help😼

@jf647,
I got to it a bit earlier than I thought. Can you give #190 a try before I merge it?