osbuild2: remove stage-specific device types

Devices unlike stage options, shouldn't be stage specific.
There is only one type of device so far, the loopback device, which
is already defined as a separate type.

The top level Devices type is simply an alias to a Device map.

The mkfs stages require a single device with a specific key ("device").
These stages accept only one device in their NewStage() function for
convenience and create the Stage struct with the required key.

The zipl.inst stage requires a device labeled 'disk' as well as the rest
of the devices that correspond to each partition. The disk device is
passed to the New stage function separately and added to the Stage
devices with the required key.

Signed-off-by: Achilleas Koutsou <achilleas@koutsou.net>
This commit is contained in:
Achilleas Koutsou 2021-08-05 19:54:15 +02:00 committed by Tom Gundersen
parent c74d13daf8
commit 745443181e
14 changed files with 49 additions and 104 deletions

View file

@ -894,10 +894,10 @@ func liveImagePipeline(inputPipelineName string, outputFilename string, pt *disk
p.Name = "image"
p.Build = "name:build"
loopback := osbuild.NewLoopbackDevice(&osbuild.LoopbackDeviceOptions{Filename: outputFilename})
p.AddStage(osbuild.NewTruncateStage(&osbuild.TruncateStageOptions{Filename: outputFilename, Size: fmt.Sprintf("%d", pt.Size)}))
sfOptions, sfDevices := sfdiskStageOptions(pt, loopback)
p.AddStage(osbuild.NewSfdiskStage(sfOptions, sfDevices))
sfOptions := sfdiskStageOptions(pt)
loopback := osbuild.NewLoopbackDevice(&osbuild.LoopbackDeviceOptions{Filename: outputFilename})
p.AddStage(osbuild.NewSfdiskStage(sfOptions, loopback))
for _, stage := range mkfsStages(pt, loopback) {
p.AddStage(stage)
@ -955,28 +955,24 @@ func mkfsStages(pt *disk.PartitionTable, device *osbuild.Device) []*osbuild2.Sta
UUID: p.Filesystem.UUID,
Label: p.Filesystem.Label,
}
devices := &osbuild.MkfsXfsStageDevices{Device: *stageDevice}
stage = osbuild.NewMkfsXfsStage(options, devices)
stage = osbuild.NewMkfsXfsStage(options, stageDevice)
case "vfat":
options := &osbuild.MkfsFATStageOptions{
VolID: strings.Replace(p.Filesystem.UUID, "-", "", -1),
}
devices := &osbuild.MkfsFATStageDevices{Device: *stageDevice}
stage = osbuild.NewMkfsFATStage(options, devices)
stage = osbuild.NewMkfsFATStage(options, stageDevice)
case "btrfs":
options := &osbuild.MkfsBtrfsStageOptions{
UUID: p.Filesystem.UUID,
Label: p.Filesystem.Label,
}
devices := &osbuild.MkfsBtrfsStageDevices{Device: *stageDevice}
stage = osbuild.NewMkfsBtrfsStage(options, devices)
stage = osbuild.NewMkfsBtrfsStage(options, stageDevice)
case "ext4":
options := &osbuild.MkfsExt4StageOptions{
UUID: p.Filesystem.UUID,
Label: p.Filesystem.Label,
}
devices := &osbuild.MkfsExt4StageDevices{Device: *stageDevice}
stage = osbuild.NewMkfsExt4Stage(options, devices)
stage = osbuild.NewMkfsExt4Stage(options, stageDevice)
default:
panic("unknown fs type " + p.Type)
}
@ -1006,17 +1002,14 @@ func bootloaderConfigStage(t *imageType, partitionTable disk.PartitionTable, ker
return osbuild.NewGRUB2Stage(grub2StageOptions(partitionTable.RootPartition(), partitionTable.BootPartition(), kernelOptions, kernel, kernelVer, uefi, legacy))
}
func bootloaderInstStage(filename string, pt *disk.PartitionTable, arch *architecture, kernelVer string, devices *osbuild.CopyStageDevices, mounts *osbuild.Mounts, disk *osbuild.Device) *osbuild.Stage {
func bootloaderInstStage(filename string, pt *disk.PartitionTable, arch *architecture, kernelVer string, devices *osbuild.Devices, mounts *osbuild.Mounts, disk *osbuild.Device) *osbuild.Stage {
platform := arch.legacy
if platform != "" {
return osbuild.NewGrub2InstStage(grub2InstStageOptions(filename, pt, platform))
}
if arch.name == distro.S390xArchName {
devmap := map[string]osbuild.Device(*devices)
devmap["disk"] = *disk
ziplDevices := osbuild.CopyStageDevices(devmap)
return osbuild.NewZiplInstStage(ziplInstStageOptions(kernelVer, pt), &ziplDevices, mounts)
return osbuild.NewZiplInstStage(ziplInstStageOptions(kernelVer, pt), disk, devices, mounts)
}
return nil

View file

@ -352,11 +352,7 @@ func grub2StageOptions(rootPartition *disk.Partition, bootPartition *disk.Partit
// sfdiskStageOptions creates the options and devices properties for an
// org.osbuild.sfdisk stage based on a partition table description
func sfdiskStageOptions(pt *disk.PartitionTable, device *osbuild.Device) (*osbuild.SfdiskStageOptions, *osbuild.SfdiskStageDevices) {
stageDevices := &osbuild.SfdiskStageDevices{
Device: *device,
}
func sfdiskStageOptions(pt *disk.PartitionTable) *osbuild.SfdiskStageOptions {
partitions := make([]osbuild.Partition, len(pt.Partitions))
for idx, p := range pt.Partitions {
partitions[idx] = osbuild.Partition{
@ -373,7 +369,7 @@ func sfdiskStageOptions(pt *disk.PartitionTable, device *osbuild.Device) (*osbui
Partitions: partitions,
}
return stageOptions, stageDevices
return stageOptions
}
// copyFSTreeOptions creates the options, inputs, devices, and mounts properties
@ -381,7 +377,7 @@ func sfdiskStageOptions(pt *disk.PartitionTable, device *osbuild.Device) (*osbui
// table description to define the mounts
func copyFSTreeOptions(inputName, inputPipeline string, pt *disk.PartitionTable, device *osbuild.Device) (
*osbuild.CopyStageOptions,
*osbuild.CopyStageDevices,
*osbuild.Devices,
*osbuild.Mounts,
) {
// assume loopback device for simplicity since it's the only one currently supported
@ -434,7 +430,7 @@ func copyFSTreeOptions(inputName, inputPipeline string, pt *disk.PartitionTable,
})
stageMounts := osbuild.Mounts(mounts)
stageDevices := osbuild.CopyStageDevices(devices)
stageDevices := osbuild.Devices(devices)
options := osbuild.CopyStageOptions{
Paths: []osbuild.CopyStagePath{

View file

@ -27,16 +27,12 @@ type CopyStageReferences []string
func (CopyStageReferences) isReferences() {}
type CopyStageDevices map[string]Device
func (CopyStageDevices) isStageDevices() {}
func NewCopyStage(options *CopyStageOptions, inputs *CopyStageInputs, devices *CopyStageDevices, mounts *Mounts) *Stage {
func NewCopyStage(options *CopyStageOptions, inputs *CopyStageInputs, devices *Devices, mounts *Mounts) *Stage {
return &Stage{
Type: "org.osbuild.copy",
Options: options,
Inputs: inputs,
Devices: devices,
Devices: *devices,
Mounts: *mounts,
}
}

View file

@ -33,15 +33,16 @@ func TestNewCopyStage(t *testing.T) {
treeInput.Type = "org.osbuild.tree"
treeInput.Origin = "org.osbuild.pipeline"
treeInput.References = []string{"name:input-pipeline"}
copyStageDevices := CopyStageDevices(devices)
expectedStage := &Stage{
Type: "org.osbuild.copy",
Options: &CopyStageOptions{paths},
Inputs: &CopyStageInputs{"tree-input": treeInput},
Devices: &copyStageDevices,
Devices: devices,
Mounts: mounts,
}
// convert to alias types
stageMounts := Mounts(mounts)
actualStage := NewCopyStage(&CopyStageOptions{paths}, &CopyStageInputs{"tree-input": treeInput}, &copyStageDevices, &stageMounts)
stageDevices := Devices(devices)
actualStage := NewCopyStage(&CopyStageOptions{paths}, &CopyStageInputs{"tree-input": treeInput}, &stageDevices, &stageMounts)
assert.Equal(t, expectedStage, actualStage)
}

View file

@ -1,8 +1,6 @@
package osbuild2
type Devices interface {
isStageDevices()
}
type Devices map[string]Device
type Device struct {
Type string `json:"type"`

View file

@ -7,16 +7,10 @@ type MkfsBtrfsStageOptions struct {
func (MkfsBtrfsStageOptions) isStageOptions() {}
type MkfsBtrfsStageDevices struct {
Device Device `json:"device"`
}
func (MkfsBtrfsStageDevices) isStageDevices() {}
func NewMkfsBtrfsStage(options *MkfsBtrfsStageOptions, devices *MkfsBtrfsStageDevices) *Stage {
func NewMkfsBtrfsStage(options *MkfsBtrfsStageOptions, device *Device) *Stage {
return &Stage{
Type: "org.osbuild.mkfs.btrfs",
Options: options,
Devices: devices,
Devices: Devices{"device": *device},
}
}

View file

@ -7,16 +7,10 @@ type MkfsExt4StageOptions struct {
func (MkfsExt4StageOptions) isStageOptions() {}
type MkfsExt4StageDevices struct {
Device Device `json:"device"`
}
func (MkfsExt4StageDevices) isStageDevices() {}
func NewMkfsExt4Stage(options *MkfsExt4StageOptions, devices *MkfsExt4StageDevices) *Stage {
func NewMkfsExt4Stage(options *MkfsExt4StageOptions, device *Device) *Stage {
return &Stage{
Type: "org.osbuild.mkfs.ext4",
Options: options,
Devices: devices,
Devices: Devices{"device": *device},
}
}

View file

@ -8,16 +8,10 @@ type MkfsFATStageOptions struct {
func (MkfsFATStageOptions) isStageOptions() {}
type MkfsFATStageDevices struct {
Device Device `json:"device"`
}
func (MkfsFATStageDevices) isStageDevices() {}
func NewMkfsFATStage(options *MkfsFATStageOptions, devices *MkfsFATStageDevices) *Stage {
func NewMkfsFATStage(options *MkfsFATStageOptions, device *Device) *Stage {
return &Stage{
Type: "org.osbuild.mkfs.fat",
Options: options,
Devices: devices,
Devices: Devices{"device": *device},
}
}

View file

@ -21,12 +21,11 @@ func TestNewMkfsStage(t *testing.T) {
UUID: uuid.New().String(),
Label: "test",
}
btrfsDevices := &MkfsBtrfsStageDevices{Device: *device}
mkbtrfs := NewMkfsBtrfsStage(btrfsOptions, btrfsDevices)
mkbtrfs := NewMkfsBtrfsStage(btrfsOptions, device)
mkbtrfsExpected := &Stage{
Type: "org.osbuild.mkfs.btrfs",
Options: btrfsOptions,
Devices: btrfsDevices,
Devices: Devices{"device": *device},
}
assert.Equal(t, mkbtrfsExpected, mkbtrfs)
@ -34,12 +33,11 @@ func TestNewMkfsStage(t *testing.T) {
UUID: uuid.New().String(),
Label: "test",
}
ext4Devices := &MkfsExt4StageDevices{Device: *device}
mkext4 := NewMkfsExt4Stage(ext4Options, ext4Devices)
mkext4 := NewMkfsExt4Stage(ext4Options, device)
mkext4Expected := &Stage{
Type: "org.osbuild.mkfs.ext4",
Options: ext4Options,
Devices: ext4Devices,
Devices: Devices{"device": *device},
}
assert.Equal(t, mkext4Expected, mkext4)
@ -48,12 +46,11 @@ func TestNewMkfsStage(t *testing.T) {
Label: "test",
FATSize: common.IntToPtr(12),
}
fatDevices := &MkfsFATStageDevices{Device: *device}
mkfat := NewMkfsFATStage(fatOptions, fatDevices)
mkfat := NewMkfsFATStage(fatOptions, device)
mkfatExpected := &Stage{
Type: "org.osbuild.mkfs.fat",
Options: fatOptions,
Devices: fatDevices,
Devices: Devices{"device": *device},
}
assert.Equal(t, mkfatExpected, mkfat)
@ -61,12 +58,11 @@ func TestNewMkfsStage(t *testing.T) {
UUID: uuid.New().String(),
Label: "test",
}
xfsDevices := &MkfsXfsStageDevices{Device: *device}
mkxfs := NewMkfsXfsStage(xfsOptions, xfsDevices)
mkxfs := NewMkfsXfsStage(xfsOptions, device)
mkxfsExpected := &Stage{
Type: "org.osbuild.mkfs.xfs",
Options: xfsOptions,
Devices: xfsDevices,
Devices: Devices{"device": *device},
}
assert.Equal(t, mkxfsExpected, mkxfs)
}

View file

@ -7,16 +7,10 @@ type MkfsXfsStageOptions struct {
func (MkfsXfsStageOptions) isStageOptions() {}
type MkfsXfsStageDevices struct {
Device Device `json:"device"`
}
func (MkfsXfsStageDevices) isStageDevices() {}
func NewMkfsXfsStage(options *MkfsXfsStageOptions, devices *MkfsXfsStageDevices) *Stage {
func NewMkfsXfsStage(options *MkfsXfsStageOptions, device *Device) *Stage {
return &Stage{
Type: "org.osbuild.mkfs.xfs",
Options: options,
Devices: devices,
Devices: Devices{"device": *device},
}
}

View file

@ -36,16 +36,10 @@ type Partition struct {
UUID string `json:"uuid,omitempty"`
}
type SfdiskStageDevices struct {
Device Device `json:"device"`
}
func (SfdiskStageDevices) isStageDevices() {}
func NewSfdiskStage(options *SfdiskStageOptions, devices *SfdiskStageDevices) *Stage {
func NewSfdiskStage(options *SfdiskStageOptions, device *Device) *Stage {
return &Stage{
Type: "org.osbuild.sfdisk",
Options: options,
Devices: devices,
Devices: Devices{"device": *device},
}
}

View file

@ -24,14 +24,14 @@ func TestNewSfdiskStage(t *testing.T) {
}
device := NewLoopbackDevice(&LoopbackDeviceOptions{Filename: "disk.raw"})
devices := SfdiskStageDevices{*device}
devices := Devices{"device": *device}
expectedStage := &Stage{
Type: "org.osbuild.sfdisk",
Options: &options,
Devices: &devices,
Devices: devices,
}
actualStage := NewSfdiskStage(&options, &devices)
actualStage := NewSfdiskStage(&options, device)
assert.Equal(t, expectedStage, actualStage)
}

View file

@ -111,23 +111,17 @@ func (stage *Stage) UnmarshalJSON(data []byte) error {
options = new(TruncateStageOptions)
case "org.osbuild.sfdisk":
options = new(SfdiskStageOptions)
devices = new(SfdiskStageDevices)
case "org.osbuild.copy":
options = new(CopyStageOptions)
inputs = new(CopyStageInputs)
devices = new(CopyStageDevices)
case "org.osbuild.mkfs.btrfs":
options = new(MkfsBtrfsStageOptions)
devices = new(MkfsBtrfsStageDevices)
case "org.osbuild.mkfs.ext4":
options = new(MkfsExt4StageOptions)
devices = new(MkfsExt4StageDevices)
case "org.osbuild.mkfs.fat":
options = new(MkfsFATStageOptions)
devices = new(MkfsFATStageDevices)
case "org.osbuild.mkfs.xfs":
options = new(MkfsXfsStageOptions)
devices = new(MkfsXfsStageDevices)
case "org.osbuild.qemu":
options = new(QEMUStageOptions)
inputs = new(QEMUStageInputs)

View file

@ -13,16 +13,17 @@ type ZiplInstStageOptions struct {
func (ZiplInstStageOptions) isStageOptions() {}
type ZiplInstStageDevices map[string]Device
func (ZiplInstStageDevices) isStageDevices() {}
// Return a new zipl.inst stage. A device needs to be specified as 'disk' and root mountpoint must be provided
func NewZiplInstStage(options *ZiplInstStageOptions, devices *CopyStageDevices, mounts *Mounts) *Stage {
// Return a new zipl.inst stage. The 'disk' parameter must represent the
// (entire) device that contains the /boot partition.
func NewZiplInstStage(options *ZiplInstStageOptions, disk *Device, devices *Devices, mounts *Mounts) *Stage {
// create a new devices map and add the disk to it
devmap := map[string]Device(*devices)
devmap["disk"] = *disk
ziplDevices := Devices(devmap)
return &Stage{
Type: "org.osbuild.zipl.inst",
Options: options,
Devices: devices,
Devices: ziplDevices,
Mounts: *mounts,
}
}