diff --git a/internal/osbuild2/files_input.go b/internal/osbuild2/files_input.go index 5dad74b4b..785ca0eeb 100644 --- a/internal/osbuild2/files_input.go +++ b/internal/osbuild2/files_input.go @@ -21,6 +21,9 @@ func NewFilesInputs(references FilesInputReferences) *FilesInputs { // IMPLEMENTED INTERFACES OF STAGES ACCEPTING THIS INPUTS TYPE +// inputs accepted by the XZ stage +func (FilesInputs) isXzStageInputs() {} + // SPECIFIC INPUT STRUCTURE type FilesInput struct { diff --git a/internal/osbuild2/stage.go b/internal/osbuild2/stage.go index 87ab877a5..8b47531f6 100644 --- a/internal/osbuild2/stage.go +++ b/internal/osbuild2/stage.go @@ -132,6 +132,12 @@ func (stage *Stage) UnmarshalJSON(data []byte) error { case "org.osbuild.qemu": options = new(QEMUStageOptions) inputs = new(QEMUStageInputs) + case "org.osbuild.xz": + options = new(XzStageOptions) + // TODO: Unmarshalling inputs should be moved to a separate method and struct should be determined by its Type + // The stage accepts also source input, but we need to rework all inputs first to handle this nicely here. + // Only files input is used by the XZ stage at this moment. + inputs = new(FilesInputs) default: return fmt.Errorf("unexpected stage type: %s", rawStage.Type) } diff --git a/internal/osbuild2/stage_test.go b/internal/osbuild2/stage_test.go index 60f87ba72..63428d5f1 100644 --- a/internal/osbuild2/stage_test.go +++ b/internal/osbuild2/stage_test.go @@ -589,6 +589,19 @@ func TestStageV2_UnmarshalJSON(t *testing.T) { data: []byte(`{"type":"org.osbuild.ostree.preptree","options":{"etc_group_members":["wheel"]}}`), }, }, + { + name: "xz", + fields: fields{ + Type: "org.osbuild.xz", + Options: &XzStageOptions{ + Filename: "image.raw.xz", + }, + Inputs: NewFilesInputs(NewFilesInputReferencesPipeline("os", "image.raw")), + }, + args: args{ + data: []byte(`{"type":"org.osbuild.xz","inputs":{"file":{"type":"org.osbuild.files","origin":"org.osbuild.pipeline","references":{"name:os":{"file":"image.raw"}}}},"options":{"filename":"image.raw.xz"}}`), + }, + }, } for idx, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/osbuild2/xz_stage.go b/internal/osbuild2/xz_stage.go new file mode 100644 index 000000000..bf0fc8b2a --- /dev/null +++ b/internal/osbuild2/xz_stage.go @@ -0,0 +1,32 @@ +package osbuild2 + +type XzStageOptions struct { + // Filename for xz archive + Filename string `json:"filename"` +} + +func (XzStageOptions) isStageOptions() {} + +func NewXzStageOptions(filename string) *XzStageOptions { + return &XzStageOptions{ + Filename: filename, + } +} + +type XzStageInputs interface { + isXzStageInputs() +} + +// Compresses a file into a xz archive. +func NewXzStage(options *XzStageOptions, inputs XzStageInputs) *Stage { + var stageInputs Inputs + if inputs != nil { + stageInputs = inputs.(Inputs) + } + + return &Stage{ + Type: "org.osbuild.xz", + Options: options, + Inputs: stageInputs, + } +} diff --git a/internal/osbuild2/xz_stage_test.go b/internal/osbuild2/xz_stage_test.go new file mode 100644 index 000000000..addb8a0a5 --- /dev/null +++ b/internal/osbuild2/xz_stage_test.go @@ -0,0 +1,47 @@ +package osbuild2 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewXzStageOptions(t *testing.T) { + filename := "image.raw.xz" + + expectedOptions := &XzStageOptions{ + Filename: filename, + } + + actualOptions := NewXzStageOptions(filename) + assert.Equal(t, expectedOptions, actualOptions) +} + +func TestNewXzStage(t *testing.T) { + inputFilename := "image.raw" + filename := "image.raw.xz" + pipeline := "os" + + expectedStage := &Stage{ + Type: "org.osbuild.xz", + Options: NewXzStageOptions(filename), + Inputs: NewFilesInputs(NewFilesInputReferencesPipeline(pipeline, inputFilename)), + } + + actualStage := NewXzStage(NewXzStageOptions(filename), + NewFilesInputs(NewFilesInputReferencesPipeline(pipeline, inputFilename))) + assert.Equal(t, expectedStage, actualStage) +} + +func TestNewXzStageNoInputs(t *testing.T) { + filename := "image.raw.xz" + + expectedStage := &Stage{ + Type: "org.osbuild.xz", + Options: &XzStageOptions{Filename: filename}, + Inputs: nil, + } + + actualStage := NewXzStage(&XzStageOptions{Filename: filename}, nil) + assert.Equal(t, expectedStage, actualStage) +}