Skip to content

Commit 399240b

Browse files
committed
feat: drop partitions on reset with system partitions wipe
When resetting+wiping system partitions (`talosctl reset --system-labels-to-wipe ...`), also drop partitions. This enables usecases such as relocating EPHEMERAL, etc. with a new machine config. Signed-off-by: Laura Brehm <laurabrehm@hey.com>
1 parent 5cca966 commit 399240b

File tree

1 file changed

+54
-8
lines changed

1 file changed

+54
-8
lines changed

internal/pkg/partition/wipe.go

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"github.com/siderolabs/go-blockdevice/v2/block"
13+
"github.com/siderolabs/go-blockdevice/v2/partitioning/gpt"
1314

1415
blockres "github.com/siderolabs/talos/pkg/machinery/resources/block"
1516
)
@@ -19,6 +20,8 @@ type VolumeWipeTarget struct {
1920
label string
2021

2122
parentDevName, devName string
23+
24+
partitionIndex int // partitionIndex is 1-based, but decrement before using
2225
}
2326

2427
// VolumeWipeTargetFromVolumeStatus creates a new VolumeWipeTarget from a VolumeStatus.
@@ -30,9 +33,10 @@ func VolumeWipeTargetFromVolumeStatus(vs *blockres.VolumeStatus) *VolumeWipeTarg
3033
}
3134

3235
return &VolumeWipeTarget{
33-
label: vs.Metadata().ID(),
34-
parentDevName: parentDevName,
35-
devName: vs.TypedSpec().Location,
36+
label: vs.Metadata().ID(),
37+
parentDevName: parentDevName,
38+
devName: vs.TypedSpec().Location,
39+
partitionIndex: vs.TypedSpec().PartitionIndex,
3640
}
3741
}
3842

@@ -45,9 +49,10 @@ func VolumeWipeTargetFromDiscoveredVolume(dv *blockres.DiscoveredVolume) *Volume
4549
}
4650

4751
return &VolumeWipeTarget{
48-
label: dv.TypedSpec().PartitionLabel,
49-
parentDevName: parentDevName,
50-
devName: dv.TypedSpec().DevPath,
52+
label: dv.TypedSpec().PartitionLabel,
53+
parentDevName: parentDevName,
54+
devName: dv.TypedSpec().DevPath,
55+
partitionIndex: int(dv.TypedSpec().PartitionIndex),
5156
}
5257
}
5358

@@ -62,8 +67,9 @@ func (v *VolumeWipeTarget) String() string {
6267
}
6368

6469
// Wipe implements runtime.PartitionTarget.
70+
// Asides from wiping the device, Wipe() also drops the partition.
6571
func (v *VolumeWipeTarget) Wipe(ctx context.Context, log func(string, ...any)) error {
66-
parentBd, err := block.NewFromPath(v.parentDevName)
72+
parentBd, err := block.NewFromPath(v.parentDevName, block.OpenForWrite())
6773
if err != nil {
6874
return fmt.Errorf("error opening block device %q: %w", v.parentDevName, err)
6975
}
@@ -76,14 +82,54 @@ func (v *VolumeWipeTarget) Wipe(ctx context.Context, log func(string, ...any)) e
7682

7783
defer parentBd.Unlock() //nolint:errcheck
7884

85+
if err := v.wipeWithParentLocked(log); err != nil {
86+
return fmt.Errorf("error wiping device %q: %w", v.devName, err)
87+
}
88+
89+
if parentBd == nil || v.partitionIndex == 0 {
90+
return fmt.Errorf("missing parent block device or partition index")
91+
}
92+
93+
if err := v.dropWithParentLocked(parentBd, log); err != nil {
94+
return fmt.Errorf("error dropping partition: %w", err)
95+
}
96+
97+
return nil
98+
}
99+
100+
func (v *VolumeWipeTarget) wipeWithParentLocked(log func(string, ...any)) error {
79101
bd, err := block.NewFromPath(v.devName, block.OpenForWrite())
80102
if err != nil {
81103
return fmt.Errorf("error opening block device %q: %w", v.devName, err)
82104
}
83105

84106
defer bd.Close() //nolint:errcheck
85107

86-
log("wiping the volume %q (%s)", v.GetLabel(), v.devName)
108+
log("wiping volume %q (%s)", v.GetLabel(), v.devName)
87109

88110
return bd.FastWipe()
89111
}
112+
113+
func (v *VolumeWipeTarget) dropWithParentLocked(parentBd *block.Device, log func(string, ...any)) error {
114+
log("dropping partition %d from device %q", v.partitionIndex, v.parentDevName)
115+
116+
gptdev, err := gpt.DeviceFromBlockDevice(parentBd)
117+
if err != nil {
118+
return fmt.Errorf("failed to get GPT device: %w", err)
119+
}
120+
121+
pt, err := gpt.Read(gptdev)
122+
if err != nil {
123+
return fmt.Errorf("failed to read GPT table: %w", err)
124+
}
125+
126+
if err = pt.DeletePartition(v.partitionIndex - 1); err != nil {
127+
return fmt.Errorf("failed to delete partition: %w", err)
128+
}
129+
130+
if err = pt.Write(); err != nil {
131+
return fmt.Errorf("failed to write GPT table: %w", err)
132+
}
133+
134+
return nil
135+
}

0 commit comments

Comments
 (0)