debian-forge-composer/internal/distro/distro.go
Tom Gundersen 506b012f08 distro: take architecture as an argument
Allow bootloader specific packages to be defined per architecture,
and allow repositories to depend on the architecture.

This does not altert he pipelines we produce, part from the ami
image now contains the grub2-pc package, rather than the grub2
package. This should make no difference.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-12-14 17:23:31 +01:00

113 lines
2.6 KiB
Go

package distro
import (
"bufio"
"errors"
"io"
"os"
"strings"
"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 {
// Returns a list of repositories from which this distribution gets its
// content.
Repositories(arch string) []rpmmd.RepoConfig
// Returns a sorted list of the output formats this distro supports.
ListOutputFormats() []string
// Returns the canonical filename and MIME type for a given output
// 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.
Pipeline(b *blueprint.Blueprint, additionalRepos []rpmmd.RepoConfig, checksums map[string]string, outputArchitecture, outputFormat string) (*pipeline.Pipeline, error)
// Returns a osbuild runner that can be used on this distro.
Runner() string
}
var registered map[string]Distro
func init() {
registered = map[string]Distro{
"fedora-30": fedora30.New(),
"rhel-8.2": rhel82.New(),
}
}
func New(name string) Distro {
distro, ok := registered[name]
if !ok {
return nil
}
return distro
}
func FromHost() (Distro, error) {
f, err := os.Open("/etc/os-release")
if err != nil {
return nil, err
}
defer f.Close()
osrelease, err := readOSRelease(f)
if err != nil {
return nil, err
}
name := osrelease["ID"] + "-" + osrelease["VERSION_ID"]
d := New(name)
if d == nil {
return nil, errors.New("unknown distro: " + name)
}
return d, nil
}
func Register(name string, distro Distro) {
if _, exists := registered[name]; exists {
panic("a distro with this name already exists: " + name)
}
registered[name] = distro
}
func readOSRelease(r io.Reader) (map[string]string, error) {
osrelease := make(map[string]string)
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if len(line) == 0 {
continue
}
parts := strings.SplitN(line, "=", 2)
if len(parts) != 2 {
return nil, errors.New("readOSRelease: invalid input")
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
if value[0] == '"' {
if len(value) < 2 || value[len(value)-1] != '"' {
return nil, errors.New("readOSRelease: invalid input")
}
value = value[1 : len(value)-1]
}
osrelease[key] = value
}
return osrelease, nil
}