Add a new option to `GenImagePrepareStages`, which is used by all modern pipelines for partitioning, to optionally use the `sgdisk` partitioning tool via `org.osbuild.sgdisk`.
126 lines
3.1 KiB
Go
126 lines
3.1 KiB
Go
package osbuild2
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/osbuild/osbuild-composer/internal/disk"
|
|
)
|
|
|
|
// sfdiskStageOptions creates the options and devices properties for an
|
|
// org.osbuild.sfdisk stage based on a partition table description
|
|
func sfdiskStageOptions(pt *disk.PartitionTable) *SfdiskStageOptions {
|
|
partitions := make([]SfdiskPartition, len(pt.Partitions))
|
|
for idx, p := range pt.Partitions {
|
|
partitions[idx] = SfdiskPartition{
|
|
Bootable: p.Bootable,
|
|
Start: pt.BytesToSectors(p.Start),
|
|
Size: pt.BytesToSectors(p.Size),
|
|
Type: p.Type,
|
|
UUID: p.UUID,
|
|
}
|
|
}
|
|
stageOptions := &SfdiskStageOptions{
|
|
Label: pt.Type,
|
|
UUID: pt.UUID,
|
|
Partitions: partitions,
|
|
}
|
|
|
|
return stageOptions
|
|
}
|
|
|
|
// sgdiskStageOptions creates the options and devices properties for an
|
|
// org.osbuild.sgdisk stage based on a partition table description
|
|
func sgdiskStageOptions(pt *disk.PartitionTable) *SgdiskStageOptions {
|
|
partitions := make([]SgdiskPartition, len(pt.Partitions))
|
|
for idx, p := range pt.Partitions {
|
|
partitions[idx] = SgdiskPartition{
|
|
Bootable: p.Bootable,
|
|
Start: pt.BytesToSectors(p.Start),
|
|
Size: pt.BytesToSectors(p.Size),
|
|
Type: p.Type,
|
|
}
|
|
|
|
if p.UUID != "" {
|
|
u := uuid.MustParse(p.UUID)
|
|
partitions[idx].UUID = &u
|
|
}
|
|
}
|
|
|
|
stageOptions := &SgdiskStageOptions{
|
|
UUID: uuid.MustParse(pt.UUID),
|
|
Partitions: partitions,
|
|
}
|
|
|
|
return stageOptions
|
|
}
|
|
|
|
type PartTool string
|
|
|
|
const (
|
|
PTSfdisk PartTool = "sfdisk"
|
|
PTSgdisk PartTool = "sgdisk"
|
|
)
|
|
|
|
func GenImagePrepareStages(pt *disk.PartitionTable, filename string, partTool PartTool) []*Stage {
|
|
stages := make([]*Stage, 0)
|
|
|
|
// create an empty file of the given size via `org.osbuild.truncate`
|
|
stage := NewTruncateStage(
|
|
&TruncateStageOptions{
|
|
Filename: filename,
|
|
Size: fmt.Sprintf("%d", pt.Size),
|
|
})
|
|
|
|
stages = append(stages, stage)
|
|
|
|
// create the partition layout in the empty file
|
|
loopback := NewLoopbackDevice(
|
|
&LoopbackDeviceOptions{
|
|
Filename: filename,
|
|
Lock: true,
|
|
},
|
|
)
|
|
|
|
if partTool == PTSfdisk {
|
|
sfOptions := sfdiskStageOptions(pt)
|
|
sfdisk := NewSfdiskStage(sfOptions, loopback)
|
|
stages = append(stages, sfdisk)
|
|
} else if partTool == PTSgdisk {
|
|
sgOptions := sgdiskStageOptions(pt)
|
|
sgdisk := NewSgdiskStage(sgOptions, loopback)
|
|
stages = append(stages, sgdisk)
|
|
} else {
|
|
panic("programming error: unknown PartTool: " + partTool)
|
|
}
|
|
|
|
// Generate all the needed "devices", like LUKS2 and LVM2
|
|
s := GenDeviceCreationStages(pt, filename)
|
|
stages = append(stages, s...)
|
|
|
|
// Generate all the filesystems on partitons and devices
|
|
s = GenMkfsStages(pt, loopback)
|
|
stages = append(stages, s...)
|
|
|
|
return stages
|
|
}
|
|
|
|
func GenImageFinishStages(pt *disk.PartitionTable, filename string) []*Stage {
|
|
return GenDeviceFinishStages(pt, filename)
|
|
}
|
|
|
|
func GenImageKernelOptions(pt *disk.PartitionTable) []string {
|
|
cmdline := make([]string, 0)
|
|
|
|
genOptions := func(e disk.Entity, path []disk.Entity) error {
|
|
switch ent := e.(type) {
|
|
case *disk.LUKSContainer:
|
|
karg := "luks.uuid=" + ent.UUID
|
|
cmdline = append(cmdline, karg)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
_ = pt.ForEachEntity(genOptions)
|
|
return cmdline
|
|
}
|