Skip to content

Commit 1ab472a

Browse files
committed
o/snapstate: add tri-state option (nil = default reservation, otherwise res_size)
1 parent 5d9bb0c commit 1ab472a

3 files changed

Lines changed: 49 additions & 22 deletions

File tree

overlord/snapstate/snapstate.go

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -174,23 +174,25 @@ func ShouldSendNotificationsToTheUser(st *state.State) (bool, error) {
174174
return true, nil
175175
}
176176

177-
func diskSpaceReservation(tr *config.Transaction) uint64 {
177+
func diskSpaceReservation(tr *config.Transaction) *uint64 {
178178
var reservation string
179179
err := tr.Get("core", "system.disk-space-reservation", &reservation)
180180
if config.IsNoOption(err) {
181181
// TODO: decide how unset system.disk-space-reservation should behave when
182182
// the experimental disk space feature flags are graduated.
183-
return defaultDiskSpaceReservation
183+
defaultReservation := defaultDiskSpaceReservation
184+
return &defaultReservation
184185
}
185186
if err != nil {
186-
return 0
187+
return nil
187188
}
188189

189190
parsedReservation, err := strutil.ParseByteSize(reservation)
190191
if err != nil {
191-
return 0
192+
return nil
192193
}
193-
return uint64(parsedReservation)
194+
reservationBytes := uint64(parsedReservation)
195+
return &reservationBytes
194196
}
195197

196198
// ConfigureSnap returns a set of tasks to configure snapName as done during installation/refresh.
@@ -2524,7 +2526,7 @@ func autoRefreshPhase2(st *state.State, candidates []*refreshCandidate, flags *F
25242526

25252527
func checkDiskSpaceDownload(st *state.State, infos []minimalInstallInfo, rootDir string) error {
25262528
reservation := diskSpaceReservation(config.NewTransaction(st))
2527-
if reservation == 0 {
2529+
if reservation == nil {
25282530
return nil
25292531
}
25302532

@@ -2533,7 +2535,7 @@ func checkDiskSpaceDownload(st *state.State, infos []minimalInstallInfo, rootDir
25332535
totalSize += uint64(info.DownloadSize())
25342536
}
25352537

2536-
return checkForAvailableSpace(totalSize, reservation, infos, "download", rootDir)
2538+
return checkForAvailableSpace(totalSize, *reservation, infos, "download", rootDir)
25372539
}
25382540

25392541
// checkDiskSpace checks if there is enough space for the requested snaps and their prerequisites
@@ -2560,7 +2562,7 @@ func checkDiskSpace(st *state.State, changeKind string, infos []minimalInstallIn
25602562
}
25612563

25622564
reservation := diskSpaceReservation(tr)
2563-
if reservation == 0 {
2565+
if reservation == nil {
25642566
return nil
25652567
}
25662568

@@ -2569,7 +2571,7 @@ func checkDiskSpace(st *state.State, changeKind string, infos []minimalInstallIn
25692571
return err
25702572
}
25712573

2572-
return checkForAvailableSpace(totalSize, reservation, infos, changeKind, dirs.SnapdStateDir(dirs.GlobalRootDir))
2574+
return checkForAvailableSpace(totalSize, *reservation, infos, changeKind, dirs.SnapdStateDir(dirs.GlobalRootDir))
25732575
}
25742576

25752577
func checkForAvailableSpace(totalSize, reservation uint64, infos []minimalInstallInfo, changeKind string, rootDir string) error {
@@ -3171,11 +3173,11 @@ func Remove(st *state.State, name string, revision snap.Revision, flags *RemoveF
31713173
// will only be greater than 0 if the feature is enabled.
31723174
if snapshotSize > 0 {
31733175
reservation := diskSpaceReservation(config.NewTransaction(st))
3174-
if reservation == 0 {
3176+
if reservation == nil {
31753177
return ts, err
31763178
}
31773179

3178-
requiredSpace := snapshotSize + reservation
3180+
requiredSpace := snapshotSize + *reservation
31793181
path := dirs.SnapdStateDir(dirs.GlobalRootDir)
31803182
if err := osutilCheckFreeSpace(path, requiredSpace); err != nil {
31813183
if _, ok := err.(*osutil.NotEnoughDiskSpaceError); ok {
@@ -3327,7 +3329,7 @@ func removeTasks(st *state.State, snapst *SnapState, removals map[string]bool, r
33273329
if err != nil && !config.IsNoOption(err) {
33283330
return nil, 0, err
33293331
}
3330-
if checkDiskSpaceRemove && diskSpaceReservation(tr) != 0 {
3332+
if checkDiskSpaceRemove && diskSpaceReservation(tr) != nil {
33313333
snapshotSize, err = EstimateSnapshotSize(st, instanceName, nil)
33323334
if err != nil {
33333335
return nil, 0, err
@@ -3611,11 +3613,11 @@ func RemoveMany(st *state.State, names []string, flags *RemoveFlags) ([]string,
36113613
// will only be greater than 0 if the feature is enabled.
36123614
if totalSnapshotsSize > 0 {
36133615
reservation := diskSpaceReservation(config.NewTransaction(st))
3614-
if reservation == 0 {
3616+
if reservation == nil {
36153617
return removed, tasksets, nil
36163618
}
36173619

3618-
requiredSpace := totalSnapshotsSize + reservation
3620+
requiredSpace := totalSnapshotsSize + *reservation
36193621
if err := osutilCheckFreeSpace(path, requiredSpace); err != nil {
36203622
if _, ok := err.(*osutil.NotEnoughDiskSpaceError); ok {
36213623
return nil, nil, &InsufficientSpaceError{

overlord/snapstate/snapstate_remove_test.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,17 +1734,21 @@ func (s *snapmgrTestSuite) TestRemoveManyDiskSpaceCheckPasses(c *C) {
17341734
c.Check(err, IsNil)
17351735
}
17361736

1737-
func (s *snapmgrTestSuite) TestRemoveManyDiskSpaceReservationZeroSkipsSnapshotSizeCheck(c *C) {
1737+
func (s *snapmgrTestSuite) TestRemoveManyDiskSpaceReservationZeroChecksSnapshotSize(c *C) {
17381738
s.state.Lock()
17391739
defer s.state.Unlock()
17401740

1741+
var snapshotSizeCall int
17411742
snapstate.EstimateSnapshotSize = func(st *state.State, instanceName string, users []string) (uint64, error) {
1742-
c.Fatalf("unexpected snapshot size estimation")
1743-
return 0, nil
1743+
snapshotSizeCall++
1744+
c.Check(instanceName, Equals, "one")
1745+
return 123, nil
17441746
}
17451747

1748+
var requiredSizes []uint64
17461749
restore := snapstate.MockOsutilCheckFreeSpace(func(path string, required uint64) error {
1747-
c.Fatalf("unexpected disk space check")
1750+
c.Check(path, Equals, filepath.Join(dirs.GlobalRootDir, "/var/lib/snapd"))
1751+
requiredSizes = append(requiredSizes, required)
17481752
return nil
17491753
})
17501754
defer restore()
@@ -1773,6 +1777,9 @@ func (s *snapmgrTestSuite) TestRemoveManyDiskSpaceReservationZeroSkipsSnapshotSi
17731777
_, _, err := snapstate.RemoveMany(s.state, []string{"one"}, nil)
17741778
c.Assert(err, IsNil)
17751779
c.Check(automaticSnapshotCalled, Equals, true)
1780+
// 0B reservation means checks run with just the snapshot size, no buffer
1781+
c.Check(snapshotSizeCall, Equals, 1)
1782+
c.Check(requiredSizes, DeepEquals, []uint64{123})
17761783
}
17771784

17781785
type snapdBackend struct {

overlord/snapstate/snapstate_update_test.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7473,6 +7473,16 @@ func (s *snapmgrTestSuite) TestUpdateDiskSpaceDefaultReservationError(c *C) {
74737473
c.Check(diskSpaceErr.Snaps, DeepEquals, []string{"some-snap"})
74747474
}
74757475

7476+
func (s *snapmgrTestSuite) TestUpdateDiskSpaceDefaultReservationHappy(c *C) {
7477+
featureFlag := true
7478+
failInstallSize := false
7479+
failDiskCheck := false
7480+
// No system.disk-space-reservation is set, so the default 5MB reservation is used.
7481+
// The helper asserts required size == 123 + DefaultDiskSpaceReservation.
7482+
err := s.testUpdateDiskSpaceCheck(c, featureFlag, failInstallSize, failDiskCheck)
7483+
c.Check(err, IsNil)
7484+
}
7485+
74767486
func (s *snapmgrTestSuite) TestUpdateConfigureDiskSpaceReservation(c *C) {
74777487
const freeDiskSpace = uint64(1500)
74787488
var requiredSizes []uint64
@@ -7521,16 +7531,21 @@ func (s *snapmgrTestSuite) TestUpdateConfigureDiskSpaceReservation(c *C) {
75217531
c.Check(requiredSizes, DeepEquals, []uint64{2123, 1123})
75227532
}
75237533

7524-
func (s *snapmgrTestSuite) TestUpdateDiskSpaceReservationZeroSkipsCheck(c *C) {
7534+
func (s *snapmgrTestSuite) TestUpdateDiskSpaceReservationZeroChecksNormalSize(c *C) {
7535+
var requiredSizes []uint64
75257536
restore := snapstate.MockOsutilCheckFreeSpace(func(path string, sz uint64) error {
7526-
c.Fatalf("unexpected disk space check")
7537+
c.Check(path, Equals, filepath.Join(dirs.GlobalRootDir, "/var/lib/snapd"))
7538+
requiredSizes = append(requiredSizes, sz)
75277539
return nil
75287540
})
75297541
defer restore()
75307542

7543+
var installSizeCalled bool
75317544
restore = snapstate.MockInstallSize(func(st *state.State, snaps []snapstate.MinimalInstallInfo, userID int, prqt snapstate.PrereqTracker) (uint64, error) {
7532-
c.Fatalf("unexpected install size calculation")
7533-
return 0, nil
7545+
installSizeCalled = true
7546+
c.Assert(snaps, HasLen, 1)
7547+
c.Check(snaps[0].InstanceName(), Equals, "some-snap")
7548+
return 123, nil
75347549
})
75357550
defer restore()
75367551

@@ -7554,6 +7569,9 @@ func (s *snapmgrTestSuite) TestUpdateDiskSpaceReservationZeroSkipsCheck(c *C) {
75547569
opts := &snapstate.RevisionOptions{Channel: "some-channel"}
75557570
_, err := snapstate.Update(s.state, "some-snap", opts, s.user.ID, snapstate.Flags{})
75567571
c.Assert(err, IsNil)
7572+
// 0B reservation means checks run with just the install size, no buffer
7573+
c.Check(installSizeCalled, Equals, true)
7574+
c.Check(requiredSizes, DeepEquals, []uint64{123})
75577575
}
75587576

75597577
func (s *snapmgrTestSuite) TestUpdateDiskCheckSkippedIfDisabled(c *C) {

0 commit comments

Comments
 (0)