chore: cleanup partition code
Cleanup partition code to be explicit about `Format` and `Partition` options. Signed-off-by: Noel Georgi <git@frezbo.dev>
This commit is contained in:
parent
31b988281e
commit
1c0c7933df
@ -360,7 +360,7 @@ func (m *Manifest) executeOnDevice(device Device, targets []*Target) (err error)
|
||||
}
|
||||
|
||||
for i, target := range targets {
|
||||
if err = target.Partition(pt, i, bd); err != nil {
|
||||
if err = target.partition(pt, i); err != nil {
|
||||
return fmt.Errorf("failed to partition device: %w", err)
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,6 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/siderolabs/go-blockdevice/blockdevice"
|
||||
"github.com/siderolabs/go-blockdevice/blockdevice/partition/gpt"
|
||||
"github.com/siderolabs/go-blockdevice/blockdevice/util"
|
||||
"golang.org/x/sys/unix"
|
||||
@ -31,6 +29,7 @@ import (
|
||||
//nolint:maligned
|
||||
type Target struct {
|
||||
*partition.FormatOptions
|
||||
*partition.Options
|
||||
Device string
|
||||
|
||||
LegacyBIOSBootable bool
|
||||
@ -99,6 +98,18 @@ func ParseTarget(label, deviceName string) (*Target, error) {
|
||||
func EFITarget(device string, extra *Target) *Target {
|
||||
target := &Target{
|
||||
FormatOptions: partition.NewFormatOptions(constants.EFIPartitionLabel),
|
||||
Options: partition.NewPartitionOptions(constants.EFIPartitionLabel, false),
|
||||
Device: device,
|
||||
}
|
||||
|
||||
return target.enhance(extra)
|
||||
}
|
||||
|
||||
// EFITargetUKI builds the default EFI UKI target.
|
||||
func EFITargetUKI(device string, extra *Target) *Target {
|
||||
target := &Target{
|
||||
FormatOptions: partition.NewFormatOptions(constants.EFIPartitionLabel),
|
||||
Options: partition.NewPartitionOptions(constants.EFIPartitionLabel, true),
|
||||
Device: device,
|
||||
}
|
||||
|
||||
@ -109,6 +120,7 @@ func EFITarget(device string, extra *Target) *Target {
|
||||
func BIOSTarget(device string, extra *Target) *Target {
|
||||
target := &Target{
|
||||
FormatOptions: partition.NewFormatOptions(constants.BIOSGrubPartitionLabel),
|
||||
Options: partition.NewPartitionOptions(constants.BIOSGrubPartitionLabel, false),
|
||||
Device: device,
|
||||
LegacyBIOSBootable: true,
|
||||
}
|
||||
@ -120,6 +132,7 @@ func BIOSTarget(device string, extra *Target) *Target {
|
||||
func BootTarget(device string, extra *Target) *Target {
|
||||
target := &Target{
|
||||
FormatOptions: partition.NewFormatOptions(constants.BootPartitionLabel),
|
||||
Options: partition.NewPartitionOptions(constants.BootPartitionLabel, false),
|
||||
Device: device,
|
||||
}
|
||||
|
||||
@ -130,6 +143,7 @@ func BootTarget(device string, extra *Target) *Target {
|
||||
func MetaTarget(device string, extra *Target) *Target {
|
||||
target := &Target{
|
||||
FormatOptions: partition.NewFormatOptions(constants.MetaPartitionLabel),
|
||||
Options: partition.NewPartitionOptions(constants.MetaPartitionLabel, false),
|
||||
Device: device,
|
||||
}
|
||||
|
||||
@ -140,6 +154,7 @@ func MetaTarget(device string, extra *Target) *Target {
|
||||
func StateTarget(device string, extra *Target) *Target {
|
||||
target := &Target{
|
||||
FormatOptions: partition.NewFormatOptions(constants.StatePartitionLabel),
|
||||
Options: partition.NewPartitionOptions(constants.StatePartitionLabel, false),
|
||||
Device: device,
|
||||
}
|
||||
|
||||
@ -150,6 +165,7 @@ func StateTarget(device string, extra *Target) *Target {
|
||||
func EphemeralTarget(device string, extra *Target) *Target {
|
||||
target := &Target{
|
||||
FormatOptions: partition.NewFormatOptions(constants.EphemeralPartitionLabel),
|
||||
Options: partition.NewPartitionOptions(constants.EphemeralPartitionLabel, false),
|
||||
Device: device,
|
||||
}
|
||||
|
||||
@ -179,24 +195,21 @@ func (t *Target) String() string {
|
||||
|
||||
// Locate existing partition on the disk.
|
||||
func (t *Target) Locate(pt *gpt.GPT) (*gpt.Partition, error) {
|
||||
for _, part := range pt.Partitions().Items() {
|
||||
if part.Name == t.Label {
|
||||
var err error
|
||||
|
||||
t.PartitionName, err = part.Path()
|
||||
if err != nil {
|
||||
return part, err
|
||||
}
|
||||
|
||||
return part, nil
|
||||
}
|
||||
part, err := partition.Locate(pt, t.Label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
t.PartitionName, err = part.Path()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return part, nil
|
||||
}
|
||||
|
||||
// Partition creates a new partition on the specified device.
|
||||
func (t *Target) Partition(pt *gpt.GPT, pos int, bd *blockdevice.BlockDevice) (err error) {
|
||||
// partition creates a new partition on the specified device.
|
||||
func (t *Target) partition(pt *gpt.GPT, pos int) (err error) {
|
||||
if t.Skip {
|
||||
part := pt.Partitions().FindByName(t.Label)
|
||||
if part != nil {
|
||||
@ -211,32 +224,17 @@ func (t *Target) Partition(pt *gpt.GPT, pos int, bd *blockdevice.BlockDevice) (e
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("partitioning %s - %s %q\n", t.Device, t.Label, humanize.Bytes(t.Size))
|
||||
|
||||
opts := []gpt.PartitionOption{
|
||||
gpt.WithPartitionType(t.PartitionType),
|
||||
gpt.WithPartitionName(t.Label),
|
||||
}
|
||||
|
||||
if t.Size == 0 {
|
||||
opts = append(opts, gpt.WithMaximumSize(true))
|
||||
}
|
||||
|
||||
if t.LegacyBIOSBootable {
|
||||
opts = append(opts, gpt.WithLegacyBIOSBootableAttribute(true))
|
||||
}
|
||||
|
||||
part, err := pt.InsertAt(pos, t.Size, opts...)
|
||||
partitionName, err := partition.Partition(pt, pos, t.Device, partition.Options{
|
||||
PartitionLabel: t.Label,
|
||||
PartitionType: t.PartitionType,
|
||||
Size: t.Size,
|
||||
LegacyBIOSBootable: t.LegacyBIOSBootable,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.PartitionName, err = part.Path()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("created %s (%s) size %d blocks", t.PartitionName, t.Label, part.Length())
|
||||
t.PartitionName = partitionName
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -1069,11 +1069,13 @@ func partitionAndFormatDisks(logger *log.Logger, r runtime.Runtime) error {
|
||||
extraTarget := &installer.Target{
|
||||
Device: disk.Device(),
|
||||
FormatOptions: &partition.FormatOptions{
|
||||
Size: part.Size(),
|
||||
Force: true,
|
||||
PartitionType: partition.LinuxFilesystemData,
|
||||
FileSystemType: partition.FilesystemTypeXFS,
|
||||
},
|
||||
Options: &partition.Options{
|
||||
Size: part.Size(),
|
||||
PartitionType: partition.LinuxFilesystemData,
|
||||
},
|
||||
}
|
||||
|
||||
m.Targets[disk.Device()] = append(m.Targets[disk.Device()], extraTarget)
|
||||
|
@ -33,6 +33,10 @@ const (
|
||||
EFISize = 100 * MiB
|
||||
BIOSGrubSize = 1 * MiB
|
||||
BootSize = 1000 * MiB
|
||||
MetaSize = 1 * MiB
|
||||
StateSize = 100 * MiB
|
||||
// EFIUKISize is the size of the EFI partition when UKI is enabled.
|
||||
// With UKI all assets are stored in the EFI partition.
|
||||
// This is the size of the old EFISize + BIOSGrubSize + BootSize.
|
||||
EFIUKISize = EFISize + BIOSGrubSize + BootSize
|
||||
MetaSize = 1 * MiB
|
||||
StateSize = 100 * MiB
|
||||
)
|
||||
|
@ -18,20 +18,13 @@ import (
|
||||
// FormatOptions contains format parameters.
|
||||
type FormatOptions struct {
|
||||
Label string
|
||||
PartitionType Type
|
||||
FileSystemType FileSystemType
|
||||
Size uint64
|
||||
Force bool
|
||||
}
|
||||
|
||||
// NewFormatOptions creates a new format options.
|
||||
func NewFormatOptions(label string) *FormatOptions {
|
||||
opts, ok := systemPartitions[label]
|
||||
if ok {
|
||||
return &opts
|
||||
}
|
||||
|
||||
return nil
|
||||
return systemPartitionsFormatOptions(label)
|
||||
}
|
||||
|
||||
// Format zeroes the device and formats it using filesystem type provided.
|
||||
@ -69,47 +62,45 @@ func zeroPartition(devname string) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
var systemPartitions = map[string]FormatOptions{
|
||||
constants.EFIPartitionLabel: {
|
||||
Label: constants.EFIPartitionLabel,
|
||||
PartitionType: EFISystemPartition,
|
||||
FileSystemType: FilesystemTypeVFAT,
|
||||
Size: EFISize,
|
||||
Force: true,
|
||||
},
|
||||
constants.BIOSGrubPartitionLabel: {
|
||||
Label: constants.BIOSGrubPartitionLabel,
|
||||
PartitionType: BIOSBootPartition,
|
||||
FileSystemType: FilesystemTypeNone,
|
||||
Size: BIOSGrubSize,
|
||||
Force: true,
|
||||
},
|
||||
constants.BootPartitionLabel: {
|
||||
Label: constants.BootPartitionLabel,
|
||||
PartitionType: LinuxFilesystemData,
|
||||
FileSystemType: FilesystemTypeXFS,
|
||||
Size: BootSize,
|
||||
Force: true,
|
||||
},
|
||||
constants.MetaPartitionLabel: {
|
||||
Label: constants.MetaPartitionLabel,
|
||||
PartitionType: LinuxFilesystemData,
|
||||
FileSystemType: FilesystemTypeNone,
|
||||
Size: MetaSize,
|
||||
Force: true,
|
||||
},
|
||||
constants.StatePartitionLabel: {
|
||||
Label: constants.StatePartitionLabel,
|
||||
PartitionType: LinuxFilesystemData,
|
||||
FileSystemType: FilesystemTypeXFS,
|
||||
Size: StateSize,
|
||||
Force: true,
|
||||
},
|
||||
constants.EphemeralPartitionLabel: {
|
||||
Label: constants.EphemeralPartitionLabel,
|
||||
PartitionType: LinuxFilesystemData,
|
||||
FileSystemType: FilesystemTypeXFS,
|
||||
Size: 0,
|
||||
Force: true,
|
||||
},
|
||||
func systemPartitionsFormatOptions(label string) *FormatOptions {
|
||||
switch label {
|
||||
case constants.EFIPartitionLabel:
|
||||
return &FormatOptions{
|
||||
Label: constants.EFIPartitionLabel,
|
||||
FileSystemType: FilesystemTypeVFAT,
|
||||
Force: true,
|
||||
}
|
||||
case constants.BIOSGrubPartitionLabel:
|
||||
return &FormatOptions{
|
||||
Label: constants.BIOSGrubPartitionLabel,
|
||||
FileSystemType: FilesystemTypeNone,
|
||||
Force: true,
|
||||
}
|
||||
case constants.BootPartitionLabel:
|
||||
return &FormatOptions{
|
||||
Label: constants.BootPartitionLabel,
|
||||
FileSystemType: FilesystemTypeXFS,
|
||||
Force: true,
|
||||
}
|
||||
case constants.MetaPartitionLabel:
|
||||
return &FormatOptions{
|
||||
Label: constants.MetaPartitionLabel,
|
||||
FileSystemType: FilesystemTypeNone,
|
||||
Force: true,
|
||||
}
|
||||
case constants.StatePartitionLabel:
|
||||
return &FormatOptions{
|
||||
Label: constants.StatePartitionLabel,
|
||||
FileSystemType: FilesystemTypeXFS,
|
||||
Force: true,
|
||||
}
|
||||
case constants.EphemeralPartitionLabel:
|
||||
return &FormatOptions{
|
||||
Label: constants.EphemeralPartitionLabel,
|
||||
FileSystemType: FilesystemTypeXFS,
|
||||
Force: true,
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -4,3 +4,120 @@
|
||||
|
||||
// Package partition provides common utils for system partition format.
|
||||
package partition
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/siderolabs/go-blockdevice/blockdevice/partition/gpt"
|
||||
|
||||
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||
)
|
||||
|
||||
// Options contains the options for creating a partition.
|
||||
type Options struct {
|
||||
PartitionLabel string
|
||||
PartitionType Type
|
||||
Size uint64
|
||||
LegacyBIOSBootable bool
|
||||
}
|
||||
|
||||
// NewPartitionOptions returns a new PartitionOptions.
|
||||
func NewPartitionOptions(label string, uki bool) *Options {
|
||||
return systemPartitionsPartitonOptions(label, uki)
|
||||
}
|
||||
|
||||
// Locate existing partition on the disk by label.
|
||||
func Locate(pt *gpt.GPT, label string) (*gpt.Partition, error) {
|
||||
for _, part := range pt.Partitions().Items() {
|
||||
if part.Name == label {
|
||||
return part, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Partition creates a new partition on the specified device.
|
||||
// Returns the path to the newly created partition.
|
||||
func Partition(pt *gpt.GPT, pos int, device string, partitionOpts Options) (string, error) {
|
||||
log.Printf("partitioning %s - %s %q\n", device, partitionOpts.PartitionLabel, humanize.Bytes(partitionOpts.Size))
|
||||
|
||||
opts := []gpt.PartitionOption{
|
||||
gpt.WithPartitionType(partitionOpts.PartitionType),
|
||||
gpt.WithPartitionName(partitionOpts.PartitionLabel),
|
||||
}
|
||||
|
||||
if partitionOpts.Size == 0 {
|
||||
opts = append(opts, gpt.WithMaximumSize(true))
|
||||
}
|
||||
|
||||
if partitionOpts.LegacyBIOSBootable {
|
||||
opts = append(opts, gpt.WithLegacyBIOSBootableAttribute(true))
|
||||
}
|
||||
|
||||
part, err := pt.InsertAt(pos, partitionOpts.Size, opts...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
partitionName, err := part.Path()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Printf("created %s (%s) size %d blocks", partitionName, partitionOpts.PartitionLabel, part.Length())
|
||||
|
||||
return partitionName, nil
|
||||
}
|
||||
|
||||
func systemPartitionsPartitonOptions(label string, uki bool) *Options {
|
||||
switch label {
|
||||
case constants.EFIPartitionLabel:
|
||||
partitionOptions := &Options{
|
||||
PartitionType: EFISystemPartition,
|
||||
Size: EFISize,
|
||||
}
|
||||
|
||||
if uki {
|
||||
partitionOptions.Size = EFIUKISize
|
||||
}
|
||||
|
||||
return partitionOptions
|
||||
case constants.BIOSGrubPartitionLabel:
|
||||
if uki {
|
||||
panic("BIOS partition is not supported with UKI")
|
||||
}
|
||||
|
||||
return &Options{
|
||||
PartitionType: BIOSBootPartition,
|
||||
Size: BIOSGrubSize,
|
||||
}
|
||||
case constants.BootPartitionLabel:
|
||||
if uki {
|
||||
panic("BOOT partition is not supported with UKI")
|
||||
}
|
||||
|
||||
return &Options{
|
||||
PartitionType: LinuxFilesystemData,
|
||||
Size: BootSize,
|
||||
}
|
||||
case constants.MetaPartitionLabel:
|
||||
return &Options{
|
||||
PartitionType: LinuxFilesystemData,
|
||||
Size: MetaSize,
|
||||
}
|
||||
case constants.StatePartitionLabel:
|
||||
return &Options{
|
||||
PartitionType: LinuxFilesystemData,
|
||||
Size: StateSize,
|
||||
}
|
||||
case constants.EphemeralPartitionLabel:
|
||||
return &Options{
|
||||
PartitionType: LinuxFilesystemData,
|
||||
Size: 0,
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user