Skip to content

Commit

Permalink
gadget: prevent failures when updating kernel/gadget on UC16/18
Browse files Browse the repository at this point in the history
Make sure that kernel/gadget updates on UC16/18 do not fail even in
the case that the gadget volumes do not match the installed disk. This
fixes a regression in behavior due to DiskTraitsFromDeviceAndValidate
now checking compatibility with the disk, which was happening in a
later stage in the past.
  • Loading branch information
alfonsosanchezbeato committed Oct 26, 2023
1 parent ae1b5b1 commit 8a80f03
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
4 changes: 4 additions & 0 deletions gadget/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,10 @@ func buildNewVolumeToDeviceMapping(mod Model, old GadgetData, vols map[string]*V

traits, err := DiskTraitsFromDeviceAndValidate(vol, dev, validateOpts)
if err != nil {
if isPreUC20 {
logger.Noticef("WARNING: not applying gadget asset updates on main system-boot volume due to error while finding disk traits: %v", err)
return nil, errSkipUpdateProceedRefresh
}
return nil, err
}

Expand Down
56 changes: 56 additions & 0 deletions gadget/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5215,6 +5215,62 @@ func (u *updateTestSuite) TestBuildNewVolumeToDeviceMappingPreUC20NonFatalError(
c.Assert(err, Not(Equals), gadget.ErrSkipUpdateProceedRefresh)
}

func (u *updateTestSuite) TestBuildNewVolumeToDeviceMappingPreUC20CannotMap(c *C) {
fmt.Println("TestBuildNewVolumeToDeviceMappingPreUC20CannotMap")
defer fmt.Println("TestBuildNewVolumeToDeviceMappingPreUC20CannotMap")
mockLogBuf, restore := logger.MockLogger()
defer restore()

allLaidOutVolumes, err := gadgettest.LayoutMultiVolumeFromYaml(c.MkDir(), "", gadgettest.UC16YAMLImplicitSystemData, uc16Model)
c.Assert(err, IsNil)

old := gadget.GadgetData{
Info: &gadget.Info{
Volumes: make(map[string]*gadget.Volume),
},
}

for volName, laidOutVol := range allLaidOutVolumes {
old.Info.Volumes[volName] = laidOutVol.Volume
}

// setup symlink for the system-boot partition
err = os.MkdirAll(filepath.Join(dirs.GlobalRootDir, "/dev/disk/by-partlabel"), 0755)
c.Assert(err, IsNil)
fakedevicepart := filepath.Join(dirs.GlobalRootDir, "/dev/vda1")
err = os.Symlink(fakedevicepart, filepath.Join(dirs.GlobalRootDir, "/dev/disk/by-partlabel", disks.BlkIDEncodeLabel("EFI System")))
c.Assert(err, IsNil)
err = os.WriteFile(fakedevicepart, nil, 0644)
c.Assert(err, IsNil)

// mock the partition device node to mock disk
restore = disks.MockPartitionDeviceNodeToDiskMapping(map[string]*disks.MockDiskMapping{
filepath.Join(dirs.GlobalRootDir, "/dev/vda1"): gadgettest.VMSystemVolumeDiskMapping,
})
defer restore()

// and the device name to the disk itself
restore = disks.MockDeviceNameToDiskMapping(map[string]*disks.MockDiskMapping{
"/dev/vda": gadgettest.VMSystemVolumeDiskMapping,
})
defer restore()

vols := map[string]*gadget.Volume{}
for name, lov := range allLaidOutVolumes {
vols[name] = lov.Volume
}

// The call will fail as it won't find a match between /dev/vda2 and
// any partition defined in the gadget. But it is ok for UC16/18.
_, err = gadget.BuildNewVolumeToDeviceMapping(uc16Model, old, vols)
c.Assert(err, Equals, gadget.ErrSkipUpdateProceedRefresh)
c.Assert(mockLogBuf.String(), testutil.Contains, "WARNING: not applying gadget asset updates on main system-boot volume due to error while finding disk traits")

// it's a fatal error on UC20 though
_, err = gadget.BuildNewVolumeToDeviceMapping(uc20Model, old, vols)
c.Assert(err, Not(Equals), gadget.ErrSkipUpdateProceedRefresh)
}

func (u *updateTestSuite) TestBuildNewVolumeToDeviceMappingUC20MultiVolume(c *C) {
allLaidOutVolumes, err := gadgettest.LayoutMultiVolumeFromYaml(c.MkDir(), "", gadgettest.MultiVolumeUC20GadgetYaml, uc20Model)
c.Assert(err, IsNil)
Expand Down

0 comments on commit 8a80f03

Please sign in to comment.