blueprint: add infrastructure for translating to blueprints

Each output type will have its own translator from a blueprint to
a pipeline.

In the future, we may also want to distinguish between different
base distributions and architectures, but for now we keep it
simple and hardcode to a given one.

Some placeholder output formats are added, these have not been
tested or reserached, but are included to show how the it will
all fit together.

Signed-off-by: Tom Gundersen <teg@jklm.no>
This commit is contained in:
Tom Gundersen 2019-10-03 20:24:04 +02:00 committed by Lars Karlitski
parent 949d3464b5
commit b1688cda76
12 changed files with 262 additions and 8 deletions

View file

@ -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"
}

View file

@ -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()
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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)
}

View file

@ -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,
}
}