From 3b774e0e6dce4fc28240e5af0ac0dd44ff7fe8ce Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 3 Feb 2020 00:07:28 +0100 Subject: [PATCH] osbuild: add source type This represents the sources objects, for now only org.osbuild.files is supported. Signed-off-by: Tom Gundersen --- internal/osbuild/files_source.go | 8 +++ internal/osbuild/source.go | 43 ++++++++++++++ internal/osbuild/source_test.go | 97 ++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 internal/osbuild/files_source.go create mode 100644 internal/osbuild/source.go create mode 100644 internal/osbuild/source_test.go diff --git a/internal/osbuild/files_source.go b/internal/osbuild/files_source.go new file mode 100644 index 000000000..b3b946873 --- /dev/null +++ b/internal/osbuild/files_source.go @@ -0,0 +1,8 @@ +package osbuild + +// The FilesSourceOptions specifies a custom script to run in the image +type FilesSource struct { + URLs map[string]string `json:"urls"` +} + +func (FilesSource) isSource() {} diff --git a/internal/osbuild/source.go b/internal/osbuild/source.go new file mode 100644 index 000000000..ca763210a --- /dev/null +++ b/internal/osbuild/source.go @@ -0,0 +1,43 @@ +package osbuild + +import ( + "encoding/json" + "errors" +) + +// A Sources map contains all the sources made available to an osbuild run +type Sources map[string]Source + +// Source specifies the operations of a given source-type. +type Source interface { + isSource() +} + +type rawSources map[string]json.RawMessage + +// UnmarshalJSON unmarshals JSON into a Source object. Each type of source has +// a custom unmarshaller for its options, selected based on the source name. +func (sources *Sources) UnmarshalJSON(data []byte) error { + var rawSources rawSources + err := json.Unmarshal(data, &rawSources) + if err != nil { + return err + } + *sources = make(map[string]Source) + for name, rawSource := range rawSources { + var source Source + switch name { + case "org.osbuild.files": + source = new(FilesSource) + default: + return errors.New("unexpected suorce name" + name) + } + err = json.Unmarshal(rawSource, source) + if err != nil { + return err + } + (*sources)[name] = source + } + + return nil +} diff --git a/internal/osbuild/source_test.go b/internal/osbuild/source_test.go new file mode 100644 index 000000000..f24b434cb --- /dev/null +++ b/internal/osbuild/source_test.go @@ -0,0 +1,97 @@ +package osbuild + +import ( + "bytes" + "encoding/json" + "reflect" + "testing" +) + +func TestSource_UnmarshalJSON(t *testing.T) { + type fields struct { + Name string + Source Source + } + type args struct { + data []byte + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + { + name: "invalid json", + args: args{ + data: []byte(`{"name":"org.osbuild.foo","options":{"bar":null}`), + }, + wantErr: true, + }, + { + name: "unknown source", + args: args{ + data: []byte(`{"name":"org.osbuild.foo","options":{"bar":null}}`), + }, + wantErr: true, + }, + { + name: "missing options", + args: args{ + data: []byte(`{"name":"org.osbuild.files"}`), + }, + wantErr: true, + }, + { + name: "missing name", + args: args{ + data: []byte(`{"foo":null,"options":{"bar":null}}`), + }, + wantErr: true, + }, + { + name: "files-empty", + fields: fields{ + Name: "org.osbuild.files", + Source: &FilesSource{URLs: map[string]string{}}, + }, + args: args{ + data: []byte(`{"org.osbuild.files":{"urls":{}}}`), + }, + }, + { + name: "files", + fields: fields{ + Name: "org.osbuild.files", + Source: &FilesSource{URLs: map[string]string{"checksum1": "url1", "checksum2": "url2"}}, + }, + args: args{ + data: []byte(`{"org.osbuild.files":{"urls":{"checksum1":"url1","checksum2":"url2"}}}`), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + sources := &Sources{ + tt.fields.Name: tt.fields.Source, + } + var gotSources Sources + if err := gotSources.UnmarshalJSON(tt.args.data); (err != nil) != tt.wantErr { + t.Errorf("Sources.UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr) + } + if tt.wantErr { + return + } + gotBytes, err := json.Marshal(sources) + if err != nil { + t.Errorf("Could not marshal source: %v", err) + } + if bytes.Compare(gotBytes, tt.args.data) != 0 { + t.Errorf("Expected '%v', got '%v'", string(tt.args.data), string(gotBytes)) + } + if !reflect.DeepEqual(&gotSources, sources) { + t.Errorf("got '%v', expected '%v'", &gotSources, sources) + } + }) + } +}