-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd: implement
manifest
command with basic rpm resolving
This commit implements the `manifest` command for `image-builder`. It will generate an osbuild manifest based on the given inputs, e.g.: ``` $ ./image-builder manifest centos-9 qcow2 {"version":"2","pipelines":[{"name":"build","runner":",... ``` Note that there is an integration test but because of the depsolve it will be slow. It will be skipped when doing `go test -short`.
- Loading branch information
Showing
9 changed files
with
252 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"strings" | ||
|
||
"github.com/osbuild/images/pkg/blueprint" | ||
"github.com/osbuild/images/pkg/distro" | ||
"github.com/osbuild/images/pkg/dnfjson" | ||
"github.com/osbuild/images/pkg/rpmmd" | ||
"github.com/osbuild/images/pkg/sbom" | ||
) | ||
|
||
// XXX: duplicated from cmd/build/main.go:depsolve (and probably more places) | ||
// should go into a common helper in "images" or images should do this on | ||
// its own | ||
var depsolve = func(cacheDir string, packageSets map[string][]rpmmd.PackageSet, d distro.Distro, arch string) (map[string][]rpmmd.PackageSpec, map[string][]rpmmd.RepoConfig, error) { | ||
solver := dnfjson.NewSolver(d.ModulePlatformID(), d.Releasever(), arch, d.Name(), cacheDir) | ||
depsolvedSets := make(map[string][]rpmmd.PackageSpec) | ||
repoSets := make(map[string][]rpmmd.RepoConfig) | ||
for name, pkgSet := range packageSets { | ||
res, err := solver.Depsolve(pkgSet, sbom.StandardTypeNone) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
depsolvedSets[name] = res.Packages | ||
repoSets[name] = res.Repos | ||
} | ||
return depsolvedSets, repoSets, nil | ||
} | ||
|
||
type manifestGenerator struct { | ||
DataDir string | ||
Out io.Writer | ||
} | ||
|
||
func (mg *manifestGenerator) Generate(distroStr, imgTypeStr, archStr string) error { | ||
// Note that distroStr/imgTypeStr/archStr may contain prefixes like | ||
// "distro:" so only the getOneImage() result should be used in the | ||
// rest of the function. | ||
res, err := getOneImage(mg.DataDir, distroStr, imgTypeStr, archStr) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var bp blueprint.Blueprint | ||
var options distro.ImageOptions | ||
reporeg, err := newRepoRegistry(mg.DataDir) | ||
if err != nil { | ||
return err | ||
} | ||
repos, err := reporeg.ReposByImageTypeName(res.Distro.Name(), res.Arch.Name(), res.ImgType.Name()) | ||
if err != nil { | ||
return err | ||
} | ||
preManifest, warnings, err := res.ImgType.Manifest(&bp, options, repos, 0) | ||
if err != nil { | ||
return err | ||
} | ||
if len(warnings) > 0 { | ||
// XXX: what can we do here? for things like json output? | ||
// what are these warnings? | ||
return fmt.Errorf("warnings during manifest creation: %v", strings.Join(warnings, "\n")) | ||
} | ||
// XXX: add something like "--rpmmd" (like bib) | ||
cacheDir := "" | ||
packageSpecs, _, err := depsolve(cacheDir, preManifest.GetPackageSetChains(), res.Distro, res.Arch.Name()) | ||
if err != nil { | ||
return err | ||
} | ||
if packageSpecs == nil { | ||
return fmt.Errorf("depsolve did not return any packages") | ||
} | ||
// XXX: support commit/container specs | ||
mf, err := preManifest.Serialize(packageSpecs, nil, nil, nil) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Fprintf(mg.Out, "%s\n", mf) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package main_test | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/osbuild/images/pkg/distrofactory" | ||
testrepos "github.com/osbuild/images/test/data/repositories" | ||
|
||
"github.com/osbuild/image-builder-cli/cmd/image-builder" | ||
) | ||
|
||
func TestManifestGeneratorSad(t *testing.T) { | ||
restore := main.MockNewRepoRegistry(testrepos.New) | ||
defer restore() | ||
|
||
mg := &main.ManifestGenerator{} | ||
assert.NotNil(t, mg) | ||
err := mg.Generate("bad-distro", "bad-type", "bad-arch") | ||
assert.EqualError(t, err, `cannot find image for: distro:"bad-distro" type:"bad-type" arch:"bad-arch"`) | ||
} | ||
|
||
// XXX: move to images:testutil.go or something | ||
func pipelineNamesFrom(t *testing.T, osbuildManifest []byte) []string { | ||
var manifest map[string]interface{} | ||
|
||
err := json.Unmarshal(osbuildManifest, &manifest) | ||
assert.NoError(t, err) | ||
assert.NotNil(t, manifest["pipelines"]) | ||
pipelines := manifest["pipelines"].([]interface{}) | ||
pipelineNames := make([]string, len(pipelines)) | ||
for idx, pi := range pipelines { | ||
pipelineNames[idx] = pi.(map[string]interface{})["name"].(string) | ||
} | ||
return pipelineNames | ||
} | ||
|
||
func TestManifestGenerator(t *testing.T) { | ||
var osbuildManifest bytes.Buffer | ||
|
||
restore := main.MockDistrofactoryNew(distrofactory.NewTestDefault) | ||
defer restore() | ||
restore = main.MockDepsolve() | ||
defer restore() | ||
|
||
mg := &main.ManifestGenerator{DataDir: "../../test/data/", Out: &osbuildManifest} | ||
assert.NotNil(t, mg) | ||
err := mg.Generate("test-distro-1", "test_type", "test_arch") | ||
assert.NoError(t, err) | ||
|
||
pipelineNames := pipelineNamesFrom(t, osbuildManifest.Bytes()) | ||
assert.Equal(t, []string{"build", "os"}, pipelineNames) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"test_arch": [ | ||
{ | ||
} | ||
] | ||
} |