osbuild: add support for the org.osbuild.skopeo source

Add bindings for the `org.osbuild.skopeo` source that can be used
to fetch container images from container registires.
This commit is contained in:
Christian Kellner 2022-07-18 15:00:47 +02:00 committed by Ondřej Budai
parent b4f890a909
commit 513ae6d3d0
2 changed files with 131 additions and 0 deletions

View file

@ -0,0 +1,73 @@
package osbuild
import (
"fmt"
"regexp"
)
var skopeoDigestPattern = regexp.MustCompile(`sha256:[0-9a-f]{64}`)
type SkopeoSource struct {
Items map[string]SkopeoSourceItem `json:"items"`
}
func (SkopeoSource) isSource() {}
type SkopeopSourceImage struct {
Name string `json:"name"`
Digest string `json:"digest"`
TLSVerify *bool `json:"tls-verify,omitempty"`
}
type SkopeoSourceItem struct {
Image SkopeopSourceImage `json:"image"`
}
// NewSkopeoSourceItem creates a new source item for name and digest
func NewSkopeoSourceItem(name, digest string, tlsVerify *bool) SkopeoSourceItem {
item := SkopeoSourceItem{
Image: SkopeopSourceImage{
Name: name,
Digest: digest,
TLSVerify: tlsVerify,
},
}
return item
}
func (item SkopeoSourceItem) validate() error {
if item.Image.Name == "" {
return fmt.Errorf("source item has empty name")
}
if !skopeoDigestPattern.MatchString(item.Image.Digest) {
return fmt.Errorf("source item has invalid digest")
}
return nil
}
// NewSkopeoSource creates a new and empty SkopeoSource
func NewSkopeoSource() *SkopeoSource {
return &SkopeoSource{
Items: make(map[string]SkopeoSourceItem),
}
}
// AddItem adds a source item to the source; will panic
// if any of the supplied options are invalid or missing
func (source *SkopeoSource) AddItem(name, digest, image string, tlsVerify *bool) {
item := NewSkopeoSourceItem(name, digest, tlsVerify)
if err := item.validate(); err != nil {
panic(err)
}
if !skopeoDigestPattern.MatchString(image) {
panic("item has invalid image id")
}
source.Items[image] = item
}

View file

@ -0,0 +1,58 @@
package osbuild
import (
"testing"
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/stretchr/testify/assert"
)
func TestNewSkopeoSource(t *testing.T) {
testDigest := "sha256:f29b6cd42a94a574583439addcd6694e6224f0e4b32044c9e3aee4c4856c2a50"
imageID := "sha256:c2ecf25cf190e76b12b07436ad5140d4ba53d8a136d498705e57a006837a720f"
source := NewSkopeoSource()
source.AddItem("name", testDigest, imageID, common.BoolToPtr(false))
assert.Len(t, source.Items, 1)
item, ok := source.Items[imageID]
assert.True(t, ok)
assert.Equal(t, item.Image.Name, "name")
assert.Equal(t, item.Image.Digest, testDigest)
assert.Equal(t, item.Image.TLSVerify, common.BoolToPtr(false))
testDigest = "sha256:d49eebefb6c7ce5505594bef652bd4adc36f413861bd44209d9b9486310b1264"
imageID = "sha256:d2ab8fea7f08a22f03b30c13c6ea443121f25e87202a7496e93736efa6fe345a"
source.AddItem("name2", testDigest, imageID, nil)
assert.Len(t, source.Items, 2)
item, ok = source.Items[imageID]
assert.True(t, ok)
assert.Nil(t, item.Image.TLSVerify)
// empty name
assert.Panics(t, func() {
source.AddItem("", testDigest, imageID, nil)
})
// empty digest
assert.Panics(t, func() {
source.AddItem("name", "", imageID, nil)
})
// empty image id
assert.Panics(t, func() {
source.AddItem("name", testDigest, "", nil)
})
// invalid digest
assert.Panics(t, func() {
source.AddItem("name", "foo", imageID, nil)
})
// invalid image id
assert.Panics(t, func() {
source.AddItem("name", testDigest, "sha256:foo", nil)
})
}