fix(spdx): use configured external URL in document namespace

Hardcoded `factory.talos.dev` in SPDX document namespace broke
deployments where image-factory runs under a different hostname.
External URL now threads from service config through SPDXOptions
and Builder down to namespace generation.

Fixes #440

Signed-off-by: Mateusz Urbanek <mateusz.urbanek@siderolabs.com>
This commit is contained in:
Mateusz Urbanek 2026-05-01 06:29:03 +02:00
parent ccffefc072
commit 114bb60b13
No known key found for this signature in database
GPG Key ID: F16F84591E26D77F
7 changed files with 18 additions and 6 deletions

View File

@ -192,6 +192,7 @@ func buildEnterprisePlugins(
}
spdxFrontend, err := enterprise.NewSpdxFrontend(logger, enterprise.SPDXOptions{
ExternalURL: opts.HTTP.ExternalURL,
SchematicFactory: configFactory,
ArtifactsManager: artifactsManager,
AssetBuilder: assetBuilder,

View File

@ -42,21 +42,23 @@ type AuthProvider interface {
// Builder orchestrates SPDX extraction and caching.
type Builder struct {
storage storage.Storage
sf singleflight.Group
authProvider AuthProvider
artifactsManager *artifacts.Manager
assetBuilder *asset.Builder
schematicFactory *schematic.Factory
logger *zap.Logger
sf singleflight.Group
authProvider AuthProvider
externalURL string
}
// Options defines the dependencies for the SPDX builder.
type Options struct {
Storage storage.Storage
AuthProvider AuthProvider
ArtifactsManager *artifacts.Manager
SchematicFactory *schematic.Factory
AssetBuilder *asset.Builder
AuthProvider AuthProvider
ExternalURL string
}
// NewBuilder creates a new SPDX bundle builder.
@ -65,6 +67,7 @@ func NewBuilder(
opts Options,
) *Builder {
return &Builder{
externalURL: opts.ExternalURL,
storage: opts.Storage,
artifactsManager: opts.ArtifactsManager,
schematicFactory: opts.SchematicFactory,
@ -136,6 +139,7 @@ func (b *Builder) buildBundle(sc *schematicpkg.Schematic, schematicID, versionTa
SchematicID: schematicID,
TalosVersion: versionTag,
Arch: string(arch),
ExternalURL: b.externalURL,
Files: []File{},
}

View File

@ -41,6 +41,9 @@ type Bundle struct {
// Arch is the target architecture (e.g., "amd64").
Arch string
// ExternalURL is the host used in the document namespace (e.g., "factory.sidero.dev").
ExternalURL string
// Files contains the extracted SPDX files.
Files []File
}
@ -60,7 +63,8 @@ func BundleToJSON(bundle *Bundle) (io.Reader, int64, error) {
SPDXIdentifier: common.ElementID("DOCUMENT"),
DocumentName: fmt.Sprintf("talos-%s-%s-%s", bundle.SchematicID, bundle.TalosVersion, bundle.Arch),
DocumentNamespace: fmt.Sprintf(
"https://factory.talos.dev/spdx/%s/%s/%s",
"https://%s/spdx/%s/%s/%s",
bundle.ExternalURL,
bundle.SchematicID,
bundle.TalosVersion,
bundle.Arch,

View File

@ -11,10 +11,10 @@ import (
"net/http"
"testing"
"github.com/siderolabs/image-factory/pkg/client"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/siderolabs/image-factory/pkg/client"
"github.com/siderolabs/image-factory/pkg/enterprise"
schematicpkg "github.com/siderolabs/image-factory/pkg/schematic"
)

View File

@ -79,7 +79,8 @@ func testSPDXFrontend(ctx context.Context, t *testing.T, baseURL string) {
assert.Equal(t, spdx.Version, doc.SPDXVersion)
assert.Equal(t, spdx.DataLicense, doc.DataLicense)
assert.Contains(t, doc.DocumentName, "talos-"+emptySchematicID)
assert.Contains(t, doc.DocumentNamespace, "https://factory.talos.dev/spdx/"+emptySchematicID)
assert.Contains(t, doc.DocumentNamespace, "https://")
assert.Contains(t, doc.DocumentNamespace, "/spdx/"+emptySchematicID)
require.NotNil(t, doc.CreationInfo)
assert.NotEmpty(t, doc.CreationInfo.Creators)
})

View File

@ -29,6 +29,7 @@ type FrontendPlugin interface {
// SPDXOptions holds configuration options for the SPDX frontend.
type SPDXOptions struct {
ExternalURL string
CacheImageSigner signer.Signer
SchematicFactory *schematic.Factory
ArtifactsManager *artifacts.Manager

View File

@ -48,6 +48,7 @@ func NewSpdxFrontend(logger *zap.Logger, opts SPDXOptions) (FrontendPlugin, erro
}
builder := builder.NewBuilder(logger, builder.Options{
ExternalURL: opts.ExternalURL,
Storage: storage,
ArtifactsManager: opts.ArtifactsManager,
SchematicFactory: opts.SchematicFactory,