distro: register distros explicitly

Automatically registering on `init()` is clever, but a bit too magical
and easy to get wrong, because every binary must include all distros
somewhere.

Flip this inside out: distros now have a `New()`, which returns
something that implements the `Distro` interface. The distro package
explicitly creates all of them.

This means that distros cannot import distro itself anymore, because go
forbids import cycles. This only affected `InvalidOutputFormatError`.
Return a generic error for now.
This commit is contained in:
Lars Karlitski 2019-11-28 16:06:41 +01:00
parent 673d3ff14b
commit 14ebed46da
10 changed files with 26 additions and 35 deletions

View file

@ -7,10 +7,7 @@ import (
"os"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/distro"
_ "github.com/osbuild/osbuild-composer/internal/distro/fedora30"
_ "github.com/osbuild/osbuild-composer/internal/distro/rhel82"
)
func main() {

View file

@ -11,6 +11,9 @@ import (
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/pipeline"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/distro/fedora30"
"github.com/osbuild/osbuild-composer/internal/distro/rhel82"
)
type Distro interface {
@ -22,28 +25,24 @@ type Distro interface {
ListOutputFormats() []string
// Returns the canonical filename and MIME type for a given output
// format
// format. `outputFormat` must be one returned by
FilenameFromType(outputFormat string) (string, string, error)
// Returns an osbuild pipeline that generates an image in the given
// output format with all packages and customizations specified in the
// given blueprint. `outputFormat` must be one returned by
// ListOutputFormats().
// given blueprint.
Pipeline(b *blueprint.Blueprint, outputFormat string) (*pipeline.Pipeline, error)
}
// An InvalidOutputFormatError is returned when a requested output format is
// not supported. The requested format is included as the error message.
type InvalidOutputFormatError struct {
Format string
}
var registered map[string]Distro
func (e *InvalidOutputFormatError) Error() string {
return e.Format
func init() {
registered = map[string]Distro{
"fedora-30": fedora30.New(),
"rhel-8.2": rhel82.New(),
}
}
var registered = map[string]Distro{}
func New(name string) Distro {
if name == "" {
distro, err := FromHost()

View file

@ -9,8 +9,6 @@ import (
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/pipeline"
_ "github.com/osbuild/osbuild-composer/internal/distro/fedora30"
)
func TestDistro_Pipeline(t *testing.T) {

View file

@ -1,6 +1,7 @@
package fedora30
import (
"errors"
"sort"
"strconv"
@ -8,7 +9,6 @@ import (
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/crypt"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/pipeline"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
)
@ -29,7 +29,7 @@ type output struct {
Assembler *pipeline.Assembler
}
func init() {
func New() *Fedora30 {
r := Fedora30{
outputs: map[string]output{},
}
@ -212,7 +212,7 @@ func init() {
Assembler: r.qemuAssembler("vmdk", "disk.vmdk"),
}
distro.Register("fedora-30", &r)
return &r
}
func (r *Fedora30) Repositories() []rpmmd.RepoConfig {
@ -268,13 +268,13 @@ func (r *Fedora30) FilenameFromType(outputFormat string) (string, string, error)
if output, exists := r.outputs[outputFormat]; exists {
return output.Name, output.MimeType, nil
}
return "", "", &distro.InvalidOutputFormatError{outputFormat}
return "", "", errors.New("invalid output format: " + outputFormat)
}
func (r *Fedora30) Pipeline(b *blueprint.Blueprint, outputFormat string) (*pipeline.Pipeline, error) {
output, exists := r.outputs[outputFormat]
if !exists {
return nil, &distro.InvalidOutputFormatError{outputFormat}
return nil, errors.New("invalid output format: " + outputFormat)
}
p := &pipeline.Pipeline{}

View file

@ -5,7 +5,6 @@ import (
"testing"
"github.com/osbuild/osbuild-composer/internal/distro"
_ "github.com/osbuild/osbuild-composer/internal/distro/fedora30"
)
func TestListOutputFormats(t *testing.T) {

View file

@ -1,6 +1,7 @@
package rhel82
import (
"errors"
"sort"
"strconv"
@ -8,7 +9,6 @@ import (
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/crypt"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/pipeline"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
)
@ -28,7 +28,7 @@ type output struct {
Assembler *pipeline.Assembler
}
func init() {
func New() *RHEL82 {
const GigaByte = 1024 * 1024 * 1024
r := RHEL82{
@ -260,7 +260,7 @@ func init() {
Assembler: r.qemuAssembler("vmdk", "disk.vmdk", 3*GigaByte),
}
distro.Register("rhel-8.2", &r)
return &r
}
func (r *RHEL82) Repositories() []rpmmd.RepoConfig {
@ -293,13 +293,13 @@ func (r *RHEL82) FilenameFromType(outputFormat string) (string, string, error) {
if output, exists := r.outputs[outputFormat]; exists {
return output.Name, output.MimeType, nil
}
return "", "", &distro.InvalidOutputFormatError{outputFormat}
return "", "", errors.New("invalid output format: " + outputFormat)
}
func (r *RHEL82) Pipeline(b *blueprint.Blueprint, outputFormat string) (*pipeline.Pipeline, error) {
output, exists := r.outputs[outputFormat]
if !exists {
return nil, &distro.InvalidOutputFormatError{outputFormat}
return nil, errors.New("invalid output format: " + outputFormat)
}
p := &pipeline.Pipeline{}

View file

@ -5,7 +5,6 @@ import (
"testing"
"github.com/osbuild/osbuild-composer/internal/distro"
_ "github.com/osbuild/osbuild-composer/internal/distro/rhel82"
)
func TestListOutputFormats(t *testing.T) {

View file

@ -1,6 +1,8 @@
package test
import (
"errors"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/pipeline"
@ -28,9 +30,9 @@ func (d *TestDistro) ListOutputFormats() []string {
}
func (d *TestDistro) FilenameFromType(outputFormat string) (string, string, error) {
return "", "", &distro.InvalidOutputFormatError{outputFormat}
return "", "", errors.New("invalid output format: " + outputFormat)
}
func (d *TestDistro) Pipeline(b *blueprint.Blueprint, outputFormat string) (*pipeline.Pipeline, error) {
return nil, &distro.InvalidOutputFormatError{outputFormat}
return nil, errors.New("invalid output format: " + outputFormat)
}

View file

@ -15,13 +15,11 @@ import (
"time"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/pipeline"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/target"
"github.com/osbuild/osbuild-composer/internal/distro"
_ "github.com/osbuild/osbuild-composer/internal/distro/fedora30"
"github.com/google/uuid"
)

View file

@ -19,7 +19,6 @@ import (
"github.com/osbuild/osbuild-composer/internal/store"
"github.com/osbuild/osbuild-composer/internal/distro"
_ "github.com/osbuild/osbuild-composer/internal/distro/fedora30"
)
type API struct {