diff --git a/internal/cloudapi/v2/server.go b/internal/cloudapi/v2/server.go index 808197c3e..f522b625f 100644 --- a/internal/cloudapi/v2/server.go +++ b/internal/cloudapi/v2/server.go @@ -419,6 +419,17 @@ func serializeManifest(ctx context.Context, manifestSource *manifest.Manifest, w }, } + // add osbuild/images dependency info to job result + osbuildImagesDep, err := common.GetDepModuleInfoByPath(common.OSBuildImagesModulePath) + if err != nil { + // do not fail here and just log the error, because the module info is not available in tests. + // Failing here would make the unit tests fail. See https://github.com/golang/go/issues/33976 + logWithId.Errorf("Error getting %s dependency info: %v", common.OSBuildImagesModulePath, err) + } else { + osbuildImagesDepModule := worker.ComposerDepModuleFromDebugModule(osbuildImagesDep) + jobResult.ManifestInfo.OSBuildComposerDeps = append(jobResult.ManifestInfo.OSBuildComposerDeps, osbuildImagesDepModule) + } + defer func() { if jobResult.JobError != nil { logWithId.Errorf("Error in manifest job %v: %v", jobResult.JobError.Reason, err) diff --git a/internal/common/dependencies.go b/internal/common/dependencies.go new file mode 100644 index 000000000..372ef2f19 --- /dev/null +++ b/internal/common/dependencies.go @@ -0,0 +1,28 @@ +package common + +import ( + "fmt" + "runtime/debug" +) + +const ( + OSBuildImagesModulePath = "github.com/osbuild/images" +) + +// GetDepModuleInfoByPath returns the debug.Module for the dependency +// with the given path. If the dependency is not found, an error is +// returned. +func GetDepModuleInfoByPath(path string) (*debug.Module, error) { + buildinfo, ok := debug.ReadBuildInfo() + if !ok { + return nil, fmt.Errorf("Failed to read build info") + } + + for _, dep := range buildinfo.Deps { + if dep.Path == path { + return dep, nil + } + } + + return nil, fmt.Errorf("Could not find dependency %s", path) +} diff --git a/internal/worker/json.go b/internal/worker/json.go index 8ca8a039f..32938c240 100644 --- a/internal/worker/json.go +++ b/internal/worker/json.go @@ -3,6 +3,7 @@ package worker import ( "encoding/json" "fmt" + "runtime/debug" "github.com/osbuild/images/pkg/distro" "github.com/osbuild/images/pkg/manifest" @@ -265,10 +266,40 @@ type DepsolveJobResult struct { type ManifestJobByID struct{} +// OSBuildComposerDepModule contains information about a module used by +// osbuild-composer which could affect the manifest content. +type OSBuildComposerDepModule struct { + Path string `json:"path"` + Version string `json:"version"` + Replace *OSBuildComposerDepModule `json:"replace,omitempty"` +} + +// ComposerDepModuleFromDebugModule converts a debug.Module instance +// to an OSBuildComposerDepModule instance. +func ComposerDepModuleFromDebugModule(module *debug.Module) *OSBuildComposerDepModule { + if module == nil { + return nil + } + depModule := &OSBuildComposerDepModule{ + Path: module.Path, + Version: module.Version, + } + if module.Replace != nil { + depModule.Replace = &OSBuildComposerDepModule{ + Path: module.Replace.Path, + Version: module.Replace.Version, + } + } + return depModule +} + // ManifestInfo contains information about the environment in which // the manifest was produced and which could affect its content. type ManifestInfo struct { OSBuildComposerVersion string `json:"osbuild_composer_version"` + // List of relevant modules used by osbuild-composer which + // could affect the manifest content. + OSBuildComposerDeps []*OSBuildComposerDepModule `json:"osbuild_composer_deps,omitempty"` } type ManifestJobByIDResult struct {