nerdctl icon indicating copy to clipboard operation
nerdctl copied to clipboard

nerdctl pull Specifies the default repository address

Open kubecto opened this issue 1 year ago • 8 comments

What is the problem you're trying to solve

If you want to pull an image, you can specify the default image repository pull in the configuration file

Describe the solution you'd like

nerdctl pull controller/controller-alpine:2.6.0
WARN[0000] skipping verifying HTTPS certs for "docker.io"
docker.io/controller/controller-alpine:2.6.0: resolving      |--------------------------------------|
docker.io/controller/controller-alpine:2.6.0: resolving      |--------------------------------------|
elapsed: 2.5 s                                total:   0.0 B (0.0 B/s)

The default pull is docker.io. I want to specify the pull address in the configuration file, not on the command line. docker pull can support pulling the image of the specified repository in daemon.json

Additional context

No response

kubecto avatar Feb 27 '24 06:02 kubecto

Looking at the codebase, the ref parsing is actually done by containerd. We can see that, in the EnsureImage func, nerdctl makes a call to ParseDockerRef(rawref) in containerd. It follows a couple of function calls till it lands in splitDockerDomain(). Here we can see that defaultDomain is used if no domain name is provided, which is docker.io, and AFAIK there's not a way to change this in containerd's TOML.

We can implement this in nerdctl or containerd. The former seems somewhat redundant if we want to be comprehensive, but the latter is probably a lot messier. containerd 2.0 puts all of these functions into its own repository (https://github.com/distribution/reference), and my guess is that nerdctl will support 2.0 ASAP once it releases. So, I think it would be best to add this functionality on nerdctl's side.

We can probably add a somewhat simple solution, along the lines of this pseudo-code

// Parse config
DefaultRepo = ""
parseConfig() // DefaultRepo set to its value in nerdctl.toml


// pkg/imgutil.go
func EnsureImage()
...
if DefaultRepo!= "" {
  domain, _ := splitRef(rawref) // separate domain from ref/tag
  if domain == "" {
    rawref = DefaultRepo + rawref
  }
}
ParseDockerRef(rawref)
// Rest of workflow proceeds as normal

I can push out a PR implementing this, but I just want confirmation that this is the direction we want.

sondavidb avatar Mar 07 '24 22:03 sondavidb

Ideally this should be implemented in https://github.com/containerd/containerd/blob/main/docs/hosts.md

AkihiroSuda avatar Mar 07 '24 23:03 AkihiroSuda

Sorry, to clarify, are you saying this is already available in containerd? Or are you suggesting this feature should be implemented in the config file in containerd? I was assuming the former but could not get the desired behavior.

sondavidb avatar Mar 08 '24 00:03 sondavidb

The latter

AkihiroSuda avatar Mar 08 '24 01:03 AkihiroSuda

Got it, I'll open an issue upstream. Thanks for the clarification!

sondavidb avatar Mar 08 '24 05:03 sondavidb

Opened an issue in containerd: https://github.com/containerd/containerd/issues/9954. Feel free to add your own thoughts to the issue. As mentioned there, I do need some clarification before I can gauge the effort required, but if so I can attempt to drive the PR. No guarantees yet, however.

sondavidb avatar Mar 08 '24 23:03 sondavidb

Apologies, been sidetracked by other things to get any headway on this.

Taking a step back, I believe the two ideas mentioned here are related but separate.

containerd should definitely have something in the hosts file that would ultimately plumb in somewhere here. However, this would not solve the issue in nerdctl, as distribution/reference will still qualify it with a docker prefix here. So, even if I were to make this change, nerdctl would still need additional changes to prepend the desired repo before sending it through ParseDockerRef. This change alone would also solve the immediate issue present here.

I'll try to make some time to at least get the latter ask done. This would likely include a new global flag and I'd have to ensure every call to ParseDockerRef gets the specified prefix added, so the initial analysis seems to show that this will take a fair amount of effort.

sondavidb avatar Apr 04 '24 23:04 sondavidb

@sondavidb IIRC did you try using the mirror mechanism?

https://github.com/containerd/containerd/blob/main/docs/hosts.md#setup-a-local-mirror-for-docker

I have not used this in a while, but IIRC you can just "point" docker.io to whatever local registry under your control with this.

apostasie avatar May 14 '24 19:05 apostasie