From 3c33638ceb7166f5516c3064195bde6faf22559d Mon Sep 17 00:00:00 2001 From: alan blount Date: Sun, 14 Jun 2026 17:44:17 +0000 Subject: [PATCH 1/2] feat: add image_pinned to skip registry rewrite for custom images Templates that specify a fully-qualified custom image (e.g. ghcr.io/myorg/scion-myimage:latest) currently get their registry prefix rewritten by the broker's image_registry setting. This makes it impossible to use custom scion-* images hosted in external registries without push access to the broker's registry. Add an `image_pinned` field to ScionConfig. When set to true in a template's scion-agent.yaml, the image is used as-is without registry rewriting. --- pkg/agent/run.go | 7 ++++++- pkg/api/types.go | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/agent/run.go b/pkg/agent/run.go index ced5bdbc8..8fc61da28 100644 --- a/pkg/agent/run.go +++ b/pkg/agent/run.go @@ -309,7 +309,12 @@ func (m *AgentManager) Start(ctx context.Context, opts api.StartOptions) (*api.A // Apply image_registry rewrite to whatever image was resolved above. // This rewrites the registry prefix for scion-* images. An explicit // --image flag below takes full precedence (no rewrite). - if settings != nil && resolvedImage != "" { + // When image_pinned is set in the agent/template config, the image is + // used as-is without registry rewriting. + imagePinned := finalScionCfg != nil && finalScionCfg.ImagePinned + if imagePinned { + util.Debugf("image resolution: image_pinned=true, skipping registry rewrite") + } else if settings != nil && resolvedImage != "" { imageRegistry := settings.ResolveImageRegistry(opts.Profile) if imageRegistry != "" { rewritten := config.RewriteImageRegistry(resolvedImage, imageRegistry) diff --git a/pkg/api/types.go b/pkg/api/types.go index 659250937..fa066fccf 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -447,8 +447,9 @@ type ScionConfig struct { Kubernetes *KubernetesConfig `json:"kubernetes,omitempty" yaml:"kubernetes,omitempty"` AuthSelectedType string `json:"auth_selectedType,omitempty" yaml:"auth_selectedType,omitempty"` Resources *ResourceSpec `json:"resources,omitempty" yaml:"resources,omitempty"` - Image string `json:"image,omitempty" yaml:"image,omitempty"` - Services []ServiceSpec `json:"services,omitempty" yaml:"services,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + ImagePinned bool `json:"image_pinned,omitempty" yaml:"image_pinned,omitempty"` + Services []ServiceSpec `json:"services,omitempty" yaml:"services,omitempty"` // MCPServers is the universal MCP server map. Keys are server names; values // are the transport-agnostic config translated by each harness's // container-side provisioner into native format. From ef8c3e8e5e24245475df86ad72f260e24fd21aa9 Mon Sep 17 00:00:00 2001 From: alan blount Date: Tue, 16 Jun 2026 03:49:56 +0000 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20address=20review=20comments=20?= =?UTF-8?q?=E2=80=94=20gofmt=20alignment=20+=20idiomatic=20Go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/agent/run.go | 3 +-- pkg/api/types.go | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/pkg/agent/run.go b/pkg/agent/run.go index 8fc61da28..6fe4fa517 100644 --- a/pkg/agent/run.go +++ b/pkg/agent/run.go @@ -311,8 +311,7 @@ func (m *AgentManager) Start(ctx context.Context, opts api.StartOptions) (*api.A // --image flag below takes full precedence (no rewrite). // When image_pinned is set in the agent/template config, the image is // used as-is without registry rewriting. - imagePinned := finalScionCfg != nil && finalScionCfg.ImagePinned - if imagePinned { + if finalScionCfg != nil && finalScionCfg.ImagePinned { util.Debugf("image resolution: image_pinned=true, skipping registry rewrite") } else if settings != nil && resolvedImage != "" { imageRegistry := settings.ResolveImageRegistry(opts.Profile) diff --git a/pkg/api/types.go b/pkg/api/types.go index fa066fccf..339bdb7a5 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -447,9 +447,9 @@ type ScionConfig struct { Kubernetes *KubernetesConfig `json:"kubernetes,omitempty" yaml:"kubernetes,omitempty"` AuthSelectedType string `json:"auth_selectedType,omitempty" yaml:"auth_selectedType,omitempty"` Resources *ResourceSpec `json:"resources,omitempty" yaml:"resources,omitempty"` - Image string `json:"image,omitempty" yaml:"image,omitempty"` - ImagePinned bool `json:"image_pinned,omitempty" yaml:"image_pinned,omitempty"` - Services []ServiceSpec `json:"services,omitempty" yaml:"services,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + ImagePinned bool `json:"image_pinned,omitempty" yaml:"image_pinned,omitempty"` + Services []ServiceSpec `json:"services,omitempty" yaml:"services,omitempty"` // MCPServers is the universal MCP server map. Keys are server names; values // are the transport-agnostic config translated by each harness's // container-side provisioner into native format.