Skip to content

Commit 6c6788a

Browse files
o/snapstate, o/s/backend: move SortServices into Backend.StartServices
1 parent 6ef8a8e commit 6c6788a

4 files changed

Lines changed: 56 additions & 28 deletions

File tree

overlord/snapstate/backend/link.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -245,24 +245,24 @@ func (b Backend) LinkComponent(cpi snap.ContainerPlaceInfo, snapRev snap.Revisio
245245
}
246246

247247
func (b Backend) StartServices(apps []*snap.AppInfo, disabledSvcs *wrappers.DisabledServices, meter progress.Meter, tm timings.Measurer) error {
248+
// Services need to be sorted according to their Before
249+
// and After requirements
250+
startupOrdered, err := snap.SortServices(apps)
251+
if err != nil {
252+
return err
253+
}
248254
opts := &wrappers.StartServicesOptions{Enable: true}
249-
return wrappersStartServices(apps, disabledSvcs, opts, meter, tm)
255+
return wrappersStartServices(startupOrdered, disabledSvcs, opts, meter, tm)
250256
}
251257

252258
func (b Backend) StopServices(apps []*snap.AppInfo, removedSvcs map[string]*snap.AppInfo, disabledSvcs *wrappers.DisabledServices, reason snap.ServiceStopReason, undoer Undoer, meter progress.Meter, tm timings.Measurer) error {
253259
// Register the undo before stopping so that services are
254260
// started again even when StopServices fails partway through
255261
// (some services stopped, then an error on a later one).
256262
undoer.AddUndo(func() error {
257-
// Services need to be sorted according to their Before
258-
// and After requirements
259-
startupOrdered, err := snap.SortServices(apps)
260-
if err != nil {
261-
return fmt.Errorf("cannot sort services for undo: %v", err)
262-
}
263263
// StartServices filters out disabled services, so only
264264
// previously enabled services will be started again.
265-
return b.StartServices(startupOrdered, disabledSvcs, meter, tm)
265+
return b.StartServices(apps, disabledSvcs, meter, tm)
266266
})
267267
return wrappersStopServices(apps, removedSvcs, nil, reason, meter, tm)
268268
}

overlord/snapstate/backend/link_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,44 @@ func (s *linkSuite) TestStartServices(c *C) {
12341234
c.Assert(called, Equals, 1)
12351235
}
12361236

1237+
func (s *linkSuite) TestStartServicesSortsServices(c *C) {
1238+
var sortedNames []string
1239+
restore := backend.MockWrappersStartServices(func(apps []*snap.AppInfo, disabledSvcs *wrappers.DisabledServices, opts *wrappers.StartServicesOptions, inter wrappers.Interacter, tm timings.Measurer) error {
1240+
sortedNames = make([]string, len(apps))
1241+
for i, app := range apps {
1242+
sortedNames[i] = app.Name
1243+
}
1244+
return nil
1245+
})
1246+
defer restore()
1247+
1248+
svc1 := &snap.AppInfo{Name: "svc1", Before: []string{"svc3"}}
1249+
svc2 := &snap.AppInfo{Name: "svc2", After: []string{"svc1"}}
1250+
svc3 := &snap.AppInfo{Name: "svc3", Before: []string{"svc2"}}
1251+
1252+
// pass in unsorted order
1253+
apps := []*snap.AppInfo{svc1, svc2, svc3}
1254+
err := s.be.StartServices(apps, nil, progress.Null, s.perfTimings)
1255+
c.Assert(err, IsNil)
1256+
// wrappers.StartServices should receive them sorted
1257+
c.Check(sortedNames, DeepEquals, []string{"svc1", "svc3", "svc2"})
1258+
}
1259+
1260+
func (s *linkSuite) TestStartServicesFailsOnCycle(c *C) {
1261+
restore := backend.MockWrappersStartServices(func(apps []*snap.AppInfo, disabledSvcs *wrappers.DisabledServices, opts *wrappers.StartServicesOptions, inter wrappers.Interacter, tm timings.Measurer) error {
1262+
c.Fatal("wrappers.StartServices should not be called when sorting fails")
1263+
return nil
1264+
})
1265+
defer restore()
1266+
1267+
svc1 := &snap.AppInfo{Name: "svc1", After: []string{"svc2"}}
1268+
svc2 := &snap.AppInfo{Name: "svc2", After: []string{"svc1"}}
1269+
1270+
apps := []*snap.AppInfo{svc1, svc2}
1271+
err := s.be.StartServices(apps, nil, progress.Null, s.perfTimings)
1272+
c.Assert(err, ErrorMatches, "applications are part of a before/after cycle: .*")
1273+
}
1274+
12371275
type nullUndoer struct{}
12381276

12391277
func (nu nullUndoer) AddUndo(f func() error) {}

overlord/snapstate/backend_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,13 +1460,17 @@ func svcSnapMountDir(svcs []*snap.AppInfo) string {
14601460
}
14611461

14621462
func (f *fakeSnappyBackend) StartServices(svcs []*snap.AppInfo, disabledSvcs *wrappers.DisabledServices, meter progress.Meter, tm timings.Measurer) error {
1463-
services := make([]string, 0, len(svcs))
1464-
for _, svc := range svcs {
1463+
startupOrdered, err := snap.SortServices(svcs)
1464+
if err != nil {
1465+
return err
1466+
}
1467+
services := make([]string, 0, len(startupOrdered))
1468+
for _, svc := range startupOrdered {
14651469
services = append(services, svc.Name)
14661470
}
14671471
op := fakeOp{
14681472
op: "start-snap-services",
1469-
path: svcSnapMountDir(svcs),
1473+
path: svcSnapMountDir(startupOrdered),
14701474
services: services,
14711475
}
14721476
// only add the services to the op if there's something to add
@@ -1505,11 +1509,7 @@ func (f *fakeSnappyBackend) StopServices(svcs []*snap.AppInfo, rmSvcs map[string
15051509
}
15061510

15071511
undoer.AddUndo(func() error {
1508-
startupOrdered, err := snap.SortServices(svcs)
1509-
if err != nil {
1510-
return fmt.Errorf("cannot sort services for undo: %v", err)
1511-
}
1512-
return f.StartServices(startupOrdered, disabledSvcs, meter, tm)
1512+
return f.StartServices(svcs, disabledSvcs, meter, tm)
15131513
})
15141514

15151515
f.appendOp(&fakeOp{

overlord/snapstate/handlers.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3505,15 +3505,10 @@ func (m *SnapManager) startSnapServices(t *state.Task, _ *tomb.Tomb) error {
35053505
return nil
35063506
}
35073507

3508-
startupOrdered, err := snap.SortServices(svcs)
3509-
if err != nil {
3510-
return err
3511-
}
3512-
35133508
pb := NewTaskProgressAdapterUnlocked(t)
35143509

35153510
st.Unlock()
3516-
err = m.backend.StartServices(startupOrdered, &wrappers.DisabledServices{
3511+
err = m.backend.StartServices(svcs, &wrappers.DisabledServices{
35173512
SystemServices: missingSvcsOverview.FoundSystemServices,
35183513
UserServices: missingSvcsOverview.FoundUserServices,
35193514
}, pb, perfTimings)
@@ -3715,11 +3710,6 @@ func (m *SnapManager) undoStopSnapServices(t *state.Task, _ *tomb.Tomb) error {
37153710
return nil
37163711
}
37173712

3718-
startupOrdered, err := snap.SortServices(svcs)
3719-
if err != nil {
3720-
return err
3721-
}
3722-
37233713
var oldLastActiveDisabledServices []string
37243714
var oldLastActiveDisabledUserServices map[int][]string
37253715
if err := t.Get("old-last-active-disabled-services", &oldLastActiveDisabledServices); err != nil && !errors.Is(err, state.ErrNoState) {
@@ -3738,7 +3728,7 @@ func (m *SnapManager) undoStopSnapServices(t *state.Task, _ *tomb.Tomb) error {
37383728
}
37393729

37403730
st.Unlock()
3741-
err = m.backend.StartServices(startupOrdered, &disabledServices, progress.Null, perfTimings)
3731+
err = m.backend.StartServices(svcs, &disabledServices, progress.Null, perfTimings)
37423732
st.Lock()
37433733
if err != nil {
37443734
return err

0 commit comments

Comments
 (0)