debian-forge-composer/cmd/osbuild-pipeline/main.go
Martin Sehnoutka 9d2dacbcab internal: pass architecture from the APIs to dnf-json
The following commit will introduce support for forced architecture in
dnf-json. The APIs already have this kind of information, so we can
simply pass it to the Depsolve and FetchMetadata functions.
2020-03-24 20:45:30 +01:00

158 lines
4.6 KiB
Go

package main
import (
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"github.com/osbuild/osbuild-composer/internal/distro/fedora30"
"github.com/osbuild/osbuild-composer/internal/distro/fedora31"
"github.com/osbuild/osbuild-composer/internal/distro/fedora32"
"github.com/osbuild/osbuild-composer/internal/distro/rhel81"
"github.com/osbuild/osbuild-composer/internal/distro/rhel82"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
)
type rpmMD struct {
BuildPackages []rpmmd.PackageSpec `json:"build-packages"`
Packages []rpmmd.PackageSpec `json:"packages"`
Checksums map[string]string `json:"checksums"`
}
func main() {
var distroArg string
var archArg string
var imageTypeArg string
var blueprintArg string
var rpmmdArg bool
flag.StringVar(&distroArg, "distro", "", "distribution to create, e.g. fedora-30")
flag.StringVar(&archArg, "arch", "", "architecture to create image for, e.g. x86_64")
flag.StringVar(&imageTypeArg, "image-type", "", "image type, e.g. qcow2 or ami")
flag.BoolVar(&rpmmdArg, "rpmmd", false, "output rpmmd struct instead of pipeline manifest")
flag.Parse()
// Path to blueprint or '-' for stdin
blueprintArg = flag.Arg(0)
blueprint := &blueprint.Blueprint{}
if blueprintArg != "" {
var reader io.Reader
if blueprintArg == "-" {
reader = os.Stdin
} else {
var err error
reader, err = os.Open(blueprintArg)
if err != nil {
panic("Could not open bluerpint: " + err.Error())
}
}
file, err := ioutil.ReadAll(reader)
if err != nil {
panic("Could not read blueprint: " + err.Error())
}
err = json.Unmarshal(file, &blueprint)
if err != nil {
panic("Could not parse blueprint: " + err.Error())
}
}
distros, err := distro.NewRegistry(fedora30.New(), fedora31.New(), fedora32.New(), rhel81.New(), rhel82.New())
if err != nil {
panic(err)
}
distro := distros.GetDistro(distroArg)
if distro == nil {
_, _ = fmt.Fprintf(os.Stderr, "The provided distribution '%s' is not supported. Use one of these:\n", distroArg)
for _, d := range distros.List() {
_, _ = fmt.Fprintln(os.Stderr, " *", d)
}
return
}
arch, err := distro.GetArch(archArg)
if err != nil {
fmt.Fprintf(os.Stderr, "The provided architecture '%s' is not supported by %s. Use one of these:\n", archArg, distro.Name())
for _, a := range distro.ListArchs() {
_, _ = fmt.Fprintln(os.Stderr, " *", a)
}
return
}
imageType, err := arch.GetImageType(imageTypeArg)
if err != nil {
fmt.Fprintf(os.Stderr, "The provided image type '%s' is not supported by %s for %s. Use one of these:\n", imageTypeArg, distro.Name(), arch.Name())
for _, t := range arch.ListImageTypes() {
_, _ = fmt.Fprintln(os.Stderr, " *", t)
}
return
}
repos, err := rpmmd.LoadRepositories([]string{"."}, distro.Name())
if err != nil {
panic(err)
}
packages := make([]string, len(blueprint.Packages))
for i, pkg := range blueprint.Packages {
packages[i] = pkg.Name
// If a package has version "*" the package name suffix must be equal to "-*-*.*"
// Using just "-*" would find any other package containing the package name
if pkg.Version != "" && pkg.Version != "*" {
packages[i] += "-" + pkg.Version
} else if pkg.Version == "*" {
packages[i] += "-*-*.*"
}
}
pkgs, exclude_pkgs := imageType.BasePackages()
packages = append(pkgs, packages...)
home, err := os.UserHomeDir()
if err != nil {
panic("os.UserHomeDir(): " + err.Error())
}
rpmmd := rpmmd.NewRPMMD(path.Join(home, ".cache/osbuild-composer/rpmmd"))
packageSpecs, checksums, err := rpmmd.Depsolve(packages, exclude_pkgs, repos[arch.Name()], distro.ModulePlatformID(), arch.Name())
if err != nil {
panic("Could not depsolve: " + err.Error())
}
buildPkgs := imageType.BuildPackages()
buildPackageSpecs, _, err := rpmmd.Depsolve(buildPkgs, nil, repos[arch.Name()], distro.ModulePlatformID(), arch.Name())
if err != nil {
panic("Could not depsolve build packages: " + err.Error())
}
var bytes []byte
if rpmmdArg {
rpmMDInfo := rpmMD{
BuildPackages: buildPackageSpecs,
Packages: packageSpecs,
Checksums: checksums,
}
bytes, err = json.Marshal(rpmMDInfo)
if err != nil {
panic("could not marshal rpmmd struct into JSON")
}
} else {
manifest, err := imageType.Manifest(blueprint.Customizations, repos[arch.Name()], packageSpecs, buildPackageSpecs, imageType.Size(0))
if err != nil {
panic(err.Error())
}
bytes, err = json.Marshal(manifest)
if err != nil {
panic("could not marshal manifest into JSON")
}
}
os.Stdout.Write(bytes)
}