store/json: simplify ImageType handling
Serialize to a plain string, and do the translation for compatibility from string to string. This removes a lot of code, and if we change the store format, we should just skip the conversion altogether. Signed-off-by: Tom Gundersen <teg@jklm.no>
This commit is contained in:
parent
2c3790f20c
commit
594858ab2c
2 changed files with 88 additions and 105 deletions
|
|
@ -1,9 +1,6 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
|
|
@ -41,7 +38,7 @@ type composesV0 map[uuid.UUID]composeV0
|
|||
// ImageBuild represents a single image build inside a compose
|
||||
type imageBuildV0 struct {
|
||||
ID int `json:"id"`
|
||||
ImageType imageType `json:"image_type"`
|
||||
ImageType string `json:"image_type"`
|
||||
Manifest *osbuild.Manifest `json:"manifest"`
|
||||
Targets []*target.Target `json:"targets"`
|
||||
JobCreated time.Time `json:"job_created"`
|
||||
|
|
@ -102,17 +99,12 @@ func newComposesFromV0(composesStruct composesV0, arch distro.Arch) map[uuid.UUI
|
|||
Blueprint: composeStruct.Blueprint,
|
||||
}
|
||||
for _, imgBuild := range composeStruct.ImageBuilds {
|
||||
imgTypeString, valid := imgBuild.ImageType.toCompatString()
|
||||
if !valid {
|
||||
imgType := imageTypeFromCompatString(imgBuild.ImageType, arch)
|
||||
if imgType == nil {
|
||||
// Invalid type strings in serialization format, this may happen
|
||||
// on upgrades. Ignore the image build.
|
||||
continue
|
||||
}
|
||||
imgType, err := arch.GetImageType(imgTypeString)
|
||||
if err != nil {
|
||||
// Ditto.
|
||||
continue
|
||||
}
|
||||
ib := ImageBuild{
|
||||
ID: imgBuild.ID,
|
||||
ImageType: imgType,
|
||||
|
|
@ -254,9 +246,9 @@ func newComposesV0(composes map[uuid.UUID]Compose) composesV0 {
|
|||
panic("the was a compose with zero image builds, that is forbidden")
|
||||
}
|
||||
for _, imgBuild := range compose.ImageBuilds {
|
||||
imgType, valid := imageTypeFromCompatString(imgBuild.ImageType.Name())
|
||||
if !valid {
|
||||
panic("invalid image type")
|
||||
imgType := imageTypeToCompatString(imgBuild.ImageType)
|
||||
if imgType == "" {
|
||||
panic("invalid image type: " + imgBuild.ImageType.Name())
|
||||
}
|
||||
ib := imageBuildV0{
|
||||
ID: imgBuild.ID,
|
||||
|
|
@ -321,90 +313,32 @@ func (store *Store) toStoreV0() *storeV0 {
|
|||
}
|
||||
}
|
||||
|
||||
type imageType int
|
||||
|
||||
// NOTE: If you want to add more constants here, don't forget to add a mapping below
|
||||
const (
|
||||
Azure imageType = iota
|
||||
Aws
|
||||
LiveISO
|
||||
OpenStack
|
||||
Qcow2Generic
|
||||
Vmware
|
||||
RawFilesystem
|
||||
PartitionedDisk
|
||||
TarArchive
|
||||
)
|
||||
|
||||
// getArchMapping is a helper function that defines the conversion from JSON string value
|
||||
// to ImageType.
|
||||
func getImageTypeMapping() map[string]int {
|
||||
mapping := map[string]int{
|
||||
"Azure": int(Azure),
|
||||
"AWS": int(Aws),
|
||||
"LiveISO": int(LiveISO),
|
||||
"OpenStack": int(OpenStack),
|
||||
"qcow2": int(Qcow2Generic),
|
||||
"VMWare": int(Vmware),
|
||||
"Raw-filesystem": int(RawFilesystem),
|
||||
"Partitioned-disk": int(PartitionedDisk),
|
||||
"Tar": int(TarArchive),
|
||||
}
|
||||
return mapping
|
||||
var imageTypeCompatMapping = map[string]string{
|
||||
"vhd": "Azure",
|
||||
"ami": "AWS",
|
||||
"liveiso": "LiveISO",
|
||||
"openstack": "OpenStack",
|
||||
"qcow2": "qcow2",
|
||||
"vmdk": "VMWare",
|
||||
"ext4-filesystem": "Raw-filesystem",
|
||||
"partitioned-disk": "Partitioned-disk",
|
||||
"tar": "Tar",
|
||||
"test_type": "test_type",
|
||||
}
|
||||
|
||||
// TODO: check the mapping here:
|
||||
func getCompatImageTypeMapping() map[int]string {
|
||||
mapping := map[int]string{
|
||||
int(Azure): "vhd",
|
||||
int(Aws): "ami",
|
||||
int(LiveISO): "liveiso",
|
||||
int(OpenStack): "openstack",
|
||||
int(Qcow2Generic): "qcow2",
|
||||
int(Vmware): "vmdk",
|
||||
int(RawFilesystem): "ext4-filesystem",
|
||||
int(PartitionedDisk): "partitioned-disk",
|
||||
int(TarArchive): "tar",
|
||||
}
|
||||
return mapping
|
||||
func imageTypeToCompatString(imgType distro.ImageType) string {
|
||||
return imageTypeCompatMapping[imgType.Name()]
|
||||
}
|
||||
|
||||
func (imgType imageType) toCompatString() (string, bool) {
|
||||
str, exists := getCompatImageTypeMapping()[int(imgType)]
|
||||
return str, exists
|
||||
}
|
||||
|
||||
func imageTypeFromCompatString(input string) (imageType, bool) {
|
||||
for k, v := range getCompatImageTypeMapping() {
|
||||
func imageTypeFromCompatString(input string, arch distro.Arch) distro.ImageType {
|
||||
for k, v := range imageTypeCompatMapping {
|
||||
if v == input {
|
||||
return imageType(k), true
|
||||
imgType, err := arch.GetImageType(k)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return imgType
|
||||
}
|
||||
}
|
||||
return imageType(999), false
|
||||
}
|
||||
|
||||
func (imgType *imageType) UnmarshalJSON(data []byte) error {
|
||||
mapping := getImageTypeMapping()
|
||||
var stringInput string
|
||||
err := json.Unmarshal(data, &stringInput)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
value, exists := mapping[stringInput]
|
||||
if !exists {
|
||||
return errors.New(stringInput + " is not a valid image type")
|
||||
}
|
||||
*imgType = imageType(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (imgType imageType) MarshalJSON() ([]byte, error) {
|
||||
mapping := getImageTypeMapping()
|
||||
input := int(imgType)
|
||||
for k, v := range mapping {
|
||||
if v == input {
|
||||
return json.Marshal(k)
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("%d is not a valid image type tag", input)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,72 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/distro"
|
||||
"github.com/osbuild/osbuild-composer/internal/distro/test_distro"
|
||||
)
|
||||
|
||||
func TestImageType_UnmarshalJSON(t *testing.T) {
|
||||
dict := struct {
|
||||
ImageTypes []imageType `json:"image_types"`
|
||||
}{}
|
||||
input := `{"image_types":["qcow2", "Azure"]}`
|
||||
err := json.Unmarshal([]byte(input), &dict)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
func Test_imageTypeToCompatString(t *testing.T) {
|
||||
type args struct {
|
||||
input distro.ImageType
|
||||
}
|
||||
if dict.ImageTypes[0] != Qcow2Generic {
|
||||
t.Fatal("failed to umarshal image type qcow2; got tag:", dict.ImageTypes[0])
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "valid",
|
||||
args: args{
|
||||
input: &test_distro.TestImageType{},
|
||||
},
|
||||
want: "test_type",
|
||||
},
|
||||
}
|
||||
if dict.ImageTypes[1] != Azure {
|
||||
t.Fatal("failed to umarshal image type Azure; got tag:", dict.ImageTypes[0])
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := imageTypeToCompatString(tt.args.input)
|
||||
if got != tt.want {
|
||||
t.Errorf("imageTypeStringToCompatString() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_imageTypeFromCompatString(t *testing.T) {
|
||||
type args struct {
|
||||
input string
|
||||
arch distro.Arch
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want distro.ImageType
|
||||
}{
|
||||
{
|
||||
name: "valid",
|
||||
args: args{
|
||||
input: "test_type",
|
||||
arch: &test_distro.TestArch{},
|
||||
},
|
||||
want: &test_distro.TestImageType{},
|
||||
},
|
||||
{
|
||||
name: "invalid",
|
||||
args: args{
|
||||
input: "foo",
|
||||
arch: &test_distro.TestArch{},
|
||||
},
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := imageTypeFromCompatString(tt.args.input, tt.args.arch)
|
||||
if got != tt.want {
|
||||
t.Errorf("imageTypeStringFromCompatString() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue