diff --git a/cmd/otk-make-grub2-inst-stage/export_test.go b/cmd/otk-make-grub2-inst-stage/export_test.go new file mode 100644 index 000000000..cc2e2795d --- /dev/null +++ b/cmd/otk-make-grub2-inst-stage/export_test.go @@ -0,0 +1,3 @@ +package main + +var Run = run diff --git a/cmd/otk-make-grub2-inst-stage/main.go b/cmd/otk-make-grub2-inst-stage/main.go new file mode 100644 index 000000000..4849030c3 --- /dev/null +++ b/cmd/otk-make-grub2-inst-stage/main.go @@ -0,0 +1,48 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "os" + + "github.com/osbuild/images/pkg/osbuild" + + "github.com/osbuild/images/internal/otkdisk" +) + +type Input struct { + Tree Tree `json:"tree"` +} + +type Tree struct { + Platform string `json:"platform"` + Filesystem otkdisk.Data `json:"filesystem"` +} + +func run(r io.Reader, w io.Writer) error { + var inp Input + if err := json.NewDecoder(r).Decode(&inp); err != nil { + return err + } + + opts := osbuild.NewGrub2InstStageOption(inp.Tree.Filesystem.Const.Filename, inp.Tree.Filesystem.Const.Internal.PartitionTable, inp.Tree.Platform) + stage := osbuild.NewGrub2InstStage(opts) + + out := map[string]interface{}{ + "tree": stage, + } + outputJson, err := json.MarshalIndent(out, "", " ") + if err != nil { + return fmt.Errorf("cannot marshal response: %w", err) + } + fmt.Fprintf(w, "%s\n", outputJson) + return nil +} + +func main() { + if err := run(os.Stdin, os.Stdout); err != nil { + fmt.Fprintf(os.Stderr, "error: %v", err.Error()) + os.Exit(1) + } +} diff --git a/cmd/otk-make-grub2-inst-stage/main_test.go b/cmd/otk-make-grub2-inst-stage/main_test.go new file mode 100644 index 000000000..5a5692396 --- /dev/null +++ b/cmd/otk-make-grub2-inst-stage/main_test.go @@ -0,0 +1,91 @@ +package main_test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + + makeGrub2Inst "github.com/osbuild/images/cmd/otk-make-grub2-inst-stage" + "github.com/osbuild/images/internal/common" + "github.com/osbuild/images/internal/otkdisk" + "github.com/osbuild/images/pkg/disk" +) + +var fakePt = &disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Size: 1 * common.MiB, + Start: 1 * common.MiB, + Bootable: true, + Type: disk.BIOSBootPartitionGUID, + UUID: disk.BIOSBootPartitionUUID, + }, + { + Size: 1 * common.GiB, + Payload: &disk.Filesystem{ + Type: "ext4", + Mountpoint: "/", + UUID: disk.RootPartitionUUID, + }, + }, + }, +} + +// this is not symetrical to the output, this is sad but also +// okay because the input is really just a dump of the internal +// disk.PartitionTable so encoding it in json here will not add +// a benefit for the test +var minimalInputBase = makeGrub2Inst.Input{ + Tree: makeGrub2Inst.Tree{ + Platform: "i386-pc", + Filesystem: otkdisk.Data{ + Const: otkdisk.Const{ + Internal: otkdisk.Internal{ + PartitionTable: fakePt, + }, + }, + }, + }, +} + +var minimalExpectedStages = `{ + "tree": { + "type": "org.osbuild.grub2.inst", + "options": { + "filename": "disk.img", + "platform": "i386-pc", + "location": 2048, + "core": { + "type": "mkimage", + "partlabel": "gpt", + "filesystem": "ext4" + }, + "prefix": { + "type": "partition", + "partlabel": "gpt", + "number": 1, + "path": "/boot/grub2" + } + } + } +} +` + +func TestIntegration(t *testing.T) { + minimalInput := minimalInputBase + minimalInput.Tree.Filesystem.Const.Filename = "disk.img" + expectedStages := minimalExpectedStages + + inpJSON, err := json.Marshal(&minimalInput) + assert.NoError(t, err) + fakeStdin := bytes.NewBuffer(inpJSON) + fakeStdout := bytes.NewBuffer(nil) + + err = makeGrub2Inst.Run(fakeStdin, fakeStdout) + assert.NoError(t, err) + + assert.Equal(t, expectedStages, fakeStdout.String()) +}