Skip to content

bug: platform chart accepts registries.mirrors.*.overridePath but patch-containerd renderer ignores it #3331

Open

Description

Describe the bug
cozystack-platform accepts registries.mirrors.<registry>.overridePath: true in platform values, but the generated cozy-system/patch-containerd Secret does not render override_path = true into the generated hosts.toml files.

This breaks path-prefixed containerd mirror endpoints such as:

https://registry.example.com/v2/registry.k8s.io
https://registry.example.com/v2/docker.io

The platform values retain overridePath: true, but the rendered Secret ignores it.

Environment

  • Cozystack version: v1.5.2
  • Provider: on-prem / air-gapped environment

To Reproduce
Steps to reproduce the behavior:

  1. Configure cozystack.cozystack-platform with path-prefixed registry mirror endpoints and overridePath: true:
apiVersion: cozystack.io/v1alpha1
kind: Package
metadata:
  name: cozystack.cozystack-platform
spec:
  variant: isp-full
  components:
    platform:
      values:
        registries:
          mirrors:
            registry.k8s.io:
              endpoints:
                - https://registry.example.com/v2/registry.k8s.io
              overridePath: true
            docker.io:
              endpoints:
                - https://registry.example.com/v2/docker.io
              overridePath: true
          config: {}
  1. Wait for cozystack-platform to reconcile.

  2. Inspect the generated Secret:

kubectl get secret -n cozy-system patch-containerd -o yaml
  1. Decode one of the generated *.toml entries.

Expected behaviour
The generated hosts.toml should include override_path = true for mirrors configured with overridePath: true:

server = "https://registry.k8s.io"

[host."https://registry.example.com/v2/registry.k8s.io"]
  capabilities = ["pull", "resolve"]
  skip_verify = true
  override_path = true

This is required for path-prefixed registry mirror endpoints where the registry API root is encoded in the URL path.

Actual behaviour
The generated hosts.toml omits override_path = true:

server = "https://registry.k8s.io"

[host."https://registry.example.com/v2/registry.k8s.io"]
  capabilities = ["pull", "resolve"]
  skip_verify = true

As a result, containerd does not use the path-prefixed mirror endpoint as intended. Manual edits to cozy-system/patch-containerd are reverted by Helm because the Secret is managed by cozystack-platform.

Logs

No application logs are required to reproduce. The issue is visible in the rendered Secret:

kubectl get secret -n cozy-system patch-containerd -o yaml

Screenshots
Not applicable.

Additional context
The Cozystack air-gapped documentation states that the platform package can generate the patch-containerd Secret from the registries section in platform values, and that this Secret is mounted into tenant worker nodes as containerd hosts.toml configuration.

containerd supports the override_path field in hosts.toml. It is required for mirrors where the registry API root is defined by the URL path.

The platform chart template appears to render endpoints, skip_verify, and auth, but does not render overridePath.

A likely fix is to update:

packages/core/platform/templates/containerd-registry-secret.yaml

to render:

{{- if $mirror.overridePath }}
      override_path = true
{{- end }}

inside each generated [host."..."] block.

Checklist

  • I have checked the documentation
  • I have searched for similar issues
  • I have included all required information
  • I have provided clear steps to reproduce
  • I have included relevant logs

Activity

  1. dosubot commented on Jul 17, 2026

    @dosubot

    Hi Lubricy Fibber (@Lubricy)! I'm Dosu and I'm helping the Cozystack team.

    I can confirm this bug. Looking at the containerd-registry-secret.yaml template, it only renders capabilities, skip_verify, and auth for each [host."..."] block — there is no logic to process or emit override_path from $mirror.overridePath [1]. The values.yaml example structure for registries also doesn't document an overridePath field, so the values schema and the template are both missing support for it.

    Your suggested fix looks correct. In packages/core/platform/templates/containerd-registry-secret.yaml, adding something like:

    {{- if $mirror.overridePath }}
      override_path = true
    {{- end }}
    

    inside each generated [host."..."] block (after the skip_verify line) should produce the expected TOML output. This aligns with containerd's documented hosts.toml schema where override_path instructs the client to use the host's URL path as-is rather than appending the default /v2/<name>/... path.

    To reply, just mention @dosu.


    Share context across your team and agents. Try Dosu.

    Leave Feedback Learn about cozystack with Dosu Add Dosu to your team

  2. github-actions commented on Sep 15, 2026

    @github-actions

    This issue has had no activity for 60 days and was marked lifecycle/stale.
    It will be closed in 14 days unless commented or labelled lifecycle/frozen.

  3. added
    lifecycle/staleDenotes an issue or PR has remained open with no activity and has become stale
    on Sep 15, 2026
  4. added
    area/platformIssues or PRs related to platform infrastructure (bundle, flux, talos, installer)
    triage/acceptedIndicates an issue is ready to be actively worked on
    priority/important-soonMust be staffed and worked on either currently, or very soon, ideally in time for the next release
    and removed
    lifecycle/staleDenotes an issue or PR has remained open with no activity and has become stale
    triage/needs-triageIndicates an issue needs triage by a maintainer
    on Sep 23, 2026
  5. IvanHunters commented on Oct 9, 2026

    @IvanHunters
    Collaborator

    We hit this on a live v1.6 air-gapped deployment and can confirm it — with one extension worth noting.

    Setup: a single pull-through registry (Harbor) exposes each upstream as a path-prefixed project, e.g. https://registry.example.com/v2/docker-io, .../v2/ghcr, .../v2/registry-k8s. Each such endpoint needs override_path, otherwise containerd appends its own /v2/ and requests .../v2/docker-io/v2/<name>/manifests/..., which 404s.

    The gap is not only in the platform patch-containerd renderer. The same overridePath is dropped by the talm-generated RegistryMirrorConfig for the management/Talos nodes (machine.registries.mirrors): the rendered document lists the endpoint URL but omits overridePath: true, so path-prefixed mirrors fail there too.

    Workaround we used (talm chart, templates/_helpers.tpl) — emit overridePath: true whenever the endpoint path contains /v2/:

    endpoints:
    {{- range $cfg.endpoints }}
      - url: {{ . }}
    {{- if regexMatch "/v2(/|$)" (. | toString) }}
        overridePath: true
    {{- end }}
    {{- end }}
    

    After this, management-node pulls (the Talos kubelet image included) go through the path-prefixed Harbor projects correctly.

    Note for v1.6: the tenant-worker patch-containerd Secret was removed (no consumer in the Talos worker machineconfig — see cozystack/website#743). So the fix should land in the talm RegistryMirrorConfig renderer and in the talos.registryMirrors passthrough for tenant workers, not only in the platform patch-containerd path.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/platformIssues or PRs related to platform infrastructure (bundle, flux, talos, installer)kind/bugCategorizes issue or PR as related to a bugpriority/important-soonMust be staffed and worked on either currently, or very soon, ideally in time for the next releasetriage/acceptedIndicates an issue is ready to be actively worked on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions