package main import ( "fmt" "os" "path/filepath" "strings" "github.com/osbuild/image-builder-cli/pkg/progress" "github.com/osbuild/images/pkg/imagefilter" ) type buildOptions struct { OutputDir string StoreDir string OutputBasename string WriteManifest bool WriteBuildlog bool } func buildImage(pbar progress.ProgressBar, res *imagefilter.Result, osbuildManifest []byte, opts *buildOptions) (string, error) { if opts == nil { opts = &buildOptions{} } basename := basenameFor(res, opts.OutputBasename) if opts.WriteManifest { p := filepath.Join(opts.OutputDir, fmt.Sprintf("%s.osbuild-manifest.json", basename)) if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil { return "", err } if err := os.WriteFile(p, osbuildManifest, 0644); err != nil { return "", err } } osbuildOpts := &progress.OSBuildOptions{ StoreDir: opts.StoreDir, OutputDir: opts.OutputDir, } if opts.WriteBuildlog { if err := os.MkdirAll(opts.OutputDir, 0755); err != nil { return "", fmt.Errorf("cannot create buildlog base directory: %w", err) } p := filepath.Join(opts.OutputDir, fmt.Sprintf("%s.buildlog", basename)) f, err := os.Create(p) if err != nil { return "", fmt.Errorf("cannot create buildlog: %w", err) } defer f.Close() osbuildOpts.BuildLog = f } if err := progress.RunOSBuild(pbar, osbuildManifest, res.ImgType.Exports(), osbuildOpts); err != nil { return "", err } // Rename *sigh*, see https://github.com/osbuild/images/pull/1039 // for my preferred way. Every frontend to images has to duplicate // similar code like this. pipelineDir := filepath.Join(opts.OutputDir, res.ImgType.Exports()[0]) srcName := filepath.Join(pipelineDir, res.ImgType.Filename()) imgExt := strings.SplitN(res.ImgType.Filename(), ".", 2)[1] dstName := filepath.Join(opts.OutputDir, fmt.Sprintf("%s.%v", basename, imgExt)) if err := os.Rename(srcName, dstName); err != nil { return "", fmt.Errorf("cannot rename artifact to final name: %w", err) } // best effort, remove the now empty pipeline export dir from osbuild _ = os.Remove(pipelineDir) return dstName, nil }