debian-forge-composer/internal/osbuild2/disk.go
Christian Kellner 75d7bbaaa3 osbuild2: optionally use sgdisk for partitioning
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`.
2022-06-21 00:06:26 +02:00

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
}