composer: add provisional multi-arch support
The pipeline generation now takes the architecture as an argument. Currently only x86_64 is supported. The architecture is detected at start-up, and passed down to each pipeline translation. For osbuild-pipeline we now requrie the architecture to be passed in. Signed-off-by: Tom Gundersen <teg@jklm.no>
This commit is contained in:
parent
dcc9cdedee
commit
d33fc5f010
11 changed files with 48 additions and 20 deletions
|
|
@ -4,6 +4,7 @@ import (
|
|||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/distro"
|
||||
"github.com/osbuild/osbuild-composer/internal/jobqueue"
|
||||
|
|
@ -14,6 +15,20 @@ import (
|
|||
"github.com/coreos/go-systemd/activation"
|
||||
)
|
||||
|
||||
func currentArch() string {
|
||||
if runtime.GOARCH == "amd64" {
|
||||
return "x86_64"
|
||||
} else if runtime.GOARCH == "arm64" {
|
||||
return "aarch64"
|
||||
} else if runtime.GOARCH == "ppc64le" {
|
||||
return "ppc64le"
|
||||
} else if runtime.GOARCH == "s390x" {
|
||||
return "s390x"
|
||||
} else {
|
||||
panic("unsupported architecture")
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var verbose bool
|
||||
flag.BoolVar(&verbose, "v", false, "Print access log")
|
||||
|
|
@ -48,7 +63,7 @@ func main() {
|
|||
store := store.New(&stateDir, distribution)
|
||||
|
||||
jobAPI := jobqueue.New(logger, store)
|
||||
weldrAPI := weldr.New(rpm, distribution, logger, store)
|
||||
weldrAPI := weldr.New(rpm, currentArch(), distribution, logger, store)
|
||||
|
||||
go jobAPI.Serve(jobListener)
|
||||
weldrAPI.Serve(weldrListener)
|
||||
|
|
|
|||
|
|
@ -14,9 +14,11 @@ import (
|
|||
func main() {
|
||||
var format string
|
||||
var blueprintArg string
|
||||
var archArg string
|
||||
var distroArg string
|
||||
flag.StringVar(&format, "output-format", "qcow2", "output format")
|
||||
flag.StringVar(&format, "output-format", "", "output format")
|
||||
flag.StringVar(&blueprintArg, "blueprint", "", "blueprint to translate")
|
||||
flag.StringVar(&archArg, "arch", "", "architecture to create image for")
|
||||
flag.StringVar(&distroArg, "distro", "", "distribution to create")
|
||||
flag.Parse()
|
||||
|
||||
|
|
@ -55,7 +57,7 @@ func main() {
|
|||
panic(err.Error())
|
||||
}
|
||||
|
||||
pipeline, err := d.Pipeline(blueprint, checksums, format)
|
||||
pipeline, err := d.Pipeline(blueprint, checksums, archArg, format)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ type Distro interface {
|
|||
// Returns an osbuild pipeline that generates an image in the given
|
||||
// output format with all packages and customizations specified in the
|
||||
// given blueprint.
|
||||
Pipeline(b *blueprint.Blueprint, checksums map[string]string, outputFormat string) (*pipeline.Pipeline, error)
|
||||
Pipeline(b *blueprint.Blueprint, checksums map[string]string, outputArchitecture, outputFormat string) (*pipeline.Pipeline, error)
|
||||
|
||||
// Returns a osbuild runner that can be used on this distro.
|
||||
Runner() string
|
||||
|
|
@ -41,7 +41,7 @@ var registered map[string]Distro
|
|||
func init() {
|
||||
registered = map[string]Distro{
|
||||
"fedora-30": fedora30.New(),
|
||||
"rhel-8.2": rhel82.New(),
|
||||
"rhel-8.2": rhel82.New(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,10 +100,10 @@ func readOSRelease(r io.Reader) (map[string]string, error) {
|
|||
key := strings.TrimSpace(parts[0])
|
||||
value := strings.TrimSpace(parts[1])
|
||||
if value[0] == '"' {
|
||||
if len(value) < 2 || value[len(value) - 1] != '"' {
|
||||
if len(value) < 2 || value[len(value)-1] != '"' {
|
||||
return nil, errors.New("readOSRelease: invalid input")
|
||||
}
|
||||
value = value[1:len(value) - 1]
|
||||
value = value[1 : len(value)-1]
|
||||
}
|
||||
|
||||
osrelease[key] = value
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ func TestDistro_Pipeline(t *testing.T) {
|
|||
for _, fileInfo := range fileInfos {
|
||||
type compose struct {
|
||||
Distro string `json:"distro"`
|
||||
Arch string `json:"arch"`
|
||||
OutputFormat string `json:"output-format"`
|
||||
Checksums map[string]string `json:"checksums"`
|
||||
Blueprint *blueprint.Blueprint `json:"blueprint"`
|
||||
|
|
@ -46,7 +47,7 @@ func TestDistro_Pipeline(t *testing.T) {
|
|||
t.Errorf("unknown distro: %v", tt.Compose.Distro)
|
||||
return
|
||||
}
|
||||
got, err := d.Pipeline(tt.Compose.Blueprint, tt.Compose.Checksums, tt.Compose.OutputFormat)
|
||||
got, err := d.Pipeline(tt.Compose.Blueprint, tt.Compose.Checksums, tt.Compose.Arch, tt.Compose.OutputFormat)
|
||||
if (err != nil) != (tt.Pipeline == nil) {
|
||||
t.Errorf("distro.Pipeline() error = %v", err)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -270,12 +270,16 @@ func (r *Fedora30) FilenameFromType(outputFormat string) (string, string, error)
|
|||
return "", "", errors.New("invalid output format: " + outputFormat)
|
||||
}
|
||||
|
||||
func (r *Fedora30) Pipeline(b *blueprint.Blueprint, checksums map[string]string, outputFormat string) (*pipeline.Pipeline, error) {
|
||||
func (r *Fedora30) Pipeline(b *blueprint.Blueprint, checksums map[string]string, outputArchitecture, outputFormat string) (*pipeline.Pipeline, error) {
|
||||
output, exists := r.outputs[outputFormat]
|
||||
if !exists {
|
||||
return nil, errors.New("invalid output format: " + outputFormat)
|
||||
}
|
||||
|
||||
if outputArchitecture != "x86_64" {
|
||||
return nil, errors.New("invalid output architecture: " + outputArchitecture)
|
||||
}
|
||||
|
||||
p := &pipeline.Pipeline{}
|
||||
p.SetBuild(r.buildPipeline(checksums), "org.osbuild.fedora30")
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ func New() *RHEL82 {
|
|||
DefaultTarget: "multi-user.target",
|
||||
IncludeFSTab: true,
|
||||
KernelOptions: "ro console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto",
|
||||
Assembler: r.qemuAssembler("raw.xz", "image.raw.xz", 6 * GigaByte),
|
||||
Assembler: r.qemuAssembler("raw.xz", "image.raw.xz", 6*GigaByte),
|
||||
}
|
||||
|
||||
r.outputs["ext4-filesystem"] = output{
|
||||
|
|
@ -294,12 +294,16 @@ func (r *RHEL82) FilenameFromType(outputFormat string) (string, string, error) {
|
|||
return "", "", errors.New("invalid output format: " + outputFormat)
|
||||
}
|
||||
|
||||
func (r *RHEL82) Pipeline(b *blueprint.Blueprint, checksums map[string]string, outputFormat string) (*pipeline.Pipeline, error) {
|
||||
func (r *RHEL82) Pipeline(b *blueprint.Blueprint, checksums map[string]string, outputArchitecture, outputFormat string) (*pipeline.Pipeline, error) {
|
||||
output, exists := r.outputs[outputFormat]
|
||||
if !exists {
|
||||
return nil, errors.New("invalid output format: " + outputFormat)
|
||||
}
|
||||
|
||||
if outputArchitecture != "x86_64" {
|
||||
return nil, errors.New("invalid output architecture: " + outputArchitecture)
|
||||
}
|
||||
|
||||
p := &pipeline.Pipeline{}
|
||||
p.SetBuild(r.buildPipeline(checksums), "org.osbuild.rhel82")
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ func (d *TestDistro) FilenameFromType(outputFormat string) (string, string, erro
|
|||
return "", "", errors.New("invalid output format: " + outputFormat)
|
||||
}
|
||||
|
||||
func (d *TestDistro) Pipeline(b *blueprint.Blueprint, checksums map[string]string, outputFormat string) (*pipeline.Pipeline, error) {
|
||||
return nil, errors.New("invalid output format: " + outputFormat)
|
||||
func (d *TestDistro) Pipeline(b *blueprint.Blueprint, checksums map[string]string, outputArch, outputFormat string) (*pipeline.Pipeline, error) {
|
||||
return nil, errors.New("invalid output format or arch: " + outputFormat + " @ " + outputArch)
|
||||
}
|
||||
|
||||
func (d *TestDistro) Runner() string {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ func TestCreate(t *testing.T) {
|
|||
store := store.New(nil, distro.New("fedora-30"))
|
||||
api := jobqueue.New(nil, store)
|
||||
|
||||
err := store.PushCompose(id, &blueprint.Blueprint{}, map[string]string{"fedora": "test:foo"}, "tar", nil)
|
||||
err := store.PushCompose(id, &blueprint.Blueprint{}, map[string]string{"fedora": "test:foo"}, "x86_64", "tar", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("error pushing compose: %v", err)
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ func testUpdateTransition(t *testing.T, from, to string, expectedStatus int) {
|
|||
api := jobqueue.New(nil, store)
|
||||
|
||||
if from != "VOID" {
|
||||
err := store.PushCompose(id, &blueprint.Blueprint{}, map[string]string{"fedora": "test:foo"}, "tar", nil)
|
||||
err := store.PushCompose(id, &blueprint.Blueprint{}, map[string]string{"fedora": "test:foo"}, "x86_64", "tar", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("error pushing compose: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -415,7 +415,7 @@ func (s *Store) DeleteBlueprintFromWorkspace(name string) {
|
|||
})
|
||||
}
|
||||
|
||||
func (s *Store) PushCompose(composeID uuid.UUID, bp *blueprint.Blueprint, checksums map[string]string, composeType string, uploadTarget *target.Target) error {
|
||||
func (s *Store) PushCompose(composeID uuid.UUID, bp *blueprint.Blueprint, checksums map[string]string, arch, composeType string, uploadTarget *target.Target) error {
|
||||
targets := []*target.Target{}
|
||||
|
||||
if s.stateDir != nil {
|
||||
|
|
@ -430,7 +430,7 @@ func (s *Store) PushCompose(composeID uuid.UUID, bp *blueprint.Blueprint, checks
|
|||
targets = append(targets, uploadTarget)
|
||||
}
|
||||
|
||||
pipeline, err := s.distro.Pipeline(bp, checksums, composeType)
|
||||
pipeline, err := s.distro.Pipeline(bp, checksums, arch, composeType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,18 +31,20 @@ type API struct {
|
|||
store *store.Store
|
||||
|
||||
rpmmd rpmmd.RPMMD
|
||||
arch string
|
||||
distro distro.Distro
|
||||
|
||||
logger *log.Logger
|
||||
router *httprouter.Router
|
||||
}
|
||||
|
||||
func New(rpmmd rpmmd.RPMMD, distro distro.Distro, logger *log.Logger, store *store.Store) *API {
|
||||
func New(rpmmd rpmmd.RPMMD, arch string, distro distro.Distro, logger *log.Logger, store *store.Store) *API {
|
||||
// This needs to be shared with the worker API so that they can communicate with each other
|
||||
// builds := make(chan queue.Build, 200)
|
||||
api := &API{
|
||||
store: store,
|
||||
rpmmd: rpmmd,
|
||||
arch: arch,
|
||||
distro: distro,
|
||||
logger: logger,
|
||||
}
|
||||
|
|
@ -1221,7 +1223,7 @@ func (api *API) composeHandler(writer http.ResponseWriter, request *http.Request
|
|||
return
|
||||
}
|
||||
|
||||
err = api.store.PushCompose(reply.BuildID, bp, checksums, cr.ComposeType, uploadTarget)
|
||||
err = api.store.PushCompose(reply.BuildID, bp, checksums, api.arch, cr.ComposeType, uploadTarget)
|
||||
|
||||
// TODO: we should probably do some kind of blueprint validation in future
|
||||
// for now, let's just 500 and bail out
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ func createWeldrAPI(fixtureGenerator rpmmd_mock.FixtureGenerator) (*weldr.API, *
|
|||
rpm := rpmmd_mock.NewRPMMDMock(fixture)
|
||||
d := distro.New("test")
|
||||
|
||||
return weldr.New(rpm, d, nil, fixture.Store), fixture.Store
|
||||
return weldr.New(rpm, "x86_64", d, nil, fixture.Store), fixture.Store
|
||||
}
|
||||
|
||||
func TestBasic(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue