diff --git a/config/common/errors.go b/config/common/errors.go index 1961f0074..2729df854 100644 --- a/config/common/errors.go +++ b/config/common/errors.go @@ -37,6 +37,8 @@ var ( ErrNodeExists = errors.New("matching filesystem node has existing contents or different type") ErrNoFilesDir = errors.New("local file paths are relative to a files directory that must be specified with -d/--files-dir") ErrTreeNotDirectory = errors.New("root of tree must be a directory") + ErrRootTooSmall = errors.New("root should have 8GiB of space available") + ErrRootNotLastPartition = errors.New("root should be last partition number to allow for growth") ErrTreeNoLocal = errors.New("local is required") // filesystem nodes diff --git a/config/fcos/v1_5_exp/translate.go b/config/fcos/v1_5_exp/translate.go index f2eec2fd0..b566200a9 100644 --- a/config/fcos/v1_5_exp/translate.go +++ b/config/fcos/v1_5_exp/translate.go @@ -68,17 +68,28 @@ func (c Config) ToIgn3_4Unvalidated(options common.TranslateOptions) (types.Conf return types.Config{}, translate.TranslationSet{}, r } 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 { + if partition.Label != nil { + if *partition.Label == "root" { + if *partition.SizeMiB < 8192 { + r.AddOnWarn(path.New("json", "storage", "disks", i, "partitions", p, "sizeMiB", *partition.SizeMiB), common.ErrRootTooSmall) + } + for _, op := range disk.Partitions { + if op.Number > partition.Number { + r.AddOnWarn(path.New("json", "storage", "disks", i, "partitions", p, "number", partition.Number), common.ErrRootNotLastPartition) + } + } + } + // Don't warn if wipeTable is set, matching later spec versions + 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) } } + } } } diff --git a/config/fcos/v1_5_exp/translate_test.go b/config/fcos/v1_5_exp/translate_test.go index fbb3f4798..ad01a011b 100644 --- a/config/fcos/v1_5_exp/translate_test.go +++ b/config/fcos/v1_5_exp/translate_test.go @@ -146,6 +146,198 @@ func TestTranslateBootDevice(t *testing.T) { }, }, }, + // root partition too small + { + Config{ + Config: base.Config{ + Storage: base.Storage{ + Disks: []base.Disk{ + { + Device: "/dev/vda", + Partitions: []base.Partition{ + { + Label: util.StrToPtr("root"), + SizeMiB: util.IntToPtr(500), + Resize: util.BoolToPtr(true), + Number: 4, + }, + { + Label: util.StrToPtr("var-home"), + SizeMiB: util.IntToPtr(10240), + }, + }, + }, + }, + Filesystems: []base.Filesystem{ + { + Device: "/dev/disk/by-partlabel/var-home", + Format: util.StrToPtr("xfs"), + Path: util.StrToPtr("/var/home"), + Label: util.StrToPtr("var-home"), + WipeFilesystem: util.BoolToPtr(false), + }, + }, + }, + }, + }, + types.Config{ + Ignition: types.Ignition{ + Version: "3.4.0-experimental", + }, + Storage: types.Storage{ + Disks: []types.Disk{ + { + Device: "/dev/vda", + Partitions: []types.Partition{ + { + Label: util.StrToPtr("root"), + SizeMiB: util.IntToPtr(500), + Resize: util.BoolToPtr(true), + Number: 4, + }, + { + Label: util.StrToPtr("var-home"), + SizeMiB: util.IntToPtr(10240), + }, + }, + }, + }, + Filesystems: []types.Filesystem{ + { + Device: "/dev/disk/by-partlabel/var-home", + Format: util.StrToPtr("xfs"), + Path: util.StrToPtr("/var/home"), + Label: util.StrToPtr("var-home"), + WipeFilesystem: util.BoolToPtr(false), + }, + }, + }, + }, + []translate.Translation{ + {path.New("yaml", "version"), path.New("json", "ignition", "version")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 0, "label"), path.New("json", "storage", "disks", 0, "partitions", 0, "label")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 0, "size_mib"), path.New("json", "storage", "disks", 0, "partitions", 0, "sizeMiB")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 0, "resize"), path.New("json", "storage", "disks", 0, "partitions", 0, "resize")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 1, "label"), path.New("json", "storage", "disks", 0, "partitions", 1, "label")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 1, "size_mib"), path.New("json", "storage", "disks", 0, "partitions", 1, "sizeMiB")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 0), path.New("json", "storage", "disks", 0, "partitions", 0)}, + {path.New("yaml", "storage", "disks", 0), path.New("json", "storage", "disks", 0)}, + {path.New("yaml", "storage", "filesystems", 0, "device"), path.New("json", "storage", "filesystems", 0, "device")}, + {path.New("yaml", "storage", "filesystems", 0, "format"), path.New("json", "storage", "filesystems", 0, "format")}, + {path.New("yaml", "storage", "filesystems", 0, "path"), path.New("json", "storage", "filesystems", 0, "path")}, + {path.New("yaml", "storage", "filesystems", 0, "label"), path.New("json", "storage", "filesystems", 0, "label")}, + {path.New("yaml", "storage", "filesystems", 0, "wipe_filesystem"), path.New("json", "storage", "filesystems", 0, "wipeFilesystem")}, + {path.New("yaml", "storage", "filesystems", 0), path.New("json", "storage", "filesystems", 0)}, + {path.New("yaml", "storage", "filesystems"), path.New("json", "storage", "filesystems")}, + {path.New("yaml", "storage"), path.New("json", "storage")}, + }, + report.Report{ + Entries: []report.Entry{ + { + Kind: report.Warn, + Message: common.ErrRootTooSmall.Error(), + Context: path.New("json", "storage", "disks", 0, "partitions", 0, "sizeMiB", 500), + }, + }, + }, + }, + // root partition constrained + { + Config{ + Config: base.Config{ + Storage: base.Storage{ + Disks: []base.Disk{ + { + Device: "/dev/vda", + Partitions: []base.Partition{ + { + Label: util.StrToPtr("root"), + SizeMiB: util.IntToPtr(10000), + Resize: util.BoolToPtr(true), + Number: 4, + }, + { + Label: util.StrToPtr("var-home"), + SizeMiB: util.IntToPtr(10240), + Number: 5, + }, + }, + }, + }, + Filesystems: []base.Filesystem{ + { + Device: "/dev/disk/by-partlabel/var-home", + Format: util.StrToPtr("xfs"), + Path: util.StrToPtr("/var/home"), + Label: util.StrToPtr("var-home"), + WipeFilesystem: util.BoolToPtr(false), + }, + }, + }, + }, + }, + types.Config{ + Ignition: types.Ignition{ + Version: "3.4.0-experimental", + }, + Storage: types.Storage{ + Disks: []types.Disk{ + { + Device: "/dev/vda", + Partitions: []types.Partition{ + { + Label: util.StrToPtr("root"), + SizeMiB: util.IntToPtr(10000), + Resize: util.BoolToPtr(true), + Number: 4, + }, + { + Label: util.StrToPtr("var-home"), + SizeMiB: util.IntToPtr(10240), + Number: 5, + }, + }, + }, + }, + Filesystems: []types.Filesystem{ + { + Device: "/dev/disk/by-partlabel/var-home", + Format: util.StrToPtr("xfs"), + Path: util.StrToPtr("/var/home"), + Label: util.StrToPtr("var-home"), + WipeFilesystem: util.BoolToPtr(false), + }, + }, + }, + }, + []translate.Translation{ + {path.New("yaml", "version"), path.New("json", "ignition", "version")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 0, "label"), path.New("json", "storage", "disks", 0, "partitions", 0, "label")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 0, "size_mib"), path.New("json", "storage", "disks", 0, "partitions", 0, "sizeMiB")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 0, "resize"), path.New("json", "storage", "disks", 0, "partitions", 0, "resize")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 1, "label"), path.New("json", "storage", "disks", 0, "partitions", 1, "label")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 1, "size_mib"), path.New("json", "storage", "disks", 0, "partitions", 1, "sizeMiB")}, + {path.New("yaml", "storage", "disks", 0, "partitions", 0), path.New("json", "storage", "disks", 0, "partitions", 0)}, + {path.New("yaml", "storage", "disks", 0), path.New("json", "storage", "disks", 0)}, + {path.New("yaml", "storage", "filesystems", 0, "device"), path.New("json", "storage", "filesystems", 0, "device")}, + {path.New("yaml", "storage", "filesystems", 0, "format"), path.New("json", "storage", "filesystems", 0, "format")}, + {path.New("yaml", "storage", "filesystems", 0, "path"), path.New("json", "storage", "filesystems", 0, "path")}, + {path.New("yaml", "storage", "filesystems", 0, "label"), path.New("json", "storage", "filesystems", 0, "label")}, + {path.New("yaml", "storage", "filesystems", 0, "wipe_filesystem"), path.New("json", "storage", "filesystems", 0, "wipeFilesystem")}, + {path.New("yaml", "storage", "filesystems", 0), path.New("json", "storage", "filesystems", 0)}, + {path.New("yaml", "storage", "filesystems"), path.New("json", "storage", "filesystems")}, + {path.New("yaml", "storage"), path.New("json", "storage")}, + }, + report.Report{ + Entries: []report.Entry{ + { + Kind: report.Warn, + Message: common.ErrRootNotLastPartition.Error(), + Context: path.New("json", "storage", "disks", 0, "partitions", 0, "number", 4), + }, + }, + }, + }, // LUKS, x86_64 { Config{ diff --git a/docs/release-notes.md b/docs/release-notes.md index 3251467ee..cbe2c4331 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -17,7 +17,8 @@ nav_order: 9 ### Misc. changes - +- Warn on root size is too small _(fcos)_ +- Warn on root constrained by another partition _(fcos)_ ### Docs changes