diff --git a/internal/blueprint/ami_output.go b/internal/blueprint/ami_output.go new file mode 100644 index 000000000..239d05011 --- /dev/null +++ b/internal/blueprint/ami_output.go @@ -0,0 +1,24 @@ +package blueprint + +import "osbuild-composer/internal/pipeline" + +type amiOutput struct{} + +func (t *amiOutput) translate(b *Blueprint) *pipeline.Pipeline { + p := &pipeline.Pipeline{} + p.SetAssembler( + pipeline.NewQEMUAssembler( + &pipeline.QEMUAssemblerOptions{ + Format: "qcow2", + Filename: t.getName(), + })) + return p +} + +func (t *amiOutput) getName() string { + return "image.ami" +} + +func (t *amiOutput) getMime() string { + return "application/x-qemu-disk" +} diff --git a/internal/blueprint/blueprint.go b/internal/blueprint/blueprint.go index 63af9fcb1..458ced7c3 100644 --- a/internal/blueprint/blueprint.go +++ b/internal/blueprint/blueprint.go @@ -2,7 +2,10 @@ // translating them to OSBuild pipelines package blueprint -import "osbuild-composer/internal/pipeline" +import ( + "osbuild-composer/internal/pipeline" + "sort" +) // A Blueprint is a high-level description of an image. type Blueprint struct { @@ -20,9 +23,43 @@ type Package struct { Version string `json:"version,omitempty"` } -// TranslateToPipeline converts the blueprint to a pipeline for a given output format. -func (b *Blueprint) TranslateToPipeline(outputFormat string) *pipeline.Pipeline { - p := &pipeline.Pipeline{} - p.SetAssembler(pipeline.NewTarAssembler(pipeline.NewTarAssemblerOptions("image.tar"))) - return p +type output interface { + translate(b *Blueprint) *pipeline.Pipeline + getName() string + getMime() string +} + +var outputs = map[string]output{ + "ami": &amiOutput{}, + "ext4-filesystem": &ext4Output{}, + "live-iso": &liveIsoOutput{}, + "partitioned-disk": &diskOutput{}, + "qcow2": &qcow2Output{}, + "openstack": &openstackOutput{}, + "tar": &tarOutput{}, + "vhd": &vhdOutput{}, + "vmdk": &vmdkOutput{}, +} + +// ListOutputFormats returns a sorted list of the supported output formats +func ListOutputFormats() []string { + formats := make([]string, 0, len(outputs)) + for name := range outputs { + formats = append(formats, name) + } + sort.Strings(formats) + + return formats +} + +// ToPipeline converts the blueprint to a pipeline for a given output format. +func (b *Blueprint) ToPipeline(outputFormat string) *pipeline.Pipeline { + return outputs[outputFormat].translate(b) +} + +// FilenameFromType gets the canonical filename and MIME type for a given +// output format +func FilenameFromType(outputFormat string) (string, string) { + translator := outputs[outputFormat] + return translator.getName(), translator.getMime() } diff --git a/internal/blueprint/disk_output.go b/internal/blueprint/disk_output.go new file mode 100644 index 000000000..514a37e2a --- /dev/null +++ b/internal/blueprint/disk_output.go @@ -0,0 +1,24 @@ +package blueprint + +import "osbuild-composer/internal/pipeline" + +type diskOutput struct{} + +func (t *diskOutput) translate(b *Blueprint) *pipeline.Pipeline { + p := &pipeline.Pipeline{} + p.SetAssembler( + pipeline.NewQEMUAssembler( + &pipeline.QEMUAssemblerOptions{ + Format: "raw", + Filename: t.getName(), + })) + return p +} + +func (t *diskOutput) getName() string { + return "image.img" +} + +func (t *diskOutput) getMime() string { + return "application/octet-stream" +} diff --git a/internal/blueprint/ext4_output.go b/internal/blueprint/ext4_output.go new file mode 100644 index 000000000..06ebe0733 --- /dev/null +++ b/internal/blueprint/ext4_output.go @@ -0,0 +1,24 @@ +package blueprint + +import "osbuild-composer/internal/pipeline" + +type ext4Output struct{} + +func (t *ext4Output) translate(b *Blueprint) *pipeline.Pipeline { + p := &pipeline.Pipeline{} + p.SetAssembler( + pipeline.NewQEMUAssembler( + &pipeline.QEMUAssemblerOptions{ + Format: "raw", + Filename: t.getName(), + })) + return p +} + +func (t *ext4Output) getName() string { + return "image.img" +} + +func (t *ext4Output) getMime() string { + return "application/octet-stream" +} diff --git a/internal/blueprint/liveiso_output.go b/internal/blueprint/liveiso_output.go new file mode 100644 index 000000000..c88616773 --- /dev/null +++ b/internal/blueprint/liveiso_output.go @@ -0,0 +1,24 @@ +package blueprint + +import "osbuild-composer/internal/pipeline" + +type liveIsoOutput struct{} + +func (t *liveIsoOutput) translate(b *Blueprint) *pipeline.Pipeline { + p := &pipeline.Pipeline{} + p.SetAssembler( + pipeline.NewQEMUAssembler( + &pipeline.QEMUAssemblerOptions{ + Format: "raw", + Filename: t.getName(), + })) + return p +} + +func (t *liveIsoOutput) getName() string { + return "image.iso" +} + +func (t *liveIsoOutput) getMime() string { + return "application/x-iso9660-image" +} diff --git a/internal/blueprint/openstack_output.go b/internal/blueprint/openstack_output.go new file mode 100644 index 000000000..ce354a70e --- /dev/null +++ b/internal/blueprint/openstack_output.go @@ -0,0 +1,24 @@ +package blueprint + +import "osbuild-composer/internal/pipeline" + +type openstackOutput struct{} + +func (t *openstackOutput) translate(b *Blueprint) *pipeline.Pipeline { + p := &pipeline.Pipeline{} + p.SetAssembler( + pipeline.NewQEMUAssembler( + &pipeline.QEMUAssemblerOptions{ + Format: "qcow2", + Filename: t.getName(), + })) + return p +} + +func (t *openstackOutput) getName() string { + return "image.qcow2" +} + +func (t *openstackOutput) getMime() string { + return "application/x-qemu-disk" +} diff --git a/internal/blueprint/qcow2_output.go b/internal/blueprint/qcow2_output.go new file mode 100644 index 000000000..0571e6e78 --- /dev/null +++ b/internal/blueprint/qcow2_output.go @@ -0,0 +1,24 @@ +package blueprint + +import "osbuild-composer/internal/pipeline" + +type qcow2Output struct{} + +func (t *qcow2Output) translate(b *Blueprint) *pipeline.Pipeline { + p := &pipeline.Pipeline{} + p.SetAssembler( + pipeline.NewQEMUAssembler( + &pipeline.QEMUAssemblerOptions{ + Format: "qcow2", + Filename: t.getName(), + })) + return p +} + +func (t *qcow2Output) getName() string { + return "image.qcow2" +} + +func (t *qcow2Output) getMime() string { + return "application/x-qemu-disk" +} diff --git a/internal/blueprint/tar_output.go b/internal/blueprint/tar_output.go new file mode 100644 index 000000000..4c11a21dc --- /dev/null +++ b/internal/blueprint/tar_output.go @@ -0,0 +1,23 @@ +package blueprint + +import "osbuild-composer/internal/pipeline" + +type tarOutput struct{} + +func (t *tarOutput) translate(b *Blueprint) *pipeline.Pipeline { + p := &pipeline.Pipeline{} + p.SetAssembler( + pipeline.NewTarAssembler( + &pipeline.TarAssemblerOptions{ + Filename: "image.tar", + })) + return p +} + +func (t *tarOutput) getName() string { + return "image.tar" +} + +func (t *tarOutput) getMime() string { + return "application/x-tar" +} diff --git a/internal/blueprint/vhd_output.go b/internal/blueprint/vhd_output.go new file mode 100644 index 000000000..19501a484 --- /dev/null +++ b/internal/blueprint/vhd_output.go @@ -0,0 +1,24 @@ +package blueprint + +import "osbuild-composer/internal/pipeline" + +type vhdOutput struct{} + +func (t *vhdOutput) translate(b *Blueprint) *pipeline.Pipeline { + p := &pipeline.Pipeline{} + p.SetAssembler( + pipeline.NewQEMUAssembler( + &pipeline.QEMUAssemblerOptions{ + Format: "qcow2", + Filename: t.getName(), + })) + return p +} + +func (t *vhdOutput) getName() string { + return "image.vhd" +} + +func (t *vhdOutput) getMime() string { + return "application/x-vhd" +} diff --git a/internal/blueprint/vmdk_output.go b/internal/blueprint/vmdk_output.go new file mode 100644 index 000000000..ae9fd5ec0 --- /dev/null +++ b/internal/blueprint/vmdk_output.go @@ -0,0 +1,24 @@ +package blueprint + +import "osbuild-composer/internal/pipeline" + +type vmdkOutput struct{} + +func (t *vmdkOutput) translate(b *Blueprint) *pipeline.Pipeline { + p := &pipeline.Pipeline{} + p.SetAssembler( + pipeline.NewQEMUAssembler( + &pipeline.QEMUAssemblerOptions{ + Format: "vmdk", + Filename: t.getName(), + })) + return p +} + +func (t *vmdkOutput) getName() string { + return "image.vmdk" +} + +func (t *vmdkOutput) getMime() string { + return "application/x-vmdk" +} diff --git a/internal/weldr/api.go b/internal/weldr/api.go index 368d89850..67f696ad6 100644 --- a/internal/weldr/api.go +++ b/internal/weldr/api.go @@ -649,7 +649,9 @@ func (api *API) composeTypesHandler(writer http.ResponseWriter, request *http.Re Types []composeType `json:"types"` } - reply.Types = append(reply.Types, composeType{"tar", true}) + for _, format := range blueprint.ListOutputFormats() { + reply.Types = append(reply.Types, composeType{format, true}) + } json.NewEncoder(writer).Encode(reply) } diff --git a/internal/weldr/store.go b/internal/weldr/store.go index dd0c7b5ae..c37cdcf7f 100644 --- a/internal/weldr/store.go +++ b/internal/weldr/store.go @@ -217,7 +217,7 @@ func (s *store) addCompose(composeID uuid.UUID, bp *blueprint.Blueprint, compose }) s.pendingJobs <- job.Job{ ComposeID: composeID, - Pipeline: bp.TranslateToPipeline(composeType), + Pipeline: bp.ToPipeline(composeType), Targets: targets, } }