pipeline: move package to top level
The pipeline package is exists conceptually between the distro and the osbuild packages, so move it to the top level rather than as a child of distro. No functional change.
This commit is contained in:
parent
e024ceb138
commit
ae34513d18
13 changed files with 0 additions and 0 deletions
|
|
@ -1,191 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
||||
)
|
||||
|
||||
// An AnacondaPipeline represents the installer tree as found on an ISO.
|
||||
type AnacondaPipeline struct {
|
||||
Pipeline
|
||||
// Users indicate whether or not the user spoke should be enabled in
|
||||
// anaconda. If it is, users specified in a kickstart will be configured,
|
||||
// and in case no users are provided in a kickstart the user will be
|
||||
// prompted to configure them at install time. If this is set to false
|
||||
// any kickstart provided users are ignored and the user is never
|
||||
// prompted to configure users during installation.
|
||||
Users bool
|
||||
// Biosdevname indicates whether or not biosdevname should be used to
|
||||
// name network devices when booting the installer. This may affect
|
||||
// the naming of network devices on the target system.
|
||||
Biosdevname bool
|
||||
// Variant is the variant of the product being installed.
|
||||
// TODO: what should be the default value?
|
||||
Variant string
|
||||
|
||||
repos []rpmmd.RepoConfig
|
||||
packageSpecs []rpmmd.PackageSpec
|
||||
kernelVer string
|
||||
arch string
|
||||
product string
|
||||
version string
|
||||
}
|
||||
|
||||
// NewAnacondaPipeline creates an anaconda pipeline object. repos and packages
|
||||
// indicate the content to build the installer from, which is distinct from the
|
||||
// packages the installer will install on the target system. kernelName is the
|
||||
// name of the kernel package the intsaller will use. arch is the supported
|
||||
// architecture. Product and version refers to the product the installer is the
|
||||
// installer for.
|
||||
func NewAnacondaPipeline(buildPipeline *BuildPipeline,
|
||||
repos []rpmmd.RepoConfig,
|
||||
packages []rpmmd.PackageSpec,
|
||||
kernelName,
|
||||
arch,
|
||||
product,
|
||||
version string) AnacondaPipeline {
|
||||
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(packages, kernelName)
|
||||
return AnacondaPipeline{
|
||||
Pipeline: New("anaconda-tree", buildPipeline, nil),
|
||||
repos: repos,
|
||||
packageSpecs: packages,
|
||||
kernelVer: kernelVer,
|
||||
arch: arch,
|
||||
product: product,
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
|
||||
// KernelVer returns the NEVRA of the kernel package the installer will use at
|
||||
// install time.
|
||||
func (p AnacondaPipeline) KernelVer() string {
|
||||
return p.kernelVer
|
||||
}
|
||||
|
||||
// Arch returns the supported architecture.
|
||||
func (p AnacondaPipeline) Arch() string {
|
||||
return p.arch
|
||||
}
|
||||
|
||||
// Product returns the product being installed.
|
||||
func (p AnacondaPipeline) Product() string {
|
||||
return p.product
|
||||
}
|
||||
|
||||
// Version returns the version of the product being installed.
|
||||
func (p AnacondaPipeline) Version() string {
|
||||
return p.version
|
||||
}
|
||||
|
||||
func (p AnacondaPipeline) Serialize() osbuild2.Pipeline {
|
||||
pipeline := p.Pipeline.Serialize()
|
||||
|
||||
pipeline.AddStage(osbuild2.NewRPMStage(osbuild2.NewRPMStageOptions(p.repos), osbuild2.NewRpmStageSourceFilesInputs(p.packageSpecs)))
|
||||
pipeline.AddStage(osbuild2.NewBuildstampStage(&osbuild2.BuildstampStageOptions{
|
||||
Arch: p.Arch(),
|
||||
Product: p.Product(),
|
||||
Variant: p.Variant,
|
||||
Version: p.Version(),
|
||||
Final: true,
|
||||
}))
|
||||
pipeline.AddStage(osbuild2.NewLocaleStage(&osbuild2.LocaleStageOptions{Language: "en_US.UTF-8"}))
|
||||
|
||||
rootPassword := ""
|
||||
rootUser := osbuild2.UsersStageOptionsUser{
|
||||
Password: &rootPassword,
|
||||
}
|
||||
|
||||
installUID := 0
|
||||
installGID := 0
|
||||
installHome := "/root"
|
||||
installShell := "/usr/libexec/anaconda/run-anaconda"
|
||||
installPassword := ""
|
||||
installUser := osbuild2.UsersStageOptionsUser{
|
||||
UID: &installUID,
|
||||
GID: &installGID,
|
||||
Home: &installHome,
|
||||
Shell: &installShell,
|
||||
Password: &installPassword,
|
||||
}
|
||||
usersStageOptions := &osbuild2.UsersStageOptions{
|
||||
Users: map[string]osbuild2.UsersStageOptionsUser{
|
||||
"root": rootUser,
|
||||
"install": installUser,
|
||||
},
|
||||
}
|
||||
|
||||
pipeline.AddStage(osbuild2.NewUsersStage(usersStageOptions))
|
||||
pipeline.AddStage(osbuild2.NewAnacondaStage(osbuild2.NewAnacondaStageOptions(p.Users)))
|
||||
pipeline.AddStage(osbuild2.NewLoraxScriptStage(&osbuild2.LoraxScriptStageOptions{
|
||||
Path: "99-generic/runtime-postinstall.tmpl",
|
||||
BaseArch: p.Arch(),
|
||||
}))
|
||||
pipeline.AddStage(osbuild2.NewDracutStage(dracutStageOptions(p.KernelVer(), p.Biosdevname, []string{
|
||||
"anaconda",
|
||||
"rdma",
|
||||
"rngd",
|
||||
"multipath",
|
||||
"fcoe",
|
||||
"fcoe-uefi",
|
||||
"iscsi",
|
||||
"lunmask",
|
||||
"nfs",
|
||||
})))
|
||||
pipeline.AddStage(osbuild2.NewSELinuxConfigStage(&osbuild2.SELinuxConfigStageOptions{State: osbuild2.SELinuxStatePermissive}))
|
||||
|
||||
return pipeline
|
||||
}
|
||||
|
||||
func dracutStageOptions(kernelVer string, biosdevname bool, additionalModules []string) *osbuild2.DracutStageOptions {
|
||||
kernel := []string{kernelVer}
|
||||
modules := []string{
|
||||
"bash",
|
||||
"systemd",
|
||||
"fips",
|
||||
"systemd-initrd",
|
||||
"modsign",
|
||||
"nss-softokn",
|
||||
"i18n",
|
||||
"convertfs",
|
||||
"network-manager",
|
||||
"network",
|
||||
"ifcfg",
|
||||
"url-lib",
|
||||
"drm",
|
||||
"plymouth",
|
||||
"crypt",
|
||||
"dm",
|
||||
"dmsquash-live",
|
||||
"kernel-modules",
|
||||
"kernel-modules-extra",
|
||||
"kernel-network-modules",
|
||||
"livenet",
|
||||
"lvm",
|
||||
"mdraid",
|
||||
"qemu",
|
||||
"qemu-net",
|
||||
"resume",
|
||||
"rootfs-block",
|
||||
"terminfo",
|
||||
"udev-rules",
|
||||
"dracut-systemd",
|
||||
"pollcdrom",
|
||||
"usrmount",
|
||||
"base",
|
||||
"fs-lib",
|
||||
"img-lib",
|
||||
"shutdown",
|
||||
"uefi-lib",
|
||||
}
|
||||
|
||||
if biosdevname {
|
||||
modules = append(modules, "biosdevname")
|
||||
}
|
||||
|
||||
modules = append(modules, additionalModules...)
|
||||
return &osbuild2.DracutStageOptions{
|
||||
Kernel: kernel,
|
||||
Modules: modules,
|
||||
Install: []string{"/.buildstamp"},
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
||||
)
|
||||
|
||||
type BuildPipeline struct {
|
||||
Pipeline
|
||||
|
||||
repos []rpmmd.RepoConfig
|
||||
packageSpecs []rpmmd.PackageSpec
|
||||
}
|
||||
|
||||
func NewBuildPipeline(runner string, repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec) BuildPipeline {
|
||||
pipeline := BuildPipeline{
|
||||
Pipeline: New("build", nil, &runner),
|
||||
repos: repos,
|
||||
packageSpecs: packages,
|
||||
}
|
||||
return pipeline
|
||||
}
|
||||
|
||||
func (p BuildPipeline) Serialize() osbuild2.Pipeline {
|
||||
pipeline := p.Pipeline.Serialize()
|
||||
|
||||
pipeline.AddStage(osbuild2.NewRPMStage(osbuild2.NewRPMStageOptions(p.repos), osbuild2.NewRpmStageSourceFilesInputs(p.packageSpecs)))
|
||||
pipeline.AddStage(osbuild2.NewSELinuxStage(selinuxStageOptions(true)))
|
||||
|
||||
return pipeline
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
)
|
||||
|
||||
type OSTreeCommitPipeline struct {
|
||||
Pipeline
|
||||
treePipeline *OSPipeline
|
||||
OSVersion string
|
||||
Parent string
|
||||
|
||||
ref string
|
||||
}
|
||||
|
||||
func NewOSTreeCommitPipeline(buildPipeline *BuildPipeline, treePipeline *OSPipeline, ref string) OSTreeCommitPipeline {
|
||||
return OSTreeCommitPipeline{
|
||||
Pipeline: New("ostree-commit", buildPipeline, nil),
|
||||
treePipeline: treePipeline,
|
||||
ref: ref,
|
||||
}
|
||||
}
|
||||
|
||||
func (p OSTreeCommitPipeline) Ref() string {
|
||||
return p.ref
|
||||
}
|
||||
|
||||
func (p OSTreeCommitPipeline) Serialize() osbuild2.Pipeline {
|
||||
pipeline := p.Pipeline.Serialize()
|
||||
|
||||
pipeline.AddStage(osbuild2.NewOSTreeInitStage(&osbuild2.OSTreeInitStageOptions{Path: "/repo"}))
|
||||
|
||||
commitStageInput := new(osbuild2.OSTreeCommitStageInput)
|
||||
commitStageInput.Type = "org.osbuild.tree"
|
||||
commitStageInput.Origin = "org.osbuild.pipeline"
|
||||
commitStageInput.References = osbuild2.OSTreeCommitStageReferences{"name:" + p.treePipeline.Name()}
|
||||
|
||||
pipeline.AddStage(osbuild2.NewOSTreeCommitStage(
|
||||
&osbuild2.OSTreeCommitStageOptions{
|
||||
Ref: p.Ref(),
|
||||
OSVersion: p.OSVersion,
|
||||
Parent: p.Parent,
|
||||
},
|
||||
&osbuild2.OSTreeCommitStageInputs{Tree: commitStageInput}),
|
||||
)
|
||||
|
||||
return pipeline
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/common"
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
||||
)
|
||||
|
||||
type OSTreeCommitServerTreePipeline struct {
|
||||
Pipeline
|
||||
commitPipeline *OSTreeCommitPipeline
|
||||
Repos []rpmmd.RepoConfig
|
||||
PackageSpecs []rpmmd.PackageSpec
|
||||
Language string
|
||||
NginxConfigPath string
|
||||
ListenPort string
|
||||
}
|
||||
|
||||
func NewOSTreeCommitServerTreePipeline(buildPipeline *BuildPipeline, commitPipeline *OSTreeCommitPipeline) OSTreeCommitServerTreePipeline {
|
||||
return OSTreeCommitServerTreePipeline{
|
||||
Pipeline: New("container-tree", buildPipeline, nil),
|
||||
commitPipeline: commitPipeline,
|
||||
Language: "en_US",
|
||||
}
|
||||
}
|
||||
|
||||
func (p OSTreeCommitServerTreePipeline) Serialize() osbuild2.Pipeline {
|
||||
pipeline := p.Pipeline.Serialize()
|
||||
|
||||
pipeline.AddStage(osbuild2.NewRPMStage(osbuild2.NewRPMStageOptions(p.Repos), osbuild2.NewRpmStageSourceFilesInputs(p.PackageSpecs)))
|
||||
pipeline.AddStage(osbuild2.NewLocaleStage(&osbuild2.LocaleStageOptions{Language: p.Language}))
|
||||
|
||||
htmlRoot := "/usr/share/nginx/html"
|
||||
repoPath := filepath.Join(htmlRoot, "repo")
|
||||
pipeline.AddStage(osbuild2.NewOSTreeInitStage(&osbuild2.OSTreeInitStageOptions{Path: repoPath}))
|
||||
|
||||
pipeline.AddStage(osbuild2.NewOSTreePullStage(
|
||||
&osbuild2.OSTreePullStageOptions{Repo: repoPath},
|
||||
osbuild2.NewOstreePullStageInputs("org.osbuild.pipeline", "name:"+p.commitPipeline.Name(), p.commitPipeline.Ref()),
|
||||
))
|
||||
|
||||
// make nginx log and lib directories world writeable, otherwise nginx can't start in
|
||||
// an unprivileged container
|
||||
pipeline.AddStage(osbuild2.NewChmodStage(chmodStageOptions("/var/log/nginx", "a+rwX", true)))
|
||||
pipeline.AddStage(osbuild2.NewChmodStage(chmodStageOptions("/var/lib/nginx", "a+rwX", true)))
|
||||
|
||||
pipeline.AddStage(osbuild2.NewNginxConfigStage(nginxConfigStageOptions(p.NginxConfigPath, htmlRoot, p.ListenPort)))
|
||||
|
||||
return pipeline
|
||||
}
|
||||
|
||||
func nginxConfigStageOptions(path, htmlRoot, listen string) *osbuild2.NginxConfigStageOptions {
|
||||
// configure nginx to work in an unprivileged container
|
||||
cfg := &osbuild2.NginxConfig{
|
||||
Listen: listen,
|
||||
Root: htmlRoot,
|
||||
Daemon: common.BoolToPtr(false),
|
||||
PID: "/tmp/nginx.pid",
|
||||
}
|
||||
return &osbuild2.NginxConfigStageOptions{
|
||||
Path: path,
|
||||
Config: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
func chmodStageOptions(path, mode string, recursive bool) *osbuild2.ChmodStageOptions {
|
||||
return &osbuild2.ChmodStageOptions{
|
||||
Items: map[string]osbuild2.ChmodStagePathOptions{
|
||||
path: {Mode: mode, Recursive: recursive},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
)
|
||||
|
||||
type ISOPipeline struct {
|
||||
Pipeline
|
||||
treePipeline *ISOTreePipeline
|
||||
Filename string
|
||||
ISOLinux bool
|
||||
}
|
||||
|
||||
func NewISOPipeline(buildPipeline *BuildPipeline, treePipeline *ISOTreePipeline) ISOPipeline {
|
||||
return ISOPipeline{
|
||||
Pipeline: New("bootiso", buildPipeline, nil),
|
||||
treePipeline: treePipeline,
|
||||
}
|
||||
}
|
||||
|
||||
func (p ISOPipeline) Serialize() osbuild2.Pipeline {
|
||||
pipeline := p.Pipeline.Serialize()
|
||||
|
||||
pipeline.AddStage(osbuild2.NewXorrisofsStage(xorrisofsStageOptions(p.Filename, p.treePipeline.ISOLabel(), p.ISOLinux), osbuild2.NewXorrisofsStagePipelineTreeInputs(p.treePipeline.Name())))
|
||||
pipeline.AddStage(osbuild2.NewImplantisomd5Stage(&osbuild2.Implantisomd5StageOptions{Filename: p.Filename}))
|
||||
|
||||
return pipeline
|
||||
}
|
||||
|
||||
func xorrisofsStageOptions(filename, isolabel string, isolinux bool) *osbuild2.XorrisofsStageOptions {
|
||||
options := &osbuild2.XorrisofsStageOptions{
|
||||
Filename: filename,
|
||||
VolID: isolabel,
|
||||
SysID: "LINUX",
|
||||
EFI: "images/efiboot.img",
|
||||
ISOLevel: 3,
|
||||
}
|
||||
|
||||
if isolinux {
|
||||
options.Boot = &osbuild2.XorrisofsBoot{
|
||||
Image: "isolinux/isolinux.bin",
|
||||
Catalog: "isolinux/boot.cat",
|
||||
}
|
||||
|
||||
options.IsohybridMBR = "/usr/share/syslinux/isohdpfx.bin"
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/blueprint"
|
||||
"github.com/osbuild/osbuild-composer/internal/distro"
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
)
|
||||
|
||||
type ISOTreePipeline struct {
|
||||
Pipeline
|
||||
anacondaPipeline *AnacondaPipeline
|
||||
Vendor string
|
||||
OSName string
|
||||
Release string
|
||||
Users []blueprint.UserCustomization
|
||||
Groups []blueprint.GroupCustomization
|
||||
OSTreeParent string
|
||||
OSTreeRef string
|
||||
|
||||
isoLabel string
|
||||
}
|
||||
|
||||
func NewISOTreePipeline(buildPipeline *BuildPipeline, anacondaPipeline *AnacondaPipeline, isoLabelTmpl string) ISOTreePipeline {
|
||||
// TODO: replace isoLabelTmpl with more high-level properties
|
||||
isoLabel := fmt.Sprintf(isoLabelTmpl, anacondaPipeline.Arch())
|
||||
|
||||
return ISOTreePipeline{
|
||||
Pipeline: New("bootiso-tree", buildPipeline, nil),
|
||||
anacondaPipeline: anacondaPipeline,
|
||||
isoLabel: isoLabel,
|
||||
}
|
||||
}
|
||||
|
||||
func (p ISOTreePipeline) ISOLabel() string {
|
||||
return p.isoLabel
|
||||
}
|
||||
|
||||
func (p ISOTreePipeline) Serialize() osbuild2.Pipeline {
|
||||
pipeline := p.Pipeline.Serialize()
|
||||
|
||||
kspath := "/osbuild.ks"
|
||||
ostreeRepoPath := "/ostree/repo"
|
||||
|
||||
pipeline.AddStage(osbuild2.NewBootISOMonoStage(bootISOMonoStageOptions(p.anacondaPipeline.KernelVer(), p.anacondaPipeline.Arch(), p.Vendor, p.anacondaPipeline.Product(), p.anacondaPipeline.Version(), p.ISOLabel(), kspath), osbuild2.NewBootISOMonoStagePipelineTreeInputs(p.anacondaPipeline.Name())))
|
||||
|
||||
kickstartOptions, err := osbuild2.NewKickstartStageOptions(kspath, "", p.Users, p.Groups, makeISORootPath(ostreeRepoPath), p.OSTreeRef, p.OSName)
|
||||
if err != nil {
|
||||
panic("password encryption failed")
|
||||
}
|
||||
|
||||
pipeline.AddStage(osbuild2.NewKickstartStage(kickstartOptions))
|
||||
pipeline.AddStage(osbuild2.NewDiscinfoStage(&osbuild2.DiscinfoStageOptions{
|
||||
BaseArch: p.anacondaPipeline.Arch(),
|
||||
Release: p.Release,
|
||||
}))
|
||||
|
||||
pipeline.AddStage(osbuild2.NewOSTreeInitStage(&osbuild2.OSTreeInitStageOptions{Path: ostreeRepoPath}))
|
||||
pipeline.AddStage(osbuild2.NewOSTreePullStage(
|
||||
&osbuild2.OSTreePullStageOptions{Repo: ostreeRepoPath},
|
||||
osbuild2.NewOstreePullStageInputs("org.osbuild.source", p.OSTreeParent, p.OSTreeRef),
|
||||
))
|
||||
|
||||
return pipeline
|
||||
}
|
||||
|
||||
func bootISOMonoStageOptions(kernelVer, arch, vendor, product, osVersion, isolabel, kspath string) *osbuild2.BootISOMonoStageOptions {
|
||||
comprOptions := new(osbuild2.FSCompressionOptions)
|
||||
if bcj := osbuild2.BCJOption(arch); bcj != "" {
|
||||
comprOptions.BCJ = bcj
|
||||
}
|
||||
var architectures []string
|
||||
|
||||
if arch == distro.X86_64ArchName {
|
||||
architectures = []string{"X64"}
|
||||
} else if arch == distro.Aarch64ArchName {
|
||||
architectures = []string{"AA64"}
|
||||
} else {
|
||||
panic("unsupported architecture")
|
||||
}
|
||||
|
||||
return &osbuild2.BootISOMonoStageOptions{
|
||||
Product: osbuild2.Product{
|
||||
Name: product,
|
||||
Version: osVersion,
|
||||
},
|
||||
ISOLabel: isolabel,
|
||||
Kernel: kernelVer,
|
||||
KernelOpts: fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", isolabel, kspath),
|
||||
EFI: osbuild2.EFI{
|
||||
Architectures: architectures,
|
||||
Vendor: vendor,
|
||||
},
|
||||
ISOLinux: osbuild2.ISOLinux{
|
||||
Enabled: arch == distro.X86_64ArchName,
|
||||
Debug: false,
|
||||
},
|
||||
Templates: "99-generic",
|
||||
RootFS: osbuild2.RootFS{
|
||||
Size: 9216,
|
||||
Compression: osbuild2.FSCompression{
|
||||
Method: "xz",
|
||||
Options: comprOptions,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//makeISORootPath return a path that can be used to address files and folders in
|
||||
//the root of the iso
|
||||
func makeISORootPath(p string) string {
|
||||
fullpath := path.Join("/run/install/repo", p)
|
||||
return fmt.Sprintf("file://%s", fullpath)
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"github.com/osbuild/osbuild-composer/internal/disk"
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
)
|
||||
|
||||
type LiveImgPipeline struct {
|
||||
Pipeline
|
||||
PartitionTable disk.PartitionTable
|
||||
BootLoader BootLoader
|
||||
GRUBLegacy string
|
||||
treePipeline *OSPipeline
|
||||
Filename string
|
||||
}
|
||||
|
||||
func NewLiveImgPipeline(buildPipeline *BuildPipeline, treePipeline *OSPipeline) LiveImgPipeline {
|
||||
return LiveImgPipeline{
|
||||
Pipeline: New("image", buildPipeline, nil),
|
||||
treePipeline: treePipeline,
|
||||
}
|
||||
}
|
||||
|
||||
func (p LiveImgPipeline) Serialize() osbuild2.Pipeline {
|
||||
pipeline := p.Pipeline.Serialize()
|
||||
|
||||
for _, stage := range osbuild2.GenImagePrepareStages(&p.PartitionTable, p.Filename, osbuild2.PTSfdisk) {
|
||||
pipeline.AddStage(stage)
|
||||
}
|
||||
|
||||
inputName := "root-tree"
|
||||
copyOptions, copyDevices, copyMounts := osbuild2.GenCopyFSTreeOptions(inputName, p.treePipeline.Name(), p.Filename, &p.PartitionTable)
|
||||
copyInputs := osbuild2.NewCopyStagePipelineTreeInputs(inputName, p.treePipeline.Name())
|
||||
pipeline.AddStage(osbuild2.NewCopyStage(copyOptions, copyInputs, copyDevices, copyMounts))
|
||||
|
||||
for _, stage := range osbuild2.GenImageFinishStages(&p.PartitionTable, p.Filename) {
|
||||
pipeline.AddStage(stage)
|
||||
}
|
||||
|
||||
switch p.BootLoader {
|
||||
case BOOTLOADER_GRUB:
|
||||
if p.GRUBLegacy != "" {
|
||||
pipeline.AddStage(osbuild2.NewGrub2InstStage(osbuild2.NewGrub2InstStageOption(p.Filename, &p.PartitionTable, p.GRUBLegacy)))
|
||||
}
|
||||
case BOOTLOADER_ZIPL:
|
||||
loopback := osbuild2.NewLoopbackDevice(&osbuild2.LoopbackDeviceOptions{Filename: p.Filename})
|
||||
pipeline.AddStage(osbuild2.NewZiplInstStage(osbuild2.NewZiplInstStageOptions(p.treePipeline.KernelVer(), &p.PartitionTable), loopback, copyDevices, copyMounts))
|
||||
}
|
||||
|
||||
return pipeline
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
)
|
||||
|
||||
type OCIContainerPipeline struct {
|
||||
Pipeline
|
||||
treePipeline *Pipeline
|
||||
Architecture string
|
||||
Filename string
|
||||
Cmd []string
|
||||
ExposedPorts []string
|
||||
}
|
||||
|
||||
func NewOCIContainerPipeline(buildPipeline *BuildPipeline, treePipeline *Pipeline) OCIContainerPipeline {
|
||||
return OCIContainerPipeline{
|
||||
Pipeline: New("container", buildPipeline, nil),
|
||||
treePipeline: treePipeline,
|
||||
}
|
||||
}
|
||||
|
||||
func (p OCIContainerPipeline) Serialize() osbuild2.Pipeline {
|
||||
pipeline := p.Pipeline.Serialize()
|
||||
|
||||
options := &osbuild2.OCIArchiveStageOptions{
|
||||
Architecture: p.Architecture,
|
||||
Filename: p.Filename,
|
||||
Config: &osbuild2.OCIArchiveConfig{
|
||||
Cmd: p.Cmd,
|
||||
ExposedPorts: p.ExposedPorts,
|
||||
},
|
||||
}
|
||||
baseInput := new(osbuild2.OCIArchiveStageInput)
|
||||
baseInput.Type = "org.osbuild.tree"
|
||||
baseInput.Origin = "org.osbuild.pipeline"
|
||||
baseInput.References = []string{"name:" + p.treePipeline.Name()}
|
||||
inputs := &osbuild2.OCIArchiveStageInputs{Base: baseInput}
|
||||
pipeline.AddStage(osbuild2.NewOCIArchiveStage(options, inputs))
|
||||
|
||||
return pipeline
|
||||
}
|
||||
|
|
@ -1,320 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/blueprint"
|
||||
"github.com/osbuild/osbuild-composer/internal/common"
|
||||
"github.com/osbuild/osbuild-composer/internal/disk"
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
||||
)
|
||||
|
||||
type OSPipeline struct {
|
||||
Pipeline
|
||||
OSTreeParent string
|
||||
OSTreeURL string
|
||||
KernelOptionsAppend []string
|
||||
BootLoader BootLoader
|
||||
UEFI bool
|
||||
GRUBLegacy string
|
||||
Vendor string
|
||||
GPGKeyFiles []string
|
||||
PartitionTable *disk.PartitionTable
|
||||
Language string
|
||||
Keyboard *string
|
||||
Hostname string
|
||||
Timezone string
|
||||
NTPServers []string
|
||||
EnabledServices []string
|
||||
DisabledServices []string
|
||||
DefaultTarget string
|
||||
// TODO: drop blueprint types from the API
|
||||
Groups []blueprint.GroupCustomization
|
||||
Users []blueprint.UserCustomization
|
||||
Firewall *blueprint.FirewallCustomization
|
||||
// TODO: drop osbuild2 types from the API
|
||||
Grub2Config *osbuild2.GRUB2Config
|
||||
Sysconfig []*osbuild2.SysconfigStageOptions
|
||||
SystemdLogind []*osbuild2.SystemdLogindStageOptions
|
||||
CloudInit []*osbuild2.CloudInitStageOptions
|
||||
Modprobe []*osbuild2.ModprobeStageOptions
|
||||
DracutConf []*osbuild2.DracutConfStageOptions
|
||||
SystemdUnit []*osbuild2.SystemdUnitStageOptions
|
||||
Authselect *osbuild2.AuthselectStageOptions
|
||||
SELinuxConfig *osbuild2.SELinuxConfigStageOptions
|
||||
Tuned *osbuild2.TunedStageOptions
|
||||
Tmpfilesd []*osbuild2.TmpfilesdStageOptions
|
||||
PamLimitsConf []*osbuild2.PamLimitsConfStageOptions
|
||||
Sysctld []*osbuild2.SysctldStageOptions
|
||||
DNFConfig []*osbuild2.DNFConfigStageOptions
|
||||
SshdConfig *osbuild2.SshdConfigStageOptions
|
||||
AuthConfig *osbuild2.AuthconfigStageOptions
|
||||
PwQuality *osbuild2.PwqualityConfStageOptions
|
||||
WAAgentConfig *osbuild2.WAAgentConfStageOptions
|
||||
|
||||
osTree bool
|
||||
repos []rpmmd.RepoConfig
|
||||
packageSpecs []rpmmd.PackageSpec
|
||||
kernelVer string
|
||||
}
|
||||
|
||||
func NewOSPipeline(buildPipeline *BuildPipeline, osTree bool, repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelName string) OSPipeline {
|
||||
name := "os"
|
||||
if osTree {
|
||||
name = "ostree-tree"
|
||||
}
|
||||
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(packages, kernelName)
|
||||
return OSPipeline{
|
||||
Pipeline: New(name, buildPipeline, nil),
|
||||
osTree: osTree,
|
||||
repos: repos,
|
||||
packageSpecs: packages,
|
||||
kernelVer: kernelVer,
|
||||
Hostname: "localhost.localdomain",
|
||||
}
|
||||
}
|
||||
|
||||
func (p OSPipeline) KernelVer() string {
|
||||
return p.kernelVer
|
||||
}
|
||||
|
||||
func (p OSPipeline) Serialize() osbuild2.Pipeline {
|
||||
pipeline := p.Pipeline.Serialize()
|
||||
|
||||
if p.osTree && p.OSTreeParent != "" && p.OSTreeURL != "" {
|
||||
pipeline.AddStage(osbuild2.NewOSTreePasswdStage("org.osbuild.source", p.OSTreeParent))
|
||||
}
|
||||
|
||||
rpmOptions := osbuild2.NewRPMStageOptions(p.repos)
|
||||
rpmOptions.GPGKeysFromTree = p.GPGKeyFiles
|
||||
pipeline.AddStage(osbuild2.NewRPMStage(rpmOptions, osbuild2.NewRpmStageSourceFilesInputs(p.packageSpecs)))
|
||||
|
||||
// If the /boot is on a separate partition, the prefix for the BLS stage must be ""
|
||||
if p.PartitionTable == nil || p.PartitionTable.FindMountable("/boot") == nil {
|
||||
pipeline.AddStage(osbuild2.NewFixBLSStage(&osbuild2.FixBLSStageOptions{}))
|
||||
} else {
|
||||
pipeline.AddStage(osbuild2.NewFixBLSStage(&osbuild2.FixBLSStageOptions{Prefix: common.StringToPtr("")}))
|
||||
}
|
||||
|
||||
pipeline.AddStage(osbuild2.NewLocaleStage(&osbuild2.LocaleStageOptions{Language: p.Language}))
|
||||
|
||||
if p.Keyboard != nil {
|
||||
pipeline.AddStage(osbuild2.NewKeymapStage(&osbuild2.KeymapStageOptions{Keymap: *p.Keyboard}))
|
||||
}
|
||||
|
||||
pipeline.AddStage(osbuild2.NewHostnameStage(&osbuild2.HostnameStageOptions{Hostname: p.Hostname}))
|
||||
pipeline.AddStage(osbuild2.NewTimezoneStage(&osbuild2.TimezoneStageOptions{Zone: p.Timezone}))
|
||||
|
||||
if len(p.NTPServers) > 0 {
|
||||
pipeline.AddStage(osbuild2.NewChronyStage(&osbuild2.ChronyStageOptions{Timeservers: p.NTPServers}))
|
||||
}
|
||||
|
||||
if len(p.Groups) > 0 {
|
||||
pipeline.AddStage(osbuild2.NewGroupsStage(osbuild2.NewGroupsStageOptions(p.Groups)))
|
||||
}
|
||||
|
||||
if len(p.Users) > 0 {
|
||||
userOptions, err := osbuild2.NewUsersStageOptions(p.Users, false)
|
||||
if err != nil {
|
||||
// TODO: move encryption into weldr
|
||||
panic("password encryption failed")
|
||||
}
|
||||
if p.osTree {
|
||||
// for ostree, writing the key during user creation is
|
||||
// redundant and can cause issues so create users without keys
|
||||
// and write them on first boot
|
||||
userOptionsSansKeys, err := osbuild2.NewUsersStageOptions(p.Users, true)
|
||||
if err != nil {
|
||||
// TODO: move encryption into weldr
|
||||
panic("password encryption failed")
|
||||
}
|
||||
pipeline.AddStage(osbuild2.NewUsersStage(userOptionsSansKeys))
|
||||
pipeline.AddStage(osbuild2.NewFirstBootStage(usersFirstBootOptions(userOptions)))
|
||||
} else {
|
||||
pipeline.AddStage(osbuild2.NewUsersStage(userOptions))
|
||||
}
|
||||
}
|
||||
|
||||
if p.EnabledServices != nil ||
|
||||
p.DisabledServices != nil || p.DefaultTarget != "" {
|
||||
pipeline.AddStage(osbuild2.NewSystemdStage(&osbuild2.SystemdStageOptions{
|
||||
EnabledServices: p.EnabledServices,
|
||||
DisabledServices: p.DisabledServices,
|
||||
DefaultTarget: p.DefaultTarget,
|
||||
}))
|
||||
}
|
||||
|
||||
if p.Firewall != nil {
|
||||
options := osbuild2.FirewallStageOptions{
|
||||
Ports: p.Firewall.Ports,
|
||||
}
|
||||
|
||||
if p.Firewall.Services != nil {
|
||||
options.EnabledServices = p.Firewall.Services.Enabled
|
||||
options.DisabledServices = p.Firewall.Services.Disabled
|
||||
}
|
||||
|
||||
pipeline.AddStage(osbuild2.NewFirewallStage(&options))
|
||||
}
|
||||
|
||||
for _, sysconfigConfig := range p.Sysconfig {
|
||||
pipeline.AddStage(osbuild2.NewSysconfigStage(sysconfigConfig))
|
||||
}
|
||||
|
||||
for _, systemdLogindConfig := range p.SystemdLogind {
|
||||
pipeline.AddStage(osbuild2.NewSystemdLogindStage(systemdLogindConfig))
|
||||
}
|
||||
|
||||
for _, cloudInitConfig := range p.CloudInit {
|
||||
pipeline.AddStage(osbuild2.NewCloudInitStage(cloudInitConfig))
|
||||
}
|
||||
|
||||
for _, modprobeConfig := range p.Modprobe {
|
||||
pipeline.AddStage(osbuild2.NewModprobeStage(modprobeConfig))
|
||||
}
|
||||
|
||||
for _, dracutConfConfig := range p.DracutConf {
|
||||
pipeline.AddStage(osbuild2.NewDracutConfStage(dracutConfConfig))
|
||||
}
|
||||
|
||||
for _, systemdUnitConfig := range p.SystemdUnit {
|
||||
pipeline.AddStage(osbuild2.NewSystemdUnitStage(systemdUnitConfig))
|
||||
}
|
||||
|
||||
if p.Authselect != nil {
|
||||
pipeline.AddStage(osbuild2.NewAuthselectStage(p.Authselect))
|
||||
}
|
||||
|
||||
if p.SELinuxConfig != nil {
|
||||
pipeline.AddStage(osbuild2.NewSELinuxConfigStage(p.SELinuxConfig))
|
||||
}
|
||||
|
||||
if p.Tuned != nil {
|
||||
pipeline.AddStage(osbuild2.NewTunedStage(p.Tuned))
|
||||
}
|
||||
|
||||
for _, tmpfilesdConfig := range p.Tmpfilesd {
|
||||
pipeline.AddStage(osbuild2.NewTmpfilesdStage(tmpfilesdConfig))
|
||||
}
|
||||
|
||||
for _, pamLimitsConfConfig := range p.PamLimitsConf {
|
||||
pipeline.AddStage(osbuild2.NewPamLimitsConfStage(pamLimitsConfConfig))
|
||||
}
|
||||
|
||||
for _, sysctldConfig := range p.Sysctld {
|
||||
pipeline.AddStage(osbuild2.NewSysctldStage(sysctldConfig))
|
||||
}
|
||||
|
||||
for _, dnfConfig := range p.DNFConfig {
|
||||
pipeline.AddStage(osbuild2.NewDNFConfigStage(dnfConfig))
|
||||
}
|
||||
|
||||
if p.SshdConfig != nil {
|
||||
pipeline.AddStage((osbuild2.NewSshdConfigStage(p.SshdConfig)))
|
||||
}
|
||||
|
||||
if p.AuthConfig != nil {
|
||||
pipeline.AddStage(osbuild2.NewAuthconfigStage(p.AuthConfig))
|
||||
}
|
||||
|
||||
if p.PwQuality != nil {
|
||||
pipeline.AddStage(osbuild2.NewPwqualityConfStage(p.PwQuality))
|
||||
}
|
||||
|
||||
if p.WAAgentConfig != nil {
|
||||
pipeline.AddStage(osbuild2.NewWAAgentConfStage(p.WAAgentConfig))
|
||||
}
|
||||
|
||||
if p.PartitionTable != nil {
|
||||
kernelOptions := osbuild2.GenImageKernelOptions(p.PartitionTable)
|
||||
kernelOptions = append(kernelOptions, p.KernelOptionsAppend...)
|
||||
pipeline = prependKernelCmdlineStage(pipeline, strings.Join(kernelOptions, " "), p.PartitionTable)
|
||||
|
||||
pipeline.AddStage(osbuild2.NewFSTabStage(osbuild2.NewFSTabStageOptions(p.PartitionTable)))
|
||||
|
||||
var bootloader *osbuild2.Stage
|
||||
switch p.BootLoader {
|
||||
case BOOTLOADER_GRUB:
|
||||
options := osbuild2.NewGrub2StageOptionsUnified(p.PartitionTable, p.kernelVer, p.UEFI, p.GRUBLegacy, p.Vendor, false)
|
||||
if cfg := p.Grub2Config; cfg != nil {
|
||||
// TODO: don't store Grub2Config in OSPipeline, making the overrides unnecessary
|
||||
// grub2.Config.Default is owned and set by `NewGrub2StageOptionsUnified`
|
||||
// and thus we need to preserve it
|
||||
if options.Config != nil {
|
||||
cfg.Default = options.Config.Default
|
||||
}
|
||||
|
||||
options.Config = cfg
|
||||
}
|
||||
bootloader = osbuild2.NewGRUB2Stage(options)
|
||||
case BOOTLOADER_ZIPL:
|
||||
bootloader = osbuild2.NewZiplStage(new(osbuild2.ZiplStageOptions))
|
||||
default:
|
||||
panic("unknown bootloader")
|
||||
}
|
||||
|
||||
pipeline.AddStage(bootloader)
|
||||
}
|
||||
|
||||
pipeline.AddStage(osbuild2.NewSELinuxStage(selinuxStageOptions(false)))
|
||||
|
||||
if p.osTree {
|
||||
pipeline.AddStage(osbuild2.NewOSTreePrepTreeStage(&osbuild2.OSTreePrepTreeStageOptions{
|
||||
EtcGroupMembers: []string{
|
||||
// NOTE: We may want to make this configurable.
|
||||
"wheel", "docker",
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
return pipeline
|
||||
}
|
||||
|
||||
func prependKernelCmdlineStage(pipeline osbuild2.Pipeline, kernelOptions string, pt *disk.PartitionTable) osbuild2.Pipeline {
|
||||
rootFs := pt.FindMountable("/")
|
||||
if rootFs == nil {
|
||||
panic("root filesystem must be defined for kernel-cmdline stage, this is a programming error")
|
||||
}
|
||||
rootFsUUID := rootFs.GetFSSpec().UUID
|
||||
kernelStage := osbuild2.NewKernelCmdlineStage(osbuild2.NewKernelCmdlineStageOptions(rootFsUUID, kernelOptions))
|
||||
pipeline.Stages = append([]*osbuild2.Stage{kernelStage}, pipeline.Stages...)
|
||||
return pipeline
|
||||
}
|
||||
|
||||
func usersFirstBootOptions(usersStageOptions *osbuild2.UsersStageOptions) *osbuild2.FirstBootStageOptions {
|
||||
cmds := make([]string, 0, 3*len(usersStageOptions.Users)+2)
|
||||
// workaround for creating authorized_keys file for user
|
||||
// need to special case the root user, which has its home in a different place
|
||||
varhome := filepath.Join("/var", "home")
|
||||
roothome := filepath.Join("/var", "roothome")
|
||||
|
||||
for name, user := range usersStageOptions.Users {
|
||||
if user.Key != nil {
|
||||
var home string
|
||||
|
||||
if name == "root" {
|
||||
home = roothome
|
||||
} else {
|
||||
home = filepath.Join(varhome, name)
|
||||
}
|
||||
|
||||
sshdir := filepath.Join(home, ".ssh")
|
||||
|
||||
cmds = append(cmds, fmt.Sprintf("mkdir -p %s", sshdir))
|
||||
cmds = append(cmds, fmt.Sprintf("sh -c 'echo %q >> %q'", *user.Key, filepath.Join(sshdir, "authorized_keys")))
|
||||
cmds = append(cmds, fmt.Sprintf("chown %s:%s -Rc %s", name, name, sshdir))
|
||||
}
|
||||
}
|
||||
cmds = append(cmds, fmt.Sprintf("restorecon -rvF %s", varhome))
|
||||
cmds = append(cmds, fmt.Sprintf("restorecon -rvF %s", roothome))
|
||||
|
||||
options := &osbuild2.FirstBootStageOptions{
|
||||
Commands: cmds,
|
||||
WaitForNetwork: false,
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
// Package pipeline implements a standard set of osbuild pipelines. A pipeline
|
||||
// conceptually represents a named filesystem tree, optionally generated
|
||||
// in a provided build root (represented by another pipeline). All inputs
|
||||
// to a pipeline must be explicitly specified, either in terms of other
|
||||
// pipeline, in terms of content addressable inputs or in terms of static
|
||||
// parameters to the inherited Pipeline structs.
|
||||
package pipeline
|
||||
|
||||
import (
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
)
|
||||
|
||||
type BootLoader uint64
|
||||
|
||||
const (
|
||||
BOOTLOADER_GRUB BootLoader = iota
|
||||
BOOTLOADER_ZIPL
|
||||
)
|
||||
|
||||
// A Pipeline represents the core functionality shared between each of the pipeline
|
||||
// implementations, and the Pipeline struct must be embedded in each of them.
|
||||
type Pipeline struct {
|
||||
name string
|
||||
runner string
|
||||
build *BuildPipeline
|
||||
}
|
||||
|
||||
// Name returns the name of the pipeline. The name must be unique for a given manifest.
|
||||
// Pipeline names are used to refer to pipelines either as dependencies between pipelines
|
||||
// or for exporting them.
|
||||
func (p Pipeline) Name() string {
|
||||
return p.name
|
||||
}
|
||||
|
||||
// New returns a generic Pipeline object. The name is mandatory, immutable and must
|
||||
// be unique among all the pipelines used in a manifest, which is currently not enforced.
|
||||
// The build argument is a pipeline representing a build root in which the rest of the
|
||||
// pipeline is built. In order to ensure reproducibility a build pipeline must always be
|
||||
// provided, except for int he build pipeline itself. When a build pipeline is not provided
|
||||
// the build host's filesystem is used as the build root, and in this case a runner must be
|
||||
// specified which knows how to interpret the host filesystem as a build root.
|
||||
func New(name string, build *BuildPipeline, runner *string) Pipeline {
|
||||
p := Pipeline{
|
||||
name: name,
|
||||
build: build,
|
||||
}
|
||||
if runner != nil {
|
||||
if build != nil {
|
||||
panic("both runner and build pipeline specified")
|
||||
}
|
||||
p.runner = *runner
|
||||
} else if build == nil {
|
||||
panic("neither build pipeline nor runner specified")
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// Serialize turns a given pipeline into an osbuild2.Pipeline object. This object is
|
||||
// meant to be treated as opaque and not to be modified further outside of the pipeline
|
||||
// package.
|
||||
func (p Pipeline) Serialize() osbuild2.Pipeline {
|
||||
var buildName string
|
||||
if p.build != nil {
|
||||
buildName = "name:" + p.build.Name()
|
||||
}
|
||||
return osbuild2.Pipeline{
|
||||
Name: p.name,
|
||||
Runner: p.runner,
|
||||
Build: buildName,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
)
|
||||
|
||||
type QemuPipeline struct {
|
||||
Pipeline
|
||||
imgPipeline *Pipeline
|
||||
InputFilename string
|
||||
OutputFilename string
|
||||
// TODO: don't expose the osbuild2 types in the API
|
||||
Format osbuild2.QEMUFormat
|
||||
FormatOptions osbuild2.QEMUFormatOptions
|
||||
}
|
||||
|
||||
func NewQemuPipeline(buildPipeline *BuildPipeline, imgPipeline *LiveImgPipeline, name string) QemuPipeline {
|
||||
return QemuPipeline{
|
||||
Pipeline: New(name, buildPipeline, nil),
|
||||
imgPipeline: &imgPipeline.Pipeline,
|
||||
}
|
||||
}
|
||||
|
||||
func (p QemuPipeline) Serialize() osbuild2.Pipeline {
|
||||
pipeline := p.Pipeline.Serialize()
|
||||
|
||||
pipeline.AddStage(osbuild2.NewQEMUStage(
|
||||
osbuild2.NewQEMUStageOptions(p.OutputFilename, p.Format, p.FormatOptions),
|
||||
osbuild2.NewQemuStagePipelineFilesInputs(p.imgPipeline.Name(), p.InputFilename),
|
||||
))
|
||||
|
||||
return pipeline
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
)
|
||||
|
||||
// selinuxStageOptions returns the options for the org.osbuild.selinux stage.
|
||||
// Setting the argument to 'true' relabels the '/usr/bin/cp'
|
||||
// binariy with 'install_exec_t'. This should be set in the build root.
|
||||
func selinuxStageOptions(labelcp bool) *osbuild2.SELinuxStageOptions {
|
||||
options := &osbuild2.SELinuxStageOptions{
|
||||
FileContexts: "etc/selinux/targeted/contexts/files/file_contexts",
|
||||
}
|
||||
if labelcp {
|
||||
options.Labels = map[string]string{
|
||||
"/usr/bin/cp": "system_u:object_r:install_exec_t:s0",
|
||||
}
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
||||
)
|
||||
|
||||
type TarPipeline struct {
|
||||
Pipeline
|
||||
inputPipeline *Pipeline
|
||||
Filename string
|
||||
}
|
||||
|
||||
func NewTarPipeline(buildPipeline *BuildPipeline, inputPipeline *Pipeline, name string) TarPipeline {
|
||||
return TarPipeline{
|
||||
Pipeline: New(name, buildPipeline, nil),
|
||||
inputPipeline: inputPipeline,
|
||||
}
|
||||
}
|
||||
|
||||
func (p TarPipeline) Serialize() osbuild2.Pipeline {
|
||||
pipeline := p.Pipeline.Serialize()
|
||||
|
||||
tree := new(osbuild2.TarStageInput)
|
||||
tree.Type = "org.osbuild.tree"
|
||||
tree.Origin = "org.osbuild.pipeline"
|
||||
tree.References = []string{"name:" + p.inputPipeline.Name()}
|
||||
tarStage := osbuild2.NewTarStage(&osbuild2.TarStageOptions{Filename: p.Filename}, &osbuild2.TarStageInputs{Tree: tree})
|
||||
|
||||
pipeline.AddStage(tarStage)
|
||||
|
||||
return pipeline
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue