From 78a5b217bc278997e81a2a9f2ef403ec56fdb7a1 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Mon, 30 Sep 2024 17:21:35 +0200 Subject: [PATCH] gadget: Add a MaxSize method to Volume This method is needed to determine the size of the disk image to create in ubuntu-image. Signed-off-by: Paul Mars --- gadget/gadget.go | 24 ++++++++++++++++---- gadget/gadget_test.go | 53 +++++++++++++++++++++++++++++++------------ 2 files changed, 58 insertions(+), 19 deletions(-) diff --git a/gadget/gadget.go b/gadget/gadget.go index 05d226fbc5b..2c2b0962f13 100644 --- a/gadget/gadget.go +++ b/gadget/gadget.go @@ -185,21 +185,35 @@ func (v *Volume) HasPartial(pp PartialProperty) bool { return false } -// MinSize returns the minimum size required by a volume, as implicitly -// defined by the size structures. It assumes sorted structures. -func (v *Volume) MinSize() quantity.Size { +// size returns the size of the volume using the structureSizer function to calculate +// structures size. It assumes sorted structures. +func (v *Volume) size(structureSizer func(VolumeStructure) quantity.Size) quantity.Size { endVol := quantity.Offset(0) for _, s := range v.Structure { if s.Offset != nil { - endVol = *s.Offset + quantity.Offset(s.MinSize) + endVol = *s.Offset + quantity.Offset(structureSizer(s)) } else { - endVol += quantity.Offset(s.MinSize) + endVol += quantity.Offset(structureSizer(s)) } } return quantity.Size(endVol) } +// MinSize returns the minimum size required by a volume. +func (v *Volume) MinSize() quantity.Size { + return v.size(func(s VolumeStructure) quantity.Size { + return s.MinSize + }) +} + +// MaxSize returns the maximum size required by a volume. +func (v *Volume) MaxSize() quantity.Size { + return v.size(func(s VolumeStructure) quantity.Size { + return s.Size + }) +} + // StructFromYamlIndex returns the structure defined at a given yaml index from // the original yaml file. func (v *Volume) StructFromYamlIndex(yamlIdx int) *VolumeStructure { diff --git a/gadget/gadget_test.go b/gadget/gadget_test.go index bd0d4f104c4..4ca73a0d0c9 100644 --- a/gadget/gadget_test.go +++ b/gadget/gadget_test.go @@ -4425,69 +4425,94 @@ kernel-cmdline: } } -func (s *gadgetYamlTestSuite) testVolumeMinSize(c *C, gadgetYaml []byte, volSizes map[string]quantity.Size) { +func (s *gadgetYamlTestSuite) testVolumeSize(c *C, gadgetYaml []byte, volSizes map[string]quantity.Size, volumeSizer func(*gadget.Volume) quantity.Size) { ginfo, err := gadget.InfoFromGadgetYaml(gadgetYaml, nil) c.Assert(err, IsNil) c.Assert(len(ginfo.Volumes), Equals, len(volSizes)) for k, v := range ginfo.Volumes { c.Logf("checking size of volume %s", k) - c.Check(v.MinSize(), Equals, quantity.Size(volSizes[k])) + c.Check(volumeSizer(v), Equals, quantity.Size(volSizes[k])) } } -func (s *gadgetYamlTestSuite) TestVolumeMinSize(c *C) { +func (s *gadgetYamlTestSuite) TestVolumeSizes(c *C) { for _, tc := range []struct { - gadgetYaml []byte - volsSizes map[string]quantity.Size + gadgetYaml []byte + volsMinSizes map[string]quantity.Size + volsMaxSizes map[string]quantity.Size }{ { gadgetYaml: gadgetYamlUnorderedParts, - volsSizes: map[string]quantity.Size{ + volsMinSizes: map[string]quantity.Size{ + "myvol": 1300 * quantity.SizeMiB, + }, + volsMaxSizes: map[string]quantity.Size{ "myvol": 1300 * quantity.SizeMiB, }, }, { gadgetYaml: mockMultiVolumeUC20GadgetYaml, - volsSizes: map[string]quantity.Size{ + volsMinSizes: map[string]quantity.Size{ + "frobinator-image": (1 + 500 + 10 + 500 + 1024) * quantity.SizeMiB, + "u-boot-frobinator": 24576 + 623000, + }, + volsMaxSizes: map[string]quantity.Size{ "frobinator-image": (1 + 500 + 10 + 500 + 1024) * quantity.SizeMiB, "u-boot-frobinator": 24576 + 623000, }, }, { gadgetYaml: mockMultiVolumeGadgetYaml, - volsSizes: map[string]quantity.Size{ + volsMinSizes: map[string]quantity.Size{ + "frobinator-image": (1 + 128 + 380) * quantity.SizeMiB, + "u-boot-frobinator": 24576 + 623000, + }, + volsMaxSizes: map[string]quantity.Size{ "frobinator-image": (1 + 128 + 380) * quantity.SizeMiB, "u-boot-frobinator": 24576 + 623000, }, }, { gadgetYaml: mockVolumeUpdateGadgetYaml, - volsSizes: map[string]quantity.Size{ + volsMinSizes: map[string]quantity.Size{ + "bootloader": 12345 + 88888, + }, + volsMaxSizes: map[string]quantity.Size{ "bootloader": 12345 + 88888, }, }, { gadgetYaml: gadgetYamlPC, - volsSizes: map[string]quantity.Size{ + volsMinSizes: map[string]quantity.Size{ + "pc": (1 + 1 + 50) * quantity.SizeMiB, + }, + volsMaxSizes: map[string]quantity.Size{ "pc": (1 + 1 + 50) * quantity.SizeMiB, }, }, { gadgetYaml: gadgetYamlUC20PC, - volsSizes: map[string]quantity.Size{ + volsMinSizes: map[string]quantity.Size{ + "pc": (1 + 1 + 1200 + 750 + 16 + 1024) * quantity.SizeMiB, + }, + volsMaxSizes: map[string]quantity.Size{ "pc": (1 + 1 + 1200 + 750 + 16 + 1024) * quantity.SizeMiB, }, }, { gadgetYaml: gadgetYamlMinSizePC, - volsSizes: map[string]quantity.Size{ + volsMinSizes: map[string]quantity.Size{ "pc": (1 + 1 + 1200 + 750 + 16 + 1024) * quantity.SizeMiB, }, + volsMaxSizes: map[string]quantity.Size{ + "pc": (1 + 1 + 1200 + 750 + 32 + 1024) * quantity.SizeMiB, + }, }, } { - c.Logf("test min size for %s", tc.gadgetYaml) - s.testVolumeMinSize(c, tc.gadgetYaml, tc.volsSizes) + c.Logf("test sizes for %s", tc.gadgetYaml) + s.testVolumeSize(c, tc.gadgetYaml, tc.volsMinSizes, (*gadget.Volume).MinSize) + s.testVolumeSize(c, tc.gadgetYaml, tc.volsMaxSizes, (*gadget.Volume).MaxSize) } }