Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/common/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ var (
// partition
ErrReuseByLabel = errors.New("partitions cannot be reused by label; number must be specified except on boot disk (/dev/disk/by-id/coreos-boot-disk) or when wipe_table is true")
ErrWrongPartitionNumber = errors.New("incorrect partition number; a new partition will be created using reserved label")
ErrRootTooSmall = errors.New("root should have 8GiB of space assigned")
ErrRootConstrained = errors.New("root partition cannot expand; it is set to fill available space but is followed by an auto-positioned partition")

// MachineConfigs
ErrFieldElided = errors.New("field ignored in raw mode")
Expand Down
32 changes: 25 additions & 7 deletions config/fcos/v1_3/translate.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,34 @@ func (c Config) ToIgn3_2Unvalidated(options common.TranslateOptions) (types.Conf
}
r.Merge(c.processBootDevice(&ret, &ts, options))
for i, disk := range ret.Storage.Disks {
// In the boot_device.mirror case, nothing specifies partition numbers
// so match existing partitions only when `wipeTable` is false
if !util.IsTrue(disk.WipeTable) {
for j, partition := range disk.Partitions {
// check for reserved partlabels
if partition.Label != nil {
for p, partition := range disk.Partitions {
// check for root partition size constraints
if partition.Label != nil {
if *partition.Label == "root" {
if partition.SizeMiB == nil || *partition.SizeMiB == 0 {
for idx := range disk.Partitions {
if idx == p {
continue
}
if disk.Partitions[idx].StartMiB == nil || *disk.Partitions[idx].StartMiB == 0 {
r.AddOnWarn(path.New("json", "storage", "disks", i, "partitions", p, "label"), common.ErrRootConstrained)
break
}
}
} else if *partition.SizeMiB < 8192 {
r.AddOnWarn(path.New("json", "storage", "disks", i, "partitions", p, "size_mib"), common.ErrRootTooSmall)
}
}

// In the boot_device.mirror case, nothing specifies partition numbers
// so match existing partitions only when `wipeTable` is false
if !util.IsTrue(disk.WipeTable) {
// check for reserved partlabels
if (*partition.Label == "BIOS-BOOT" && partition.Number != 1) || (*partition.Label == "PowerPC-PReP-boot" && partition.Number != 1) || (*partition.Label == "EFI-SYSTEM" && partition.Number != 2) || (*partition.Label == "boot" && partition.Number != 3) || (*partition.Label == "root" && partition.Number != 4) {
r.AddOnWarn(path.New("json", "storage", "disks", i, "partitions", j, "label"), common.ErrWrongPartitionNumber)
r.AddOnWarn(path.New("json", "storage", "disks", i, "partitions", p, "label"), common.ErrWrongPartitionNumber)
}
}

}
}
}
Expand Down
239 changes: 239 additions & 0 deletions config/fcos/v1_3/translate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1423,3 +1423,242 @@ func TestTranslateBootDevice(t *testing.T) {
})
}
}

func TestRootPartitionConstraints(t *testing.T) {
tests := []struct {
name string
in Config
report report.Report
}{
{
name: "root constrained by auto-positioned partition",
in: Config{
Config: base.Config{
Storage: base.Storage{
Disks: []base.Disk{
{
Device: "/dev/vda",
Partitions: []base.Partition{
{
Label: util.StrToPtr("root"),
Number: 4,
SizeMiB: util.IntToPtr(0), // fill available
},
{
Label: util.StrToPtr("data"),
StartMiB: util.IntToPtr(0), // auto-positioned - will be placed after root
},
},
},
},
},
},
},
report: report.Report{
Entries: []report.Entry{
{
Kind: report.Warn,
Message: common.ErrRootConstrained.Error(),
Context: path.New("yaml", "storage", "disks", 0, "partitions", 0, "label"),
},
},
},
},
{
name: "root constrained by auto-positioned partition with explicit root start",
in: Config{
Config: base.Config{
Storage: base.Storage{
Disks: []base.Disk{
{
Device: "/dev/vda",
Partitions: []base.Partition{
{
Label: util.StrToPtr("root"),
Number: 4,
SizeMiB: util.IntToPtr(0), // fill available
StartMiB: util.IntToPtr(2048),
},
{
Label: util.StrToPtr("var"),
StartMiB: util.IntToPtr(0), // auto-positioned - constrains root
},
},
},
},
},
},
},
report: report.Report{
Entries: []report.Entry{
{
Kind: report.Warn,
Message: common.ErrRootConstrained.Error(),
Context: path.New("yaml", "storage", "disks", 0, "partitions", 0, "label"),
},
},
},
},
// Root partition NOT constrained because next partition has explicit StartMiB
{
name: "root not constrained with explicit StartMiB after",
in: Config{
Config: base.Config{
Storage: base.Storage{
Disks: []base.Disk{
{
Device: "/dev/vda",
Partitions: []base.Partition{
{
Label: util.StrToPtr("root"),
Number: 4,
SizeMiB: util.IntToPtr(0), // fill available
StartMiB: util.IntToPtr(2048),
},
{
Label: util.StrToPtr("data"),
StartMiB: util.IntToPtr(10240), // explicit position - does NOT constrain root
},
},
},
},
},
},
},
report: report.Report{},
},
// Root partition constrained by auto-positioned partition even when
// an explicit partition is also present
{
name: "root constrained by auto-positioned partition with explicit also present",
in: Config{
Config: base.Config{
Storage: base.Storage{
Disks: []base.Disk{
{
Device: "/dev/vda",
Partitions: []base.Partition{
{
Label: util.StrToPtr("root"),
Number: 4,
SizeMiB: util.IntToPtr(0), // fill available
StartMiB: util.IntToPtr(2048),
},
{
Label: util.StrToPtr("var"),
StartMiB: util.IntToPtr(0), // auto-positioned - constrains root
},
{
Label: util.StrToPtr("data"),
StartMiB: util.IntToPtr(10240), // explicit position
},
},
},
},
},
},
},
report: report.Report{
Entries: []report.Entry{
{
Kind: report.Warn,
Message: common.ErrRootConstrained.Error(),
Context: path.New("yaml", "storage", "disks", 0, "partitions", 0, "label"),
},
},
},
},
{
name: "root partition too small",
in: Config{
Config: base.Config{
Storage: base.Storage{
Disks: []base.Disk{
{
Device: "/dev/vda",
Partitions: []base.Partition{
{
Label: util.StrToPtr("root"),
Number: 4,
SizeMiB: util.IntToPtr(4096),
},
},
},
},
},
},
},
report: report.Report{
Entries: []report.Entry{
{
Kind: report.Warn,
Message: common.ErrRootTooSmall.Error(),
Context: path.New("json", "storage", "disks", 0, "partitions", 0, "size_mib"),
},
},
},
},
{
name: "root partition exactly 8GiB",
in: Config{
Config: base.Config{
Storage: base.Storage{
Disks: []base.Disk{
{
Device: "/dev/vda",
Partitions: []base.Partition{
{
Label: util.StrToPtr("root"),
Number: 4,
SizeMiB: util.IntToPtr(8192),
},
},
},
},
},
},
},
report: report.Report{},
},
{
name: "root constrained with nil sizeMiB and nil startMiB",
in: Config{
Config: base.Config{
Storage: base.Storage{
Disks: []base.Disk{
{
Device: "/dev/vda",
Partitions: []base.Partition{
{
Label: util.StrToPtr("root"),
Number: 4,
},
{
Label: util.StrToPtr("data"),
},
},
},
},
},
},
},
report: report.Report{
Entries: []report.Entry{
{
Kind: report.Warn,
Message: common.ErrRootConstrained.Error(),
Context: path.New("yaml", "storage", "disks", 0, "partitions", 0, "label"),
},
},
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
_, translations, r := test.in.ToIgn3_2Unvalidated(common.TranslateOptions{})
r = confutil.TranslateReportPaths(r, translations)
assert.Equal(t, test.report, r, "report mismatch")
})
}
}
32 changes: 25 additions & 7 deletions config/fcos/v1_4/translate.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,34 @@ func (c Config) ToIgn3_3Unvalidated(options common.TranslateOptions) (types.Conf
}
r.Merge(c.processBootDevice(&ret, &ts, options))
for i, disk := range ret.Storage.Disks {
// In the boot_device.mirror case, nothing specifies partition numbers
// so match existing partitions only when `wipeTable` is false
if !util.IsTrue(disk.WipeTable) {
for j, partition := range disk.Partitions {
// check for reserved partlabels
if partition.Label != nil {
for p, partition := range disk.Partitions {
// check for root partition size constraints
if partition.Label != nil {
if *partition.Label == "root" {
if partition.SizeMiB == nil || *partition.SizeMiB == 0 {
for idx := range disk.Partitions {
if idx == p {
continue
}
if disk.Partitions[idx].StartMiB == nil || *disk.Partitions[idx].StartMiB == 0 {
r.AddOnWarn(path.New("json", "storage", "disks", i, "partitions", p, "label"), common.ErrRootConstrained)
break
}
}
} else if *partition.SizeMiB < 8192 {
r.AddOnWarn(path.New("json", "storage", "disks", i, "partitions", p, "size_mib"), common.ErrRootTooSmall)
}
}

// In the boot_device.mirror case, nothing specifies partition numbers
// so match existing partitions only when `wipeTable` is false
if !util.IsTrue(disk.WipeTable) {
// check for reserved partlabels
if (*partition.Label == "BIOS-BOOT" && partition.Number != 1) || (*partition.Label == "PowerPC-PReP-boot" && partition.Number != 1) || (*partition.Label == "EFI-SYSTEM" && partition.Number != 2) || (*partition.Label == "boot" && partition.Number != 3) || (*partition.Label == "root" && partition.Number != 4) {
r.AddOnWarn(path.New("json", "storage", "disks", i, "partitions", j, "label"), common.ErrWrongPartitionNumber)
r.AddOnWarn(path.New("json", "storage", "disks", i, "partitions", p, "label"), common.ErrWrongPartitionNumber)
}
}

}
}
}
Expand Down
Loading
Loading