filters: add new getOneImage() helper for manifest/build
This commit adds a helper to find exactly a single image from a given disto/type/arch description. This will be used in `manifest`, `build` and potentially more. It is meant to support copy/paste from the `image-builder list-images` output, so: "distro:centos-9" is support just like "centos-9" (same for distro/imgType/arch).
This commit is contained in:
parent
7f9936acc9
commit
e9e8dc5256
3 changed files with 106 additions and 0 deletions
|
|
@ -8,6 +8,10 @@ import (
|
|||
"github.com/osbuild/images/pkg/reporegistry"
|
||||
)
|
||||
|
||||
var (
|
||||
GetOneImage = getOneImage
|
||||
)
|
||||
|
||||
func MockOsArgs(new []string) (restore func()) {
|
||||
saved := os.Args
|
||||
os.Args = append([]string{"argv0"}, new...)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
|
||||
"github.com/osbuild/images/pkg/distrofactory"
|
||||
"github.com/osbuild/images/pkg/imagefilter"
|
||||
)
|
||||
|
|
@ -13,3 +18,45 @@ func newImageFilterDefault(dataDir string) (*imagefilter.ImageFilter, error) {
|
|||
}
|
||||
return imagefilter.New(fac, repos)
|
||||
}
|
||||
|
||||
// should this be moved to images:imagefilter?
|
||||
func getOneImage(dataDir, distroName, imgTypeStr, archStr string) (*imagefilter.Result, error) {
|
||||
imageFilter, err := newImageFilterDefault(dataDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// strip prefixes to make ib copy/paste friendly when pasting output
|
||||
// from "list-images"
|
||||
distroName = strings.TrimPrefix(distroName, "distro:")
|
||||
imgTypeStr = strings.TrimPrefix(imgTypeStr, "type:")
|
||||
archStr = strings.TrimPrefix(archStr, "arch:")
|
||||
|
||||
// error early when globs are used
|
||||
for _, s := range []string{distroName, imgTypeStr, archStr} {
|
||||
if glob.QuoteMeta(s) != s {
|
||||
return nil, fmt.Errorf("cannot use globs in %q when getting a single image", s)
|
||||
}
|
||||
}
|
||||
|
||||
filterExprs := []string{
|
||||
fmt.Sprintf("distro:%s", distroName),
|
||||
fmt.Sprintf("arch:%s", archStr),
|
||||
fmt.Sprintf("type:%s", imgTypeStr),
|
||||
}
|
||||
filteredResults, err := imageFilter.Filter(filterExprs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(filteredResults) {
|
||||
case 0:
|
||||
return nil, fmt.Errorf("cannot find image for: distro:%q type:%q arch:%q", distroName, imgTypeStr, archStr)
|
||||
case 1:
|
||||
return &filteredResults[0], nil
|
||||
default:
|
||||
// This condition should never be hit in practise as we
|
||||
// disallow globs above.
|
||||
// XXX: imagefilter.Result should have a String() method so
|
||||
// that this output can actually show the results
|
||||
return nil, fmt.Errorf("internal error: found %v results for %q %q %q", len(filteredResults), distroName, imgTypeStr, archStr)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
55
cmd/image-builder/filters_test.go
Normal file
55
cmd/image-builder/filters_test.go
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package main_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
testrepos "github.com/osbuild/images/test/data/repositories"
|
||||
|
||||
"github.com/osbuild/image-builder-cli/cmd/image-builder"
|
||||
)
|
||||
|
||||
func TestGetOneImageHappy(t *testing.T) {
|
||||
restore := main.MockNewRepoRegistry(testrepos.New)
|
||||
defer restore()
|
||||
|
||||
dataDir := ""
|
||||
for _, tc := range []struct {
|
||||
distro, imgType, arch string
|
||||
}{
|
||||
{"centos-9", "qcow2", "x86_64"},
|
||||
{"distro:centos-9", "qcow2", "x86_64"},
|
||||
{"distro:centos-9", "type:qcow2", "x86_64"},
|
||||
{"distro:centos-9", "type:qcow2", "arch:x86_64"},
|
||||
} {
|
||||
res, err := main.GetOneImage(dataDir, tc.distro, tc.imgType, tc.arch)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "centos-9", res.Distro.Name())
|
||||
assert.Equal(t, "qcow2", res.ImgType.Name())
|
||||
assert.Equal(t, "x86_64", res.Arch.Name())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOneImageError(t *testing.T) {
|
||||
restore := main.MockNewRepoRegistry(testrepos.New)
|
||||
defer restore()
|
||||
|
||||
dataDir := ""
|
||||
for _, tc := range []struct {
|
||||
distro, imgType, arch string
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
"unknown", "qcow2", "x86_64",
|
||||
`cannot find image for: distro:"unknown" type:"qcow2" arch:"x86_64"`,
|
||||
},
|
||||
{
|
||||
"centos*", "qcow2", "x86_64",
|
||||
`cannot use globs in "centos*" when getting a single image`,
|
||||
},
|
||||
} {
|
||||
_, err := main.GetOneImage(dataDir, tc.distro, tc.imgType, tc.arch)
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue