diff options
| author | Michael Vogt <mvo@ubuntu.com> | 2018-08-16 17:34:14 +0200 |
|---|---|---|
| committer | Michael Vogt <mvo@ubuntu.com> | 2018-08-16 17:34:17 +0200 |
| commit | d50c078a649d1a89b4b4ec10389fb6a6588aab4e (patch) | |
| tree | a9d4fcbc41f5405417ac797889d4948b7076bebe | |
| parent | 23c5acfd807b4537e62b2b6aa40080f326372023 (diff) | |
ifstate: extra common code into checkAutoConflicts()conflicts-check-simplify
We current have two similar helpers to check conflicts for auto connect and auto disconnect. This PR extracts the common bits into shared code with some extra checks that each of the two helpers performs.
| -rw-r--r-- | overlord/ifacestate/handlers.go | 52 |
1 files changed, 19 insertions, 33 deletions
diff --git a/overlord/ifacestate/handlers.go b/overlord/ifacestate/handlers.go index 0571dd5cc4..bf5e9aa9a6 100644 --- a/overlord/ifacestate/handlers.go +++ b/overlord/ifacestate/handlers.go @@ -631,7 +631,7 @@ func (m *InterfaceManager) defaultContentProviders(snapName string) map[string]b return defaultProviders } -func checkAutoconnectConflicts(st *state.State, plugSnap, slotSnap string) error { +func checkAutoConflicts(st *state.State, plugSnap, slotSnap string, extraCheck func(t *state.Task) error) error { for _, task := range st.Tasks() { if task.Status().Ready() { continue @@ -665,55 +665,41 @@ func checkAutoconnectConflicts(st *state.State, plugSnap, slotSnap string) error continue } + if err := extraCheck(task); err != nil { + return err + } + } + return nil +} + +func checkAutoconnectConflicts(st *state.State, plugSnap, slotSnap string) error { + return checkAutoConflicts(st, plugSnap, slotSnap, func(task *state.Task) error { + k := task.Kind() // other snap that affects us because of plug or slot if k == "unlink-snap" || k == "link-snap" || k == "setup-profiles" { // if snap is getting removed, we will retry but the snap will be gone and auto-connect becomes no-op // if snap is getting installed/refreshed - temporary conflict, retry later return &state.Retry{After: connectRetryTimeout} } - } - return nil + return nil + }) } func checkDisconnectConflicts(st *state.State, disconnectingSnap, plugSnap, slotSnap string) error { - for _, task := range st.Tasks() { - if task.Status().Ready() { - continue - } - - k := task.Kind() - if k == "connect" || k == "disconnect" { - // retry if we found another connect/disconnect affecting same snap; note we can only encounter - // connects/disconnects created by doAutoDisconnect / doAutoConnect here as manual interface ops - // are rejected by conflict check logic in snapstate. - plugRef, slotRef, err := getPlugAndSlotRefs(task) - if err != nil { - return err - } - if plugRef.Snap == plugSnap || slotRef.Snap == slotSnap { - return &state.Retry{After: connectRetryTimeout} - } - continue - } - + return checkAutoConflicts(st, plugSnap, slotSnap, func(task *state.Task) error { snapsup, err := snapstate.TaskSnapSetup(task) // e.g. hook tasks don't have task snap setup if err != nil { - continue + return nil } - otherSnapName := snapsup.InstanceName() - // different snaps - no conflict - if otherSnapName != plugSnap && otherSnapName != slotSnap { - continue - } - // another task related to same snap op (unrelated op would be blocked by snapstate conflict logic) if otherSnapName == disconnectingSnap { - continue + return nil } + k := task.Kind() // note, don't care about unlink-snap for the opposite end. This relies // on the fact that auto-disconnect will create conflicting "disconnect" tasks that // we will retry with the logic above. @@ -721,8 +707,8 @@ func checkDisconnectConflicts(st *state.State, disconnectingSnap, plugSnap, slot // other snap is getting installed/refreshed - temporary conflict return &state.Retry{After: connectRetryTimeout} } - } - return nil + return nil + }) } // doAutoConnect creates task(s) to connect the given snap to viable candidates. |
