From 2099cc79b949e1c4d08e7bebed5ad0a0e185a581 Mon Sep 17 00:00:00 2001 From: Maciej Borzecki Date: Wed, 23 Sep 2020 10:34:25 +0200 Subject: [PATCH 1/6] gadget: allow content observer to have opinions about a change Allow content observers to have opinions about a given change, with the ability to request the original content to be preserved. Signed-off-by: Maciej Borzecki --- gadget/update.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/gadget/update.go b/gadget/update.go index 38bc9b5c4e8..d930137d2f5 100644 --- a/gadget/update.go +++ b/gadget/update.go @@ -61,11 +61,16 @@ type ContentChange struct { } type ContentOperation int +type ContentChangeDisposition int const ( ContentWrite ContentOperation = iota ContentUpdate ContentRollback + + ChangeExecute ContentChangeDisposition = iota + ChangeAbort + ChangePreserveBefore ) // ContentObserver allows for observing operations on the content of the gadget @@ -82,8 +87,14 @@ type ContentObserver interface { // that will be written. When called during rollback, observe call // happens after the original file has been restored (or removed if the // file was added during the update), the source path is empty. + // + // Returning ChangeExecute indicates that the observer agrees for a + // given change to be executed. When called with a ContentUpdate + // operation, returning ChangePreserveBefore indicates that the 'before' + // content shall be preserved. Returning ChangeAbort is returned along + // with a non-nil error. Observe(op ContentOperation, sourceStruct *LaidOutStructure, - targetRootDir, relativeTargetPath string, dataChange *ContentChange) (bool, error) + targetRootDir, relativeTargetPath string, dataChange *ContentChange) (ContentChangeDisposition, error) } // ContentUpdateObserver allows for observing update (and potentially a From 1771b37265072d54ac39bb85d68ec17757ef8268 Mon Sep 17 00:00:00 2001 From: Maciej Borzecki Date: Wed, 23 Sep 2020 10:35:40 +0200 Subject: [PATCH 2/6] many: update content observer interface Signed-off-by: Maciej Borzecki --- boot/assets.go | 64 ++++++++++++------------ gadget/install/content_test.go | 4 +- gadget/mountedfilesystem_test.go | 8 +-- gadget/update_test.go | 4 +- tests/lib/uc20-create-partitions/main.go | 4 +- 5 files changed, 42 insertions(+), 42 deletions(-) diff --git a/boot/assets.go b/boot/assets.go index 8154f6eca3e..69ca87f3666 100644 --- a/boot/assets.go +++ b/boot/assets.go @@ -227,36 +227,36 @@ type TrustedAssetsInstallObserver struct { // of the secure boot. // // Implements gadget.ContentObserver. -func (o *TrustedAssetsInstallObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, relativeTarget string, data *gadget.ContentChange) (bool, error) { +func (o *TrustedAssetsInstallObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, relativeTarget string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { if affectedStruct.Role != gadget.SystemBoot { // only care about system-boot - return true, nil + return gadget.ChangeExecute, nil } if o.blName == "" { // we have no information about the bootloader yet bl, err := bootloader.ForGadget(o.gadgetDir, root, &bootloader.Options{Role: bootloader.RoleRunMode, NoSlashBoot: true}) if err != nil { - return false, fmt.Errorf("cannot find bootloader: %v", err) + return gadget.ChangeAbort, fmt.Errorf("cannot find bootloader: %v", err) } o.blName = bl.Name() tbl, ok := bl.(bootloader.TrustedAssetsBootloader) if !ok { - return true, nil + return gadget.ChangeExecute, nil } trustedAssets, err := tbl.TrustedAssets() if err != nil { - return false, fmt.Errorf("cannot list %q bootloader trusted assets: %v", bl.Name(), err) + return gadget.ChangeAbort, fmt.Errorf("cannot list %q bootloader trusted assets: %v", bl.Name(), err) } o.trustedAssets = trustedAssets } if len(o.trustedAssets) == 0 || !strutil.ListContains(o.trustedAssets, relativeTarget) { // not one of the trusted assets - return true, nil + return gadget.ChangeExecute, nil } ta, err := o.cache.Add(data.After, o.blName, filepath.Base(relativeTarget)) if err != nil { - return false, err + return gadget.ChangeAbort, err } // during installation, modeenv is written out later, at this point we // only care that the same file may appear multiple times in gadget @@ -266,11 +266,11 @@ func (o *TrustedAssetsInstallObserver) Observe(op gadget.ContentOperation, affec o.trackedAssets = bootAssetsMap{} } if len(o.trackedAssets[ta.name]) > 0 { - return false, fmt.Errorf("cannot reuse asset name %q", ta.name) + return gadget.ChangeAbort, fmt.Errorf("cannot reuse asset name %q", ta.name) } o.trackedAssets[ta.name] = append(o.trackedAssets[ta.name], ta.hash) } - return true, nil + return gadget.ChangeExecute, nil } // ObserveExistingTrustedRecoveryAssets observes existing trusted assets of a @@ -380,7 +380,7 @@ func findMaybeTrustedAssetsBootloader(root string, opts *bootloader.Options) (fo // the bootloader binary which is measured as part of the secure boot. // // Implements gadget.ContentUpdateObserver. -func (o *TrustedAssetsUpdateObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, relativeTarget string, data *gadget.ContentChange) (bool, error) { +func (o *TrustedAssetsUpdateObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, relativeTarget string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { var whichBootloader bootloader.Bootloader var whichAssets []string var err error @@ -394,7 +394,7 @@ func (o *TrustedAssetsUpdateObserver) Observe(op gadget.ContentOperation, affect NoSlashBoot: true, }) if err != nil { - return false, err + return gadget.ChangeAbort, err } } whichBootloader = o.bootBootloader @@ -405,7 +405,7 @@ func (o *TrustedAssetsUpdateObserver) Observe(op gadget.ContentOperation, affect Role: bootloader.RoleRecovery, }) if err != nil { - return false, err + return gadget.ChangeAbort, err } } whichBootloader = o.seedBootloader @@ -413,17 +413,17 @@ func (o *TrustedAssetsUpdateObserver) Observe(op gadget.ContentOperation, affect isRecovery = true default: // only system-seed and system-boot are of interest - return true, nil + return gadget.ChangeExecute, nil } if len(whichAssets) == 0 || !strutil.ListContains(whichAssets, relativeTarget) { // not one of the trusted assets - return true, nil + return gadget.ChangeExecute, nil } if o.modeenv == nil { // we've hit a trusted asset, so a modeenv is needed now too o.modeenv, err = ReadModeenv("") if err != nil { - return false, fmt.Errorf("cannot load modeenv: %v", err) + return gadget.ChangeAbort, fmt.Errorf("cannot load modeenv: %v", err) } } switch op { @@ -433,14 +433,14 @@ func (o *TrustedAssetsUpdateObserver) Observe(op gadget.ContentOperation, affect return o.observeRollback(whichBootloader, isRecovery, root, relativeTarget, data) default: // we only care about update and rollback actions - return false, nil + return gadget.ChangeExecute, nil } } -func (o *TrustedAssetsUpdateObserver) observeUpdate(bl bootloader.Bootloader, recovery bool, root, relativeTarget string, change *gadget.ContentChange) (bool, error) { +func (o *TrustedAssetsUpdateObserver) observeUpdate(bl bootloader.Bootloader, recovery bool, root, relativeTarget string, change *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { modeenvBefore, err := o.modeenv.Copy() if err != nil { - return false, fmt.Errorf("cannot copy modeenv: %v", err) + return gadget.ChangeAbort, fmt.Errorf("cannot copy modeenv: %v", err) } // we may be running after a mid-update reboot, where a successful boot @@ -453,13 +453,13 @@ func (o *TrustedAssetsUpdateObserver) observeUpdate(bl bootloader.Bootloader, re // it existed taBefore, err = o.cache.Add(change.Before, bl.Name(), filepath.Base(relativeTarget)) if err != nil { - return false, err + return gadget.ChangeAbort, err } } ta, err := o.cache.Add(change.After, bl.Name(), filepath.Base(relativeTarget)) if err != nil { - return false, err + return gadget.ChangeAbort, err } trustedAssets := &o.modeenv.CurrentTrustedBootAssets @@ -490,21 +490,21 @@ func (o *TrustedAssetsUpdateObserver) observeUpdate(bl bootloader.Bootloader, re // during an update; more entries indicates that the // same asset name is used multiple times with different // content - return false, fmt.Errorf("cannot reuse asset name %q", ta.name) + return gadget.ChangeAbort, fmt.Errorf("cannot reuse asset name %q", ta.name) } (*trustedAssets)[ta.name] = append((*trustedAssets)[ta.name], ta.hash) } if o.modeenv.deepEqual(modeenvBefore) { - return true, nil + return gadget.ChangeExecute, nil } if err := o.modeenv.Write(); err != nil { - return false, fmt.Errorf("cannot write modeeenv: %v", err) + return gadget.ChangeAbort, fmt.Errorf("cannot write modeeenv: %v", err) } - return true, nil + return gadget.ChangeExecute, nil } -func (o *TrustedAssetsUpdateObserver) observeRollback(bl bootloader.Bootloader, recovery bool, root, relativeTarget string, data *gadget.ContentChange) (bool, error) { +func (o *TrustedAssetsUpdateObserver) observeRollback(bl bootloader.Bootloader, recovery bool, root, relativeTarget string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { trustedAssets := &o.modeenv.CurrentTrustedBootAssets otherTrustedAssets := o.modeenv.CurrentTrustedRecoveryBootAssets if recovery { @@ -516,7 +516,7 @@ func (o *TrustedAssetsUpdateObserver) observeRollback(bl bootloader.Bootloader, hashList, ok := (*trustedAssets)[assetName] if !ok || len(hashList) == 0 { // asset not tracked in modeenv - return true, nil + return gadget.ChangeExecute, nil } // new assets are appended to the list @@ -527,20 +527,20 @@ func (o *TrustedAssetsUpdateObserver) observeRollback(bl bootloader.Bootloader, if err != nil { // file may not exist if it was added by the update, that's ok if !os.IsNotExist(err) { - return false, fmt.Errorf("cannot calculate the digest of current asset: %v", err) + return gadget.ChangeAbort, fmt.Errorf("cannot calculate the digest of current asset: %v", err) } newlyAdded = true if len(hashList) > 1 { // we have more than 1 hash of the asset, so we expected // a previous revision to be restored, but got nothing // instead - return false, fmt.Errorf("tracked asset %q is unexpectedly missing from disk", + return gadget.ChangeAbort, fmt.Errorf("tracked asset %q is unexpectedly missing from disk", assetName) } } else { if ondiskHash != expectedOldHash { // this is unexpected, a different file exists on disk? - return false, fmt.Errorf("unexpected content of existing asset %q", relativeTarget) + return gadget.ChangeAbort, fmt.Errorf("unexpected content of existing asset %q", relativeTarget) } } @@ -556,7 +556,7 @@ func (o *TrustedAssetsUpdateObserver) observeRollback(bl bootloader.Bootloader, // asset revision is not used used elsewhere, we can remove it from the cache if err := o.cache.Remove(bl.Name(), assetName, newHash); err != nil { // XXX: should this be a log instead? - return false, fmt.Errorf("cannot remove unused boot asset %v:%v: %v", assetName, newHash, err) + return gadget.ChangeAbort, fmt.Errorf("cannot remove unused boot asset %v:%v: %v", assetName, newHash, err) } } @@ -568,10 +568,10 @@ func (o *TrustedAssetsUpdateObserver) observeRollback(bl bootloader.Bootloader, } if err := o.modeenv.Write(); err != nil { - return false, fmt.Errorf("cannot write modeeenv: %v", err) + return gadget.ChangeAbort, fmt.Errorf("cannot write modeeenv: %v", err) } - return false, nil + return gadget.ChangeExecute, nil } // BeforeWrite is called when the update process has been staged for execution. diff --git a/gadget/install/content_test.go b/gadget/install/content_test.go index 65016017c13..21c887799ab 100644 --- a/gadget/install/content_test.go +++ b/gadget/install/content_test.go @@ -185,7 +185,7 @@ type mockWriteObserver struct { } func (m *mockWriteObserver) Observe(op gadget.ContentOperation, sourceStruct *gadget.LaidOutStructure, - targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (bool, error) { + targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { if m.content == nil { m.content = make(map[string][]*mockContentChange) } @@ -193,7 +193,7 @@ func (m *mockWriteObserver) Observe(op gadget.ContentOperation, sourceStruct *ga &mockContentChange{path: relativeTargetPath, change: data}) m.c.Assert(sourceStruct, NotNil) m.c.Check(sourceStruct, DeepEquals, m.expectedStruct) - return true, m.observeErr + return gadget.ChangeExecute, m.observeErr } func (s *contentTestSuite) TestWriteFilesystemContent(c *C) { diff --git a/gadget/mountedfilesystem_test.go b/gadget/mountedfilesystem_test.go index d8975815266..7f7c0e12ae5 100644 --- a/gadget/mountedfilesystem_test.go +++ b/gadget/mountedfilesystem_test.go @@ -257,7 +257,7 @@ type mockWriteObserver struct { } func (m *mockWriteObserver) Observe(op gadget.ContentOperation, sourceStruct *gadget.LaidOutStructure, - targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (bool, error) { + targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { m.c.Assert(data, NotNil) m.c.Assert(op, Equals, gadget.ContentWrite, Commentf("unexpected operation %v", op)) if m.content == nil { @@ -276,7 +276,7 @@ func (m *mockWriteObserver) Observe(op gadget.ContentOperation, sourceStruct *ga m.c.Assert(sourceStruct, NotNil) m.c.Check(m.expectedStruct, DeepEquals, sourceStruct) - return true, m.observeErr + return gadget.ChangeExecute, m.observeErr } func (s *mountedfilesystemTestSuite) TestMountedWriterHappy(c *C) { @@ -839,7 +839,7 @@ type mockContentUpdateObserver struct { } func (m *mockContentUpdateObserver) Observe(op gadget.ContentOperation, sourceStruct *gadget.LaidOutStructure, - targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (bool, error) { + targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { if m.contentUpdate == nil { m.contentUpdate = make(map[string][]*mockContentChange) } @@ -870,7 +870,7 @@ func (m *mockContentUpdateObserver) Observe(op gadget.ContentOperation, sourceSt m.c.Assert(sourceStruct, NotNil) m.c.Check(m.expectedStruct, DeepEquals, sourceStruct) - return true, m.observeErr + return gadget.ChangeExecute, m.observeErr } func (s *mountedfilesystemTestSuite) TestMountedUpdaterBackupSimple(c *C) { diff --git a/gadget/update_test.go b/gadget/update_test.go index f604b4d6f3f..f1cf0e8413c 100644 --- a/gadget/update_test.go +++ b/gadget/update_test.go @@ -711,8 +711,8 @@ type mockUpdateProcessObserver struct { } func (m *mockUpdateProcessObserver) Observe(op gadget.ContentOperation, sourceStruct *gadget.LaidOutStructure, - targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (bool, error) { - return false, errors.New("unexpected call") + targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { + return gadget.ChangeAbort, errors.New("unexpected call") } func (m *mockUpdateProcessObserver) BeforeWrite() error { diff --git a/tests/lib/uc20-create-partitions/main.go b/tests/lib/uc20-create-partitions/main.go index 1bece17c336..88a6f712684 100644 --- a/tests/lib/uc20-create-partitions/main.go +++ b/tests/lib/uc20-create-partitions/main.go @@ -53,8 +53,8 @@ type simpleObserver struct { encryptionKey secboot.EncryptionKey } -func (o *simpleObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, dst string, data *gadget.ContentChange) (bool, error) { - return true, nil +func (o *simpleObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, dst string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { + return gadget.ChangeExecute, nil } func (o *simpleObserver) ChosenEncryptionKey(key secboot.EncryptionKey) { From 64da4767e50295eda5a9eec44528b4b5ca2d2da3 Mon Sep 17 00:00:00 2001 From: Maciej Borzecki Date: Wed, 23 Sep 2020 13:06:46 +0200 Subject: [PATCH 3/6] boot: check observer return values in unit tests Signed-off-by: Maciej Borzecki --- boot/assets_test.go | 196 +++++++++++++++++++++++++++++--------------- 1 file changed, 130 insertions(+), 66 deletions(-) diff --git a/boot/assets_test.go b/boot/assets_test.go index e9a4bf29e6b..a5f44fe4f15 100644 --- a/boot/assets_test.go +++ b/boot/assets_test.go @@ -693,32 +693,37 @@ func (s *assetsSuite) TestUpdateObserverUpdateMockedWithReseal(c *C) { // we get an observer for UC20 obs, _ := s.uc20UpdateObserver(c) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{ After: filepath.Join(d, "foobar"), // original content would get backed up by the updater Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // the list of trusted assets was asked once for the boot bootloader c.Check(tab.TrustedAssetsCalls, Equals, 1) // observe the recovery struct - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{ After: filepath.Join(d, "foobar"), // original content Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "nested/other-asset", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "nested/other-asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // and once again for the recovery bootloader c.Check(tab.TrustedAssetsCalls, Equals, 2) // all files are in cache @@ -801,15 +806,18 @@ func (s *assetsSuite) TestUpdateObserverUpdateExistingAssetMocked(c *C) { obs, _ := s.uc20UpdateObserver(c) // observe the updates - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // trusted assets were asked for c.Check(tab.TrustedAssetsCalls, Equals, 2) // file is in the cache @@ -867,12 +875,14 @@ func (s *assetsSuite) TestUpdateObserverUpdateNothingTrackedMocked(c *C) { obs, _ := s.uc20UpdateObserver(c) // observe the updates - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // trusted assets were asked for c.Check(tab.TrustedAssetsCalls, Equals, 2) // file is in the cache @@ -917,9 +927,10 @@ func (s *assetsSuite) TestUpdateObserverUpdateOtherRoleStructMocked(c *C) { } // observe the updates - _, err := obs.Observe(gadget.ContentUpdate, mockVolumeStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockVolumeStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // trusted assets were asked for c.Check(tab.TrustedAssetsCalls, Equals, 0) } @@ -942,12 +953,14 @@ func (s *assetsSuite) TestUpdateObserverUpdateNotTrustedMocked(c *C) { obs, _ := s.uc20UpdateObserver(c) // observe the updates - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // reseal is a noop err = obs.BeforeWrite() @@ -965,13 +978,14 @@ func (s *assetsSuite) TestUpdateObserverUpdateTrivialErr(c *C) { // first no bootloader bootloader.ForceError(fmt.Errorf("bootloader fail")) - _, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) - c.Assert(err, ErrorMatches, "cannot find bootloader: bootloader fail") - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeAbort) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, "cannot find bootloader: bootloader fail") + c.Check(res, Equals, gadget.ChangeAbort) bootloader.ForceError(nil) bl := bootloadertest.Mock("trusted", "").WithTrustedAssets() @@ -982,22 +996,26 @@ func (s *assetsSuite) TestUpdateObserverUpdateTrivialErr(c *C) { bl.TrustedAssetsErr = fmt.Errorf("fail") // listing trusted assets fails - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, `cannot list "trusted" bootloader trusted assets: fail`) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeAbort) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, `cannot list "trusted" bootloader trusted assets: fail`) + c.Check(res, Equals, gadget.ChangeAbort) bl.TrustedAssetsErr = nil // no modeenv - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, `cannot load modeenv: .* no such file or directory`) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeAbort) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, `cannot load modeenv: .* no such file or directory`) + c.Check(res, Equals, gadget.ChangeAbort) m := boot.Modeenv{ Mode: "run", @@ -1006,15 +1024,18 @@ func (s *assetsSuite) TestUpdateObserverUpdateTrivialErr(c *C) { c.Assert(err, IsNil) // no source file, hash will fail - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, `cannot open asset file: .*/foobar: no such file or directory`) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeAbort) + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{Before: filepath.Join(d, "before"), After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, `cannot open asset file: .*/before: no such file or directory`) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeAbort) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, `cannot open asset file: .*/foobar: no such file or directory`) + c.Check(res, Equals, gadget.ChangeAbort) } func (s *assetsSuite) TestUpdateObserverUpdateRepeatedAssetErr(c *C) { @@ -1045,12 +1066,14 @@ func (s *assetsSuite) TestUpdateObserverUpdateRepeatedAssetErr(c *C) { err = ioutil.WriteFile(filepath.Join(d, "foobar"), nil, 0644) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, `cannot reuse asset name "asset"`) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeAbort) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, `cannot reuse asset name "asset"`) + c.Check(res, Equals, gadget.ChangeAbort) } func (s *assetsSuite) TestUpdateObserverUpdateAfterSuccessfulBootMocked(c *C) { @@ -1103,20 +1126,22 @@ func (s *assetsSuite) TestUpdateObserverUpdateAfterSuccessfulBootMocked(c *C) { // we get an observer for UC20 obs, _ := s.uc20UpdateObserver(c) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{ After: filepath.Join(d, "foobar"), // original content would get backed up by the updater Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{ After: filepath.Join(d, "foobar"), // original content Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // all files are in cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted", "*"), []string{ @@ -1202,38 +1227,43 @@ func (s *assetsSuite) TestUpdateObserverRollbackModeenvManipulationMocked(c *C) err := m.WriteTo("") c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "asset", &gadget.ContentChange{ After: filepath.Join(d, "asset"), Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "shim", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "shim", &gadget.ContentChange{ After: filepath.Join(d, "shim"), // no before content, new file }) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // the list of trusted assets was asked once for the boot bootloader c.Check(tab.TrustedAssetsCalls, Equals, 1) // observe the recovery struct - _, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, rootSeed, "shim", + res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, rootSeed, "shim", &gadget.ContentChange{ After: filepath.Join(d, "shim"), Before: filepath.Join(backups, "shim.backup"), }) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, rootSeed, "asset", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, rootSeed, "asset", &gadget.ContentChange{ After: filepath.Join(d, "asset"), Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, rootSeed, "nested/other-asset", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, rootSeed, "nested/other-asset", &gadget.ContentChange{ After: filepath.Join(d, "asset"), }) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // and once again for the recovery bootloader c.Check(tab.TrustedAssetsCalls, Equals, 2) // all files are in cache @@ -1276,15 +1306,17 @@ func (s *assetsSuite) TestUpdateObserverRollbackFileSanity(c *C) { err := m.WriteTo("") c.Assert(err, IsNil) // file does not exist on disk - _, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "asset", &gadget.ContentChange{}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // the list of trusted assets was asked once for the boot bootloader c.Check(tab.TrustedAssetsCalls, Equals, 1) // observe the recovery struct - _, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, root, "asset", + res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, root, "asset", &gadget.ContentChange{}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // and once again for the recovery bootloader c.Check(tab.TrustedAssetsCalls, Equals, 2) // check modeenv @@ -1309,23 +1341,27 @@ func (s *assetsSuite) TestUpdateObserverRollbackFileSanity(c *C) { err = m.WriteTo("") c.Assert(err, IsNil) // again, file does not exist on disk, but we expected it to be there - _, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "asset", + res, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "asset", &gadget.ContentChange{}) c.Assert(err, ErrorMatches, `tracked asset "asset" is unexpectedly missing from disk`) - _, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeAbort) + res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, root, "asset", &gadget.ContentChange{}) c.Assert(err, ErrorMatches, `tracked asset "asset" is unexpectedly missing from disk`) + c.Check(res, Equals, gadget.ChangeAbort) // create the file which will fail checksum check err = ioutil.WriteFile(filepath.Join(root, "asset"), nil, 0644) c.Assert(err, IsNil) // once more, the file exists on disk, but has unexpected checksum - _, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "asset", + res, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "asset", &gadget.ContentChange{}) c.Assert(err, ErrorMatches, `unexpected content of existing asset "asset"`) - _, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeAbort) + res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, root, "asset", &gadget.ContentChange{}) c.Assert(err, ErrorMatches, `unexpected content of existing asset "asset"`) + c.Check(res, Equals, gadget.ChangeAbort) } func (s *assetsSuite) TestUpdateObserverUpdateRollbackGrub(c *C) { @@ -1422,15 +1458,18 @@ func (s *assetsSuite) TestUpdateObserverUpdateRollbackGrub(c *C) { c.Assert(err, IsNil) // updates first - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, bootDir, "EFI/boot/grubx64.efi", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, bootDir, "EFI/boot/grubx64.efi", &gadget.ContentChange{After: filepath.Join(gadgetDir, "grubx64.efi")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, seedDir, "EFI/boot/grubx64.efi", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, seedDir, "EFI/boot/grubx64.efi", &gadget.ContentChange{After: filepath.Join(gadgetDir, "grubx64.efi")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, seedDir, "EFI/boot/bootx64.efi", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, seedDir, "EFI/boot/bootx64.efi", &gadget.ContentChange{After: filepath.Join(gadgetDir, "bootx64.efi")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // verify cache contents checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "grub", "*"), []string{ // recovery shim @@ -1474,15 +1513,18 @@ func (s *assetsSuite) TestUpdateObserverUpdateRollbackGrub(c *C) { // hiya, update failed, pretend we do a rollback, files on disk are as // if they were restored - _, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, bootDir, "EFI/boot/grubx64.efi", + res, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, bootDir, "EFI/boot/grubx64.efi", &gadget.ContentChange{}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, seedDir, "EFI/boot/grubx64.efi", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, seedDir, "EFI/boot/grubx64.efi", &gadget.ContentChange{}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, seedDir, "EFI/boot/bootx64.efi", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, seedDir, "EFI/boot/bootx64.efi", &gadget.ContentChange{}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // modeenv is back to the initial state afterRollbackM, err := boot.ReadModeenv("") @@ -1536,19 +1578,23 @@ func (s *assetsSuite) TestUpdateObserverCanceledSimpleAfterBackupMocked(c *C) { err = ioutil.WriteFile(filepath.Join(d, "shim"), shim, 0644) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // observe the recovery struct - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // files are in cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "trusted", fmt.Sprintf("asset-%s", dataHash)), @@ -1638,17 +1684,20 @@ func (s *assetsSuite) TestUpdateObserverCanceledPartiallyUsedMocked(c *C) { err = m.WriteTo("") c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // observe the recovery struct // XXX: shim is not updated - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // files are in cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "trusted", fmt.Sprintf("asset-%s", dataHash)), @@ -1746,9 +1795,10 @@ func (s *assetsSuite) TestUpdateObserverCanceledNoActionsMocked(c *C) { err = ioutil.WriteFile(filepath.Join(d, "shim"), []byte("shim"), 0644) c.Assert(err, IsNil) // observe only recovery bootloader update, no action for run bootloader - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", + res, err := obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // cancel again err = obs.Canceled() c.Assert(err, IsNil) @@ -1781,9 +1831,10 @@ func (s *assetsSuite) TestUpdateObserverCanceledEmptyModeenvAssets(c *C) { err = ioutil.WriteFile(filepath.Join(d, "shim"), []byte("shim"), 0644) c.Assert(err, IsNil) // observe an update only for the recovery bootloader, the run bootloader trusted assets remain empty - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", + res, err := obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // cancel the update err = obs.Canceled() @@ -1795,9 +1846,10 @@ func (s *assetsSuite) TestUpdateObserverCanceledEmptyModeenvAssets(c *C) { // get a new observer, and observe an update for run bootloader asset only obs, _ = s.uc20UpdateObserver(c) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // cancel once more err = obs.Canceled() c.Assert(err, IsNil) @@ -1832,12 +1884,14 @@ func (s *assetsSuite) TestUpdateObserverCanceledAfterRollback(c *C) { // trigger loading modeenv and bootloader information err = ioutil.WriteFile(filepath.Join(d, "shim"), []byte("shim"), 0644) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", + res, err := obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // procure the desired state by: // injecting a changed asset for run bootloader @@ -1897,12 +1951,14 @@ func (s *assetsSuite) TestUpdateObserverCanceledUnhappyCacheStillProceeds(c *C) shimHash := "dac0063e831d4b2e7a330426720512fc50fa315042f0bb30f9d1db73e4898dcb89119cac41fdfa62137c8931a50f9d7b" err = ioutil.WriteFile(filepath.Join(d, "shim"), shim, 0644) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", + res, err := obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // make sure that the cache directory state is as expected checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "trusted", "asset-assethash"), @@ -2344,27 +2400,31 @@ func (s *assetsSuite) TestUpdateObserverReseal(c *C) { // we get an observer for UC20 obs, uc20model := s.uc20UpdateObserver(c) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{ After: filepath.Join(d, "foobar"), // original content would get backed up by the updater Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // observe the recovery struct - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{ After: filepath.Join(d, "foobar"), // original content Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "trusted", fmt.Sprintf("asset-%s", dataHash)), filepath.Join(dirs.SnapBootAssetsDir, "trusted", fmt.Sprintf("asset-%s", beforeHash)), @@ -2479,19 +2539,23 @@ func (s *assetsSuite) TestUpdateObserverCanceledReseal(c *C) { c.Assert(err, IsNil) // trigger a bunch of updates, so that we have things to cancel - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", + res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // observe the recovery struct - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) restore := boot.MockSeedReadSystemEssential(func(seedDir, label string, essentialTypes []snap.Type, tm timings.Measurer) (*asserts.Model, []*seed.Snap, error) { kernelSnap := &seed.Snap{ From c8f1c3b208c3e629ce5c4a23d5c42733df1ed5ba Mon Sep 17 00:00:00 2001 From: Maciej Borzecki Date: Wed, 23 Sep 2020 13:22:16 +0200 Subject: [PATCH 4/6] boot: verify install observer return values in unit tests Signed-off-by: Maciej Borzecki --- boot/assets_test.go | 46 ++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/boot/assets_test.go b/boot/assets_test.go index a5f44fe4f15..44f1e1f6405 100644 --- a/boot/assets_test.go +++ b/boot/assets_test.go @@ -278,19 +278,23 @@ func (s *assetsSuite) TestInstallObserverObserveSystemBootRealGrub(c *C) { Before: "", } // only grubx64.efi gets installed to system-boot - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + res, err := obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "EFI/boot/grubx64.efi", writeChange) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // Observe is called when populating content, but one can freely specify // overlapping content entries, so a same file may be observed more than // once - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "EFI/boot/grubx64.efi", writeChange) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // try with one more file, which is not a trusted asset of a run mode, so it is ignored - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "EFI/boot/bootx64.efi", writeChange) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) + // a single file in cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "grub", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "grub", fmt.Sprintf("grubx64.efi-%s", dataHash)), @@ -305,9 +309,10 @@ func (s *assetsSuite) TestInstallObserverObserveSystemBootRealGrub(c *C) { otherWriteChange := &gadget.ContentChange{ After: filepath.Join(d, "other-foobar"), } - _, err = obs.Observe(gadget.ContentWrite, systemSeedStruct, boot.InitramfsUbuntuBootDir, + res, err = obs.Observe(gadget.ContentWrite, systemSeedStruct, boot.InitramfsUbuntuBootDir, "EFI/boot/grubx64.efi", otherWriteChange) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // still, only one entry in the cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "grub", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "grub", fmt.Sprintf("grubx64.efi-%s", dataHash)), @@ -349,21 +354,25 @@ func (s *assetsSuite) TestInstallObserverObserveSystemBootMocked(c *C) { // there is no original file in place Before: "", } - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + res, err := obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", writeChange) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // observe same asset again - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", writeChange) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // different one - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "nested/other-asset", writeChange) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // a non trusted asset - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "non-trusted", writeChange) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // a single file in cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted-assets", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "trusted-assets", fmt.Sprintf("asset-%s", dataHash)), @@ -395,9 +404,10 @@ func (s *assetsSuite) TestInstallObserverNonTrustedBootloader(c *C) { err = ioutil.WriteFile(filepath.Join(d, "foobar"), []byte("foobar"), 0644) c.Assert(err, IsNil) // bootloder is found, but ignored because it does not support trusted assets - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + res, err := obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) c.Check(osutil.IsDirectory(dirs.SnapBootAssetsDir), Equals, false, Commentf("%q exists while it should not", dirs.SnapBootAssetsDir)) c.Check(obs.CurrentTrustedBootAssetsMap(), IsNil) @@ -419,12 +429,14 @@ func (s *assetsSuite) TestInstallObserverTrustedButNoAssets(c *C) { err = ioutil.WriteFile(filepath.Join(d, "foobar"), []byte("foobar"), 0644) c.Assert(err, IsNil) // bootloder is found, but ignored because it does not support trusted assets - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + res, err := obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + c.Check(res, Equals, gadget.ChangeExecute) + res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "other-asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // the list of trusted assets was asked for just once c.Check(tab.TrustedAssetsCalls, Equals, 1) c.Check(obs.CurrentTrustedBootAssetsMap(), IsNil) @@ -452,13 +464,15 @@ func (s *assetsSuite) TestInstallObserverTrustedReuseNameErr(c *C) { c.Assert(err, IsNil) err = ioutil.WriteFile(filepath.Join(d, "other"), []byte("other"), 0644) c.Assert(err, IsNil) - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", + res, err := obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) + c.Check(res, Equals, gadget.ChangeExecute) // same asset name but different content - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "nested/asset", + res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "nested/asset", &gadget.ContentChange{After: filepath.Join(d, "other")}) c.Assert(err, ErrorMatches, `cannot reuse asset name "asset"`) + c.Check(res, Equals, gadget.ChangeAbort) // the list of trusted assets was asked for just once c.Check(tab.TrustedAssetsCalls, Equals, 1) } @@ -477,18 +491,20 @@ func (s *assetsSuite) TestInstallObserverObserveErr(c *C) { c.Assert(err, IsNil) // there is no known bootloader in gadget - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + res, err := obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, "cannot find bootloader: mocked bootloader error") + c.Check(res, Equals, gadget.ChangeAbort) // force a bootloader now bootloader.ForceError(nil) bootloader.Force(tab) defer bootloader.Force(nil) - _, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, + res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, ErrorMatches, `cannot list "trusted-assets" bootloader trusted assets: mocked trusted assets error`) + c.Check(res, Equals, gadget.ChangeAbort) } func (s *assetsSuite) TestInstallObserverObserveExistingRecoveryMocked(c *C) { From e8a04297d82cd792fdf04c1b80e74058aec2bd1b Mon Sep 17 00:00:00 2001 From: Maciej Borzecki Date: Wed, 23 Sep 2020 14:21:33 +0200 Subject: [PATCH 5/6] many: naming tweaks Signed-off-by: Maciej Borzecki --- boot/assets.go | 30 +++--- boot/assets_test.go | 124 +++++++++++------------ gadget/install/content_test.go | 4 +- gadget/mountedfilesystem_test.go | 8 +- gadget/update.go | 18 ++-- gadget/update_test.go | 2 +- tests/lib/uc20-create-partitions/main.go | 4 +- 7 files changed, 95 insertions(+), 95 deletions(-) diff --git a/boot/assets.go b/boot/assets.go index 69ca87f3666..9b928faf442 100644 --- a/boot/assets.go +++ b/boot/assets.go @@ -227,10 +227,10 @@ type TrustedAssetsInstallObserver struct { // of the secure boot. // // Implements gadget.ContentObserver. -func (o *TrustedAssetsInstallObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, relativeTarget string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { +func (o *TrustedAssetsInstallObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, relativeTarget string, data *gadget.ContentChange) (gadget.ContentChangeAction, error) { if affectedStruct.Role != gadget.SystemBoot { // only care about system-boot - return gadget.ChangeExecute, nil + return gadget.ChangeApply, nil } if o.blName == "" { @@ -242,7 +242,7 @@ func (o *TrustedAssetsInstallObserver) Observe(op gadget.ContentOperation, affec o.blName = bl.Name() tbl, ok := bl.(bootloader.TrustedAssetsBootloader) if !ok { - return gadget.ChangeExecute, nil + return gadget.ChangeApply, nil } trustedAssets, err := tbl.TrustedAssets() if err != nil { @@ -252,7 +252,7 @@ func (o *TrustedAssetsInstallObserver) Observe(op gadget.ContentOperation, affec } if len(o.trustedAssets) == 0 || !strutil.ListContains(o.trustedAssets, relativeTarget) { // not one of the trusted assets - return gadget.ChangeExecute, nil + return gadget.ChangeApply, nil } ta, err := o.cache.Add(data.After, o.blName, filepath.Base(relativeTarget)) if err != nil { @@ -270,7 +270,7 @@ func (o *TrustedAssetsInstallObserver) Observe(op gadget.ContentOperation, affec } o.trackedAssets[ta.name] = append(o.trackedAssets[ta.name], ta.hash) } - return gadget.ChangeExecute, nil + return gadget.ChangeApply, nil } // ObserveExistingTrustedRecoveryAssets observes existing trusted assets of a @@ -380,7 +380,7 @@ func findMaybeTrustedAssetsBootloader(root string, opts *bootloader.Options) (fo // the bootloader binary which is measured as part of the secure boot. // // Implements gadget.ContentUpdateObserver. -func (o *TrustedAssetsUpdateObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, relativeTarget string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { +func (o *TrustedAssetsUpdateObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, relativeTarget string, data *gadget.ContentChange) (gadget.ContentChangeAction, error) { var whichBootloader bootloader.Bootloader var whichAssets []string var err error @@ -413,11 +413,11 @@ func (o *TrustedAssetsUpdateObserver) Observe(op gadget.ContentOperation, affect isRecovery = true default: // only system-seed and system-boot are of interest - return gadget.ChangeExecute, nil + return gadget.ChangeApply, nil } if len(whichAssets) == 0 || !strutil.ListContains(whichAssets, relativeTarget) { // not one of the trusted assets - return gadget.ChangeExecute, nil + return gadget.ChangeApply, nil } if o.modeenv == nil { // we've hit a trusted asset, so a modeenv is needed now too @@ -433,11 +433,11 @@ func (o *TrustedAssetsUpdateObserver) Observe(op gadget.ContentOperation, affect return o.observeRollback(whichBootloader, isRecovery, root, relativeTarget, data) default: // we only care about update and rollback actions - return gadget.ChangeExecute, nil + return gadget.ChangeApply, nil } } -func (o *TrustedAssetsUpdateObserver) observeUpdate(bl bootloader.Bootloader, recovery bool, root, relativeTarget string, change *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { +func (o *TrustedAssetsUpdateObserver) observeUpdate(bl bootloader.Bootloader, recovery bool, root, relativeTarget string, change *gadget.ContentChange) (gadget.ContentChangeAction, error) { modeenvBefore, err := o.modeenv.Copy() if err != nil { return gadget.ChangeAbort, fmt.Errorf("cannot copy modeenv: %v", err) @@ -496,15 +496,15 @@ func (o *TrustedAssetsUpdateObserver) observeUpdate(bl bootloader.Bootloader, re } if o.modeenv.deepEqual(modeenvBefore) { - return gadget.ChangeExecute, nil + return gadget.ChangeApply, nil } if err := o.modeenv.Write(); err != nil { return gadget.ChangeAbort, fmt.Errorf("cannot write modeeenv: %v", err) } - return gadget.ChangeExecute, nil + return gadget.ChangeApply, nil } -func (o *TrustedAssetsUpdateObserver) observeRollback(bl bootloader.Bootloader, recovery bool, root, relativeTarget string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { +func (o *TrustedAssetsUpdateObserver) observeRollback(bl bootloader.Bootloader, recovery bool, root, relativeTarget string, data *gadget.ContentChange) (gadget.ContentChangeAction, error) { trustedAssets := &o.modeenv.CurrentTrustedBootAssets otherTrustedAssets := o.modeenv.CurrentTrustedRecoveryBootAssets if recovery { @@ -516,7 +516,7 @@ func (o *TrustedAssetsUpdateObserver) observeRollback(bl bootloader.Bootloader, hashList, ok := (*trustedAssets)[assetName] if !ok || len(hashList) == 0 { // asset not tracked in modeenv - return gadget.ChangeExecute, nil + return gadget.ChangeApply, nil } // new assets are appended to the list @@ -571,7 +571,7 @@ func (o *TrustedAssetsUpdateObserver) observeRollback(bl bootloader.Bootloader, return gadget.ChangeAbort, fmt.Errorf("cannot write modeeenv: %v", err) } - return gadget.ChangeExecute, nil + return gadget.ChangeApply, nil } // BeforeWrite is called when the update process has been staged for execution. diff --git a/boot/assets_test.go b/boot/assets_test.go index 44f1e1f6405..0f6c8a30a31 100644 --- a/boot/assets_test.go +++ b/boot/assets_test.go @@ -281,19 +281,19 @@ func (s *assetsSuite) TestInstallObserverObserveSystemBootRealGrub(c *C) { res, err := obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "EFI/boot/grubx64.efi", writeChange) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // Observe is called when populating content, but one can freely specify // overlapping content entries, so a same file may be observed more than // once res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "EFI/boot/grubx64.efi", writeChange) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // try with one more file, which is not a trusted asset of a run mode, so it is ignored res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "EFI/boot/bootx64.efi", writeChange) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // a single file in cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "grub", "*"), []string{ @@ -312,7 +312,7 @@ func (s *assetsSuite) TestInstallObserverObserveSystemBootRealGrub(c *C) { res, err = obs.Observe(gadget.ContentWrite, systemSeedStruct, boot.InitramfsUbuntuBootDir, "EFI/boot/grubx64.efi", otherWriteChange) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // still, only one entry in the cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "grub", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "grub", fmt.Sprintf("grubx64.efi-%s", dataHash)), @@ -357,22 +357,22 @@ func (s *assetsSuite) TestInstallObserverObserveSystemBootMocked(c *C) { res, err := obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", writeChange) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // observe same asset again res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", writeChange) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // different one res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "nested/other-asset", writeChange) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // a non trusted asset res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "non-trusted", writeChange) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // a single file in cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted-assets", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "trusted-assets", fmt.Sprintf("asset-%s", dataHash)), @@ -407,7 +407,7 @@ func (s *assetsSuite) TestInstallObserverNonTrustedBootloader(c *C) { res, err := obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) c.Check(osutil.IsDirectory(dirs.SnapBootAssetsDir), Equals, false, Commentf("%q exists while it should not", dirs.SnapBootAssetsDir)) c.Check(obs.CurrentTrustedBootAssetsMap(), IsNil) @@ -432,11 +432,11 @@ func (s *assetsSuite) TestInstallObserverTrustedButNoAssets(c *C) { res, err := obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "other-asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // the list of trusted assets was asked for just once c.Check(tab.TrustedAssetsCalls, Equals, 1) c.Check(obs.CurrentTrustedBootAssetsMap(), IsNil) @@ -467,7 +467,7 @@ func (s *assetsSuite) TestInstallObserverTrustedReuseNameErr(c *C) { res, err := obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // same asset name but different content res, err = obs.Observe(gadget.ContentWrite, mockRunBootStruct, boot.InitramfsUbuntuBootDir, "nested/asset", &gadget.ContentChange{After: filepath.Join(d, "other")}) @@ -716,18 +716,18 @@ func (s *assetsSuite) TestUpdateObserverUpdateMockedWithReseal(c *C) { Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // the list of trusted assets was asked once for the boot bootloader c.Check(tab.TrustedAssetsCalls, Equals, 1) // observe the recovery struct res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{ After: filepath.Join(d, "foobar"), @@ -735,11 +735,11 @@ func (s *assetsSuite) TestUpdateObserverUpdateMockedWithReseal(c *C) { Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "nested/other-asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // and once again for the recovery bootloader c.Check(tab.TrustedAssetsCalls, Equals, 2) // all files are in cache @@ -825,15 +825,15 @@ func (s *assetsSuite) TestUpdateObserverUpdateExistingAssetMocked(c *C) { res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // trusted assets were asked for c.Check(tab.TrustedAssetsCalls, Equals, 2) // file is in the cache @@ -894,11 +894,11 @@ func (s *assetsSuite) TestUpdateObserverUpdateNothingTrackedMocked(c *C) { res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // trusted assets were asked for c.Check(tab.TrustedAssetsCalls, Equals, 2) // file is in the cache @@ -946,7 +946,7 @@ func (s *assetsSuite) TestUpdateObserverUpdateOtherRoleStructMocked(c *C) { res, err := obs.Observe(gadget.ContentUpdate, mockVolumeStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // trusted assets were asked for c.Check(tab.TrustedAssetsCalls, Equals, 0) } @@ -972,11 +972,11 @@ func (s *assetsSuite) TestUpdateObserverUpdateNotTrustedMocked(c *C) { res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // reseal is a noop err = obs.BeforeWrite() @@ -1149,7 +1149,7 @@ func (s *assetsSuite) TestUpdateObserverUpdateAfterSuccessfulBootMocked(c *C) { Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{ After: filepath.Join(d, "foobar"), @@ -1157,7 +1157,7 @@ func (s *assetsSuite) TestUpdateObserverUpdateAfterSuccessfulBootMocked(c *C) { Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // all files are in cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted", "*"), []string{ @@ -1249,14 +1249,14 @@ func (s *assetsSuite) TestUpdateObserverRollbackModeenvManipulationMocked(c *C) Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "shim", &gadget.ContentChange{ After: filepath.Join(d, "shim"), // no before content, new file }) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // the list of trusted assets was asked once for the boot bootloader c.Check(tab.TrustedAssetsCalls, Equals, 1) // observe the recovery struct @@ -1266,20 +1266,20 @@ func (s *assetsSuite) TestUpdateObserverRollbackModeenvManipulationMocked(c *C) Before: filepath.Join(backups, "shim.backup"), }) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, rootSeed, "asset", &gadget.ContentChange{ After: filepath.Join(d, "asset"), Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, rootSeed, "nested/other-asset", &gadget.ContentChange{ After: filepath.Join(d, "asset"), }) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // and once again for the recovery bootloader c.Check(tab.TrustedAssetsCalls, Equals, 2) // all files are in cache @@ -1325,14 +1325,14 @@ func (s *assetsSuite) TestUpdateObserverRollbackFileSanity(c *C) { res, err := obs.Observe(gadget.ContentRollback, mockRunBootStruct, root, "asset", &gadget.ContentChange{}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // the list of trusted assets was asked once for the boot bootloader c.Check(tab.TrustedAssetsCalls, Equals, 1) // observe the recovery struct res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, root, "asset", &gadget.ContentChange{}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // and once again for the recovery bootloader c.Check(tab.TrustedAssetsCalls, Equals, 2) // check modeenv @@ -1477,15 +1477,15 @@ func (s *assetsSuite) TestUpdateObserverUpdateRollbackGrub(c *C) { res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, bootDir, "EFI/boot/grubx64.efi", &gadget.ContentChange{After: filepath.Join(gadgetDir, "grubx64.efi")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, seedDir, "EFI/boot/grubx64.efi", &gadget.ContentChange{After: filepath.Join(gadgetDir, "grubx64.efi")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, seedDir, "EFI/boot/bootx64.efi", &gadget.ContentChange{After: filepath.Join(gadgetDir, "bootx64.efi")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // verify cache contents checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "grub", "*"), []string{ // recovery shim @@ -1532,15 +1532,15 @@ func (s *assetsSuite) TestUpdateObserverUpdateRollbackGrub(c *C) { res, err = obs.Observe(gadget.ContentRollback, mockRunBootStruct, bootDir, "EFI/boot/grubx64.efi", &gadget.ContentChange{}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, seedDir, "EFI/boot/grubx64.efi", &gadget.ContentChange{}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentRollback, mockSeedStruct, seedDir, "EFI/boot/bootx64.efi", &gadget.ContentChange{}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // modeenv is back to the initial state afterRollbackM, err := boot.ReadModeenv("") @@ -1597,20 +1597,20 @@ func (s *assetsSuite) TestUpdateObserverCanceledSimpleAfterBackupMocked(c *C) { res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // observe the recovery struct res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // files are in cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "trusted", fmt.Sprintf("asset-%s", dataHash)), @@ -1703,17 +1703,17 @@ func (s *assetsSuite) TestUpdateObserverCanceledPartiallyUsedMocked(c *C) { res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // observe the recovery struct // XXX: shim is not updated res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // files are in cache checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "trusted", fmt.Sprintf("asset-%s", dataHash)), @@ -1814,7 +1814,7 @@ func (s *assetsSuite) TestUpdateObserverCanceledNoActionsMocked(c *C) { res, err := obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // cancel again err = obs.Canceled() c.Assert(err, IsNil) @@ -1850,7 +1850,7 @@ func (s *assetsSuite) TestUpdateObserverCanceledEmptyModeenvAssets(c *C) { res, err := obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // cancel the update err = obs.Canceled() @@ -1865,7 +1865,7 @@ func (s *assetsSuite) TestUpdateObserverCanceledEmptyModeenvAssets(c *C) { res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // cancel once more err = obs.Canceled() c.Assert(err, IsNil) @@ -1903,11 +1903,11 @@ func (s *assetsSuite) TestUpdateObserverCanceledAfterRollback(c *C) { res, err := obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // procure the desired state by: // injecting a changed asset for run bootloader @@ -1970,11 +1970,11 @@ func (s *assetsSuite) TestUpdateObserverCanceledUnhappyCacheStillProceeds(c *C) res, err := obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // make sure that the cache directory state is as expected checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "trusted", "asset-assethash"), @@ -2423,16 +2423,16 @@ func (s *assetsSuite) TestUpdateObserverReseal(c *C) { Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // observe the recovery struct res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{ After: filepath.Join(d, "foobar"), @@ -2440,7 +2440,7 @@ func (s *assetsSuite) TestUpdateObserverReseal(c *C) { Before: filepath.Join(backups, "asset.backup"), }) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) checkContentGlob(c, filepath.Join(dirs.SnapBootAssetsDir, "trusted", "*"), []string{ filepath.Join(dirs.SnapBootAssetsDir, "trusted", fmt.Sprintf("asset-%s", dataHash)), filepath.Join(dirs.SnapBootAssetsDir, "trusted", fmt.Sprintf("asset-%s", beforeHash)), @@ -2558,20 +2558,20 @@ func (s *assetsSuite) TestUpdateObserverCanceledReseal(c *C) { res, err := obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockRunBootStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) // observe the recovery struct res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "shim", &gadget.ContentChange{After: filepath.Join(d, "shim")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) res, err = obs.Observe(gadget.ContentUpdate, mockSeedStruct, root, "asset", &gadget.ContentChange{After: filepath.Join(d, "foobar")}) c.Assert(err, IsNil) - c.Check(res, Equals, gadget.ChangeExecute) + c.Check(res, Equals, gadget.ChangeApply) restore := boot.MockSeedReadSystemEssential(func(seedDir, label string, essentialTypes []snap.Type, tm timings.Measurer) (*asserts.Model, []*seed.Snap, error) { kernelSnap := &seed.Snap{ diff --git a/gadget/install/content_test.go b/gadget/install/content_test.go index 21c887799ab..dcb032333ca 100644 --- a/gadget/install/content_test.go +++ b/gadget/install/content_test.go @@ -185,7 +185,7 @@ type mockWriteObserver struct { } func (m *mockWriteObserver) Observe(op gadget.ContentOperation, sourceStruct *gadget.LaidOutStructure, - targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { + targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeAction, error) { if m.content == nil { m.content = make(map[string][]*mockContentChange) } @@ -193,7 +193,7 @@ func (m *mockWriteObserver) Observe(op gadget.ContentOperation, sourceStruct *ga &mockContentChange{path: relativeTargetPath, change: data}) m.c.Assert(sourceStruct, NotNil) m.c.Check(sourceStruct, DeepEquals, m.expectedStruct) - return gadget.ChangeExecute, m.observeErr + return gadget.ChangeApply, m.observeErr } func (s *contentTestSuite) TestWriteFilesystemContent(c *C) { diff --git a/gadget/mountedfilesystem_test.go b/gadget/mountedfilesystem_test.go index 7f7c0e12ae5..41d0edfb55b 100644 --- a/gadget/mountedfilesystem_test.go +++ b/gadget/mountedfilesystem_test.go @@ -257,7 +257,7 @@ type mockWriteObserver struct { } func (m *mockWriteObserver) Observe(op gadget.ContentOperation, sourceStruct *gadget.LaidOutStructure, - targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { + targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeAction, error) { m.c.Assert(data, NotNil) m.c.Assert(op, Equals, gadget.ContentWrite, Commentf("unexpected operation %v", op)) if m.content == nil { @@ -276,7 +276,7 @@ func (m *mockWriteObserver) Observe(op gadget.ContentOperation, sourceStruct *ga m.c.Assert(sourceStruct, NotNil) m.c.Check(m.expectedStruct, DeepEquals, sourceStruct) - return gadget.ChangeExecute, m.observeErr + return gadget.ChangeApply, m.observeErr } func (s *mountedfilesystemTestSuite) TestMountedWriterHappy(c *C) { @@ -839,7 +839,7 @@ type mockContentUpdateObserver struct { } func (m *mockContentUpdateObserver) Observe(op gadget.ContentOperation, sourceStruct *gadget.LaidOutStructure, - targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { + targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeAction, error) { if m.contentUpdate == nil { m.contentUpdate = make(map[string][]*mockContentChange) } @@ -870,7 +870,7 @@ func (m *mockContentUpdateObserver) Observe(op gadget.ContentOperation, sourceSt m.c.Assert(sourceStruct, NotNil) m.c.Check(m.expectedStruct, DeepEquals, sourceStruct) - return gadget.ChangeExecute, m.observeErr + return gadget.ChangeApply, m.observeErr } func (s *mountedfilesystemTestSuite) TestMountedUpdaterBackupSimple(c *C) { diff --git a/gadget/update.go b/gadget/update.go index d930137d2f5..ba740f34b53 100644 --- a/gadget/update.go +++ b/gadget/update.go @@ -61,15 +61,15 @@ type ContentChange struct { } type ContentOperation int -type ContentChangeDisposition int +type ContentChangeAction int const ( ContentWrite ContentOperation = iota ContentUpdate ContentRollback - ChangeExecute ContentChangeDisposition = iota - ChangeAbort + ChangeAbort ContentChangeAction = iota + ChangeApply ChangePreserveBefore ) @@ -88,13 +88,13 @@ type ContentObserver interface { // happens after the original file has been restored (or removed if the // file was added during the update), the source path is empty. // - // Returning ChangeExecute indicates that the observer agrees for a - // given change to be executed. When called with a ContentUpdate - // operation, returning ChangePreserveBefore indicates that the 'before' - // content shall be preserved. Returning ChangeAbort is returned along - // with a non-nil error. + // Returning ChangeApply indicates that the observer agrees for a given + // change to be executed. When called with a ContentUpdate operation, + // returning ChangePreserveBefore indicates that the 'before' content + // shall be preserved. ChangeAbort is expected to be returned along with + // a non-nil error. Observe(op ContentOperation, sourceStruct *LaidOutStructure, - targetRootDir, relativeTargetPath string, dataChange *ContentChange) (ContentChangeDisposition, error) + targetRootDir, relativeTargetPath string, dataChange *ContentChange) (ContentChangeAction, error) } // ContentUpdateObserver allows for observing update (and potentially a diff --git a/gadget/update_test.go b/gadget/update_test.go index f1cf0e8413c..4dce0394a6d 100644 --- a/gadget/update_test.go +++ b/gadget/update_test.go @@ -711,7 +711,7 @@ type mockUpdateProcessObserver struct { } func (m *mockUpdateProcessObserver) Observe(op gadget.ContentOperation, sourceStruct *gadget.LaidOutStructure, - targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { + targetRootDir, relativeTargetPath string, data *gadget.ContentChange) (gadget.ContentChangeAction, error) { return gadget.ChangeAbort, errors.New("unexpected call") } diff --git a/tests/lib/uc20-create-partitions/main.go b/tests/lib/uc20-create-partitions/main.go index 88a6f712684..3bc22fe38cd 100644 --- a/tests/lib/uc20-create-partitions/main.go +++ b/tests/lib/uc20-create-partitions/main.go @@ -53,8 +53,8 @@ type simpleObserver struct { encryptionKey secboot.EncryptionKey } -func (o *simpleObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, dst string, data *gadget.ContentChange) (gadget.ContentChangeDisposition, error) { - return gadget.ChangeExecute, nil +func (o *simpleObserver) Observe(op gadget.ContentOperation, affectedStruct *gadget.LaidOutStructure, root, dst string, data *gadget.ContentChange) (gadget.ContentChangeAction, error) { + return gadget.ChangeApply, nil } func (o *simpleObserver) ChosenEncryptionKey(key secboot.EncryptionKey) { From 95aecd85b0476bc9c3f92136aa96871e296026bc Mon Sep 17 00:00:00 2001 From: Maciej Borzecki Date: Thu, 24 Sep 2020 13:53:20 +0200 Subject: [PATCH 6/6] gadget: comment tweak Signed-off-by: Maciej Borzecki --- gadget/update.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gadget/update.go b/gadget/update.go index ba740f34b53..1ac77f72d94 100644 --- a/gadget/update.go +++ b/gadget/update.go @@ -89,7 +89,7 @@ type ContentObserver interface { // file was added during the update), the source path is empty. // // Returning ChangeApply indicates that the observer agrees for a given - // change to be executed. When called with a ContentUpdate operation, + // change to be applied. When called with a ContentUpdate operation, // returning ChangePreserveBefore indicates that the 'before' content // shall be preserved. ChangeAbort is expected to be returned along with // a non-nil error.