diff options
| author | Miguel Pires <miguel.pires@canonical.com> | 2022-07-08 16:32:52 +0100 |
|---|---|---|
| committer | Miguel Pires <miguel.pires@canonical.com> | 2022-07-08 16:33:22 +0100 |
| commit | 824d87a4272effbbdff2c61f8d08eeaaefb4b0ec (patch) | |
| tree | 91872299d3e890646dde0a916bd77a0389c0fb49 | |
| parent | 5ed2c0b34484b74064b76419626b0a87959c469b (diff) | |
ifacestate: add shared iface schemas package
Signed-off-by: Miguel Pires <miguel.pires@canonical.com>
| -rw-r--r-- | cmd/snap/cmd_debug_state.go | 30 | ||||
| -rw-r--r-- | overlord/ifacestate/export_test.go | 11 | ||||
| -rw-r--r-- | overlord/ifacestate/handlers.go | 11 | ||||
| -rw-r--r-- | overlord/ifacestate/helpers.go | 41 | ||||
| -rw-r--r-- | overlord/ifacestate/schemas/schemas.go | 44 |
5 files changed, 75 insertions, 62 deletions
diff --git a/cmd/snap/cmd_debug_state.go b/cmd/snap/cmd_debug_state.go index 78eaa0ebd1..c54c077a89 100644 --- a/cmd/snap/cmd_debug_state.go +++ b/cmd/snap/cmd_debug_state.go @@ -34,6 +34,7 @@ import ( "github.com/snapcore/snapd/i18n" "github.com/snapcore/snapd/interfaces" + "github.com/snapcore/snapd/overlord/ifacestate/schemas" "github.com/snapcore/snapd/overlord/state" "github.com/snapcore/snapd/strutil" ) @@ -301,26 +302,13 @@ func (c *cmdDebugState) showIsSeeded(st *state.State) error { return nil } -// connState is the connection state stored by InterfaceManager -type connState struct { - Auto bool `json:"auto,omitempty" yaml:"auto"` - ByGadget bool `json:"by-gadget,omitempty" yaml:"by-gadget"` - Interface string `json:"interface,omitempty" yaml:"interface"` - Undesired bool `json:"undesired,omitempty" yaml:"undesired"` - StaticPlugAttrs map[string]interface{} `json:"plug-static,omitempty" yaml:"plug-static,omitempty"` - DynamicPlugAttrs map[string]interface{} `json:"plug-dynamic,omitempty" yaml:"plug-dynamic,omitempty"` - StaticSlotAttrs map[string]interface{} `json:"slot-static,omitempty" yaml:"slot-static,omitempty"` - DynamicSlotAttrs map[string]interface{} `json:"slot-dynamic,omitempty" yaml:"slot-dynamic,omitempty"` - // TODO: hotplug -} - type connectionInfo struct { PlugSnap string PlugName string SlotSnap string SlotName string - connState + schemas.Connection } type byPlug []*connectionInfo @@ -351,7 +339,7 @@ func (c *cmdDebugState) showConnectionDetails(st *state.State, connArg string) e } } - var conns map[string]*connState + var conns map[string]*schemas.Connection if err := st.Get("conns", &conns); err != nil && !errors.Is(err, state.ErrNoState) { return err } @@ -414,7 +402,7 @@ func (c *cmdDebugState) showConnections(st *state.State) error { st.Lock() defer st.Unlock() - var conns map[string]*connState + var conns map[string]*schemas.Connection if err := st.Get("conns", &conns); err != nil && !errors.Is(err, state.ErrNoState) { return err } @@ -429,11 +417,11 @@ func (c *cmdDebugState) showConnections(st *state.State) error { slot := strings.Split(p[1], ":") c := &connectionInfo{ - PlugSnap: plug[0], - PlugName: plug[1], - SlotSnap: slot[0], - SlotName: slot[1], - connState: *conn, + PlugSnap: plug[0], + PlugName: plug[1], + SlotSnap: slot[0], + SlotName: slot[1], + Connection: *conn, } all = append(all, c) } diff --git a/overlord/ifacestate/export_test.go b/overlord/ifacestate/export_test.go index c7c2d9f9d4..7946b37d27 100644 --- a/overlord/ifacestate/export_test.go +++ b/overlord/ifacestate/export_test.go @@ -21,6 +21,7 @@ import ( "time" "github.com/snapcore/snapd/interfaces" + "github.com/snapcore/snapd/overlord/ifacestate/schemas" "github.com/snapcore/snapd/overlord/ifacestate/udevmonitor" "github.com/snapcore/snapd/overlord/snapstate" "github.com/snapcore/snapd/overlord/state" @@ -125,19 +126,19 @@ func MockUDevInitRetryTimeout(t time.Duration) (restore func()) { // UpperCaseConnState returns a canned connection state map. // This allows us to keep connState private and still write some tests for it. -func UpperCaseConnState() map[string]*connState { - return map[string]*connState{ +func UpperCaseConnState() map[string]*schemas.Connection { + return map[string]*schemas.Connection{ "APP:network CORE:network": {Auto: true, Interface: "network"}, } } -func UpdateConnectionInConnState(conns map[string]*connState, conn *interfaces.Connection, autoConnect, byGadget, undesired, hotplugGone bool) { +func UpdateConnectionInConnState(conns map[string]*schemas.Connection, conn *interfaces.Connection, autoConnect, byGadget, undesired, hotplugGone bool) { connRef := &interfaces.ConnRef{ PlugRef: *conn.Plug.Ref(), SlotRef: *conn.Slot.Ref(), } - conns[connRef.ID()] = &connState{ + conns[connRef.ID()] = &schemas.Connection{ Interface: conn.Interface(), StaticPlugAttrs: conn.Plug.StaticAttrs(), DynamicPlugAttrs: conn.Plug.DynamicAttrs(), @@ -150,7 +151,7 @@ func UpdateConnectionInConnState(conns map[string]*connState, conn *interfaces.C } } -func GetConnStateAttrs(conns map[string]*connState, connID string) (plugStatic, plugDynamic, slotStatic, SlotDynamic map[string]interface{}, ok bool) { +func GetConnStateAttrs(conns map[string]*schemas.Connection, connID string) (plugStatic, plugDynamic, slotStatic, SlotDynamic map[string]interface{}, ok bool) { conn, ok := conns[connID] if !ok { return nil, nil, nil, nil, false diff --git a/overlord/ifacestate/handlers.go b/overlord/ifacestate/handlers.go index 2e3298657c..b83a5ea995 100644 --- a/overlord/ifacestate/handlers.go +++ b/overlord/ifacestate/handlers.go @@ -36,6 +36,7 @@ import ( "github.com/snapcore/snapd/interfaces/hotplug" "github.com/snapcore/snapd/logger" "github.com/snapcore/snapd/overlord/hookstate" + "github.com/snapcore/snapd/overlord/ifacestate/schemas" "github.com/snapcore/snapd/overlord/servicestate" "github.com/snapcore/snapd/overlord/snapstate" "github.com/snapcore/snapd/overlord/state" @@ -384,7 +385,7 @@ func (m *InterfaceManager) doDiscardConns(task *state.Task, _ *tomb.Tomb) error if err != nil { return err } - removed := make(map[string]*connState) + removed := make(map[string]*schemas.Connection) for id := range conns { connRef, err := interfaces.ParseConnRef(id) if err != nil { @@ -405,7 +406,7 @@ func (m *InterfaceManager) undoDiscardConns(task *state.Task, _ *tomb.Tomb) erro st.Lock() defer st.Unlock() - var removed map[string]*connState + var removed map[string]*schemas.Connection err := task.Get("removed", &removed) if err != nil && !errors.Is(err, state.ErrNoState) { return err @@ -584,7 +585,7 @@ func (m *InterfaceManager) doConnect(task *state.Task, _ *tomb.Tomb) (err error) task.Set("old-conn", old) } - conns[connRef.ID()] = &connState{ + conns[connRef.ID()] = &schemas.Connection{ Interface: conn.Interface(), StaticPlugAttrs: conn.Plug.StaticAttrs(), DynamicPlugAttrs: conn.Plug.DynamicAttrs(), @@ -720,7 +721,7 @@ func (m *InterfaceManager) undoDisconnect(task *state.Task, _ *tomb.Tomb) error perfTimings := state.TimingsForTask(task) defer perfTimings.Save(st) - var oldconn connState + var oldconn schemas.Connection err := task.Get("old-conn", &oldconn) if errors.Is(err, state.ErrNoState) { return nil @@ -817,7 +818,7 @@ func (m *InterfaceManager) undoConnect(task *state.Task, _ *tomb.Tomb) error { return err } - var old connState + var old schemas.Connection err = task.Get("old-conn", &old) if err != nil && !errors.Is(err, state.ErrNoState) { return err diff --git a/overlord/ifacestate/helpers.go b/overlord/ifacestate/helpers.go index 310e847dfe..880d749508 100644 --- a/overlord/ifacestate/helpers.go +++ b/overlord/ifacestate/helpers.go @@ -38,6 +38,7 @@ import ( "github.com/snapcore/snapd/jsonutil" "github.com/snapcore/snapd/logger" "github.com/snapcore/snapd/overlord/assertstate" + "github.com/snapcore/snapd/overlord/ifacestate/schemas" "github.com/snapcore/snapd/overlord/snapstate" "github.com/snapcore/snapd/overlord/state" "github.com/snapcore/snapd/snap" @@ -521,28 +522,6 @@ func addHotplugSlot(st *state.State, repo *interfaces.Repository, stateSlots map return nil } -// connState holds properties of a connection. -// Changes to connState should be reflected in cmd_debug_state.go. -type connState struct { - Auto bool `json:"auto,omitempty"` - ByGadget bool `json:"by-gadget,omitempty"` - Interface string `json:"interface,omitempty"` - // Undesired tracks connections that were manually disconnected after being auto-connected, - // so that they are not automatically reconnected again in the future. - Undesired bool `json:"undesired,omitempty"` - StaticPlugAttrs map[string]interface{} `json:"plug-static,omitempty"` - DynamicPlugAttrs map[string]interface{} `json:"plug-dynamic,omitempty"` - StaticSlotAttrs map[string]interface{} `json:"slot-static,omitempty"` - DynamicSlotAttrs map[string]interface{} `json:"slot-dynamic,omitempty"` - // Hotplug-related attributes: HotplugGone indicates a connection that - // disappeared because the device was removed, but may potentially be - // restored in the future if we see the device again. HotplugKey is the - // key of the associated device; it's empty for connections of regular - // slots. - HotplugGone bool `json:"hotplug-gone,omitempty"` - HotplugKey snap.HotplugKey `json:"hotplug-key,omitempty"` -} - type gadgetConnect struct { st *state.State task *state.Task @@ -566,7 +545,7 @@ func newGadgetConnect(s *state.State, task *state.Task, repo *interfaces.Reposit // addGadgetConnections adds to newconns any applicable connections // from the gadget connections stanza. // conflictError is called to handle checkAutoconnectConflicts errors. -func (gc *gadgetConnect) addGadgetConnections(newconns map[string]*interfaces.ConnRef, conns map[string]*connState, conflictError func(*state.Retry, error) error) error { +func (gc *gadgetConnect) addGadgetConnections(newconns map[string]*interfaces.ConnRef, conns map[string]*schemas.Connection, conflictError func(*state.Retry, error) error) error { var seeded bool err := gc.st.Get("seeded", &seeded) if err != nil && !errors.Is(err, state.ErrNoState) { @@ -653,7 +632,7 @@ func (gc *gadgetConnect) addGadgetConnections(newconns map[string]*interfaces.Co return nil } -func addNewConnection(st *state.State, task *state.Task, newconns map[string]*interfaces.ConnRef, conns map[string]*connState, plug *snap.PlugInfo, slot *snap.SlotInfo, conflictError func(*state.Retry, error) error) error { +func addNewConnection(st *state.State, task *state.Task, newconns map[string]*interfaces.ConnRef, conns map[string]*schemas.Connection, plug *snap.PlugInfo, slot *snap.SlotInfo, conflictError func(*state.Retry, error) error) error { connRef := interfaces.NewConnRef(plug, slot) key := connRef.ID() if _, ok := conns[key]; ok { @@ -815,7 +794,7 @@ func filterUbuntuCoreSlots(candidates []*snap.SlotInfo, arities []interfaces.Sid // conns. cannotAutoConnectLog is called to build a log message in // case no applicable pair was found. conflictError is called // to handle checkAutoconnectConflicts errors. -func (c *autoConnectChecker) addAutoConnections(newconns map[string]*interfaces.ConnRef, plugs []*snap.PlugInfo, filter func([]*snap.SlotInfo) []*snap.SlotInfo, conns map[string]*connState, cannotAutoConnectLog func(plug *snap.PlugInfo, candRefs []string) string, conflictError func(*state.Retry, error) error) error { +func (c *autoConnectChecker) addAutoConnections(newconns map[string]*interfaces.ConnRef, plugs []*snap.PlugInfo, filter func([]*snap.SlotInfo) []*snap.SlotInfo, conns map[string]*schemas.Connection, cannotAutoConnectLog func(plug *snap.PlugInfo, candRefs []string) string, conflictError func(*state.Retry, error) error) error { for _, plug := range plugs { candSlots, arities := c.repo.AutoConnectCandidateSlots(plug.Snap.InstanceName(), plug.Name, c.check) @@ -950,7 +929,7 @@ func getPlugAndSlotRefs(task *state.Task) (interfaces.PlugRef, interfaces.SlotRe // getConns returns information about connections from the state. // // Connections are transparently re-mapped according to remapIncomingConnRef -func getConns(st *state.State) (conns map[string]*connState, err error) { +func getConns(st *state.State) (conns map[string]*schemas.Connection, err error) { var raw *json.RawMessage err = st.Get("conns", &raw) if err != nil && !errors.Is(err, state.ErrNoState) { @@ -963,9 +942,9 @@ func getConns(st *state.State) (conns map[string]*connState, err error) { } } if conns == nil { - conns = make(map[string]*connState) + conns = make(map[string]*schemas.Connection) } - remapped := make(map[string]*connState, len(conns)) + remapped := make(map[string]*schemas.Connection, len(conns)) for id, cstate := range conns { cref, err := interfaces.ParseConnRef(id) if err != nil { @@ -985,8 +964,8 @@ func getConns(st *state.State) (conns map[string]*connState, err error) { // setConns sets information about connections in the state. // // Connections are transparently re-mapped according to remapOutgoingConnRef -func setConns(st *state.State, conns map[string]*connState) { - remapped := make(map[string]*connState, len(conns)) +func setConns(st *state.State, conns map[string]*schemas.Connection) { + remapped := make(map[string]*schemas.Connection, len(conns)) for id, cstate := range conns { cref, err := interfaces.ParseConnRef(id) if err != nil { @@ -1320,7 +1299,7 @@ func findHotplugSlot(stateSlots map[string]*HotplugSlotInfo, ifaceName string, h return nil } -func findConnsForHotplugKey(conns map[string]*connState, ifaceName string, hotplugKey snap.HotplugKey) []string { +func findConnsForHotplugKey(conns map[string]*schemas.Connection, ifaceName string, hotplugKey snap.HotplugKey) []string { var connsForDevice []string for id, connSt := range conns { if connSt.Interface != ifaceName || connSt.HotplugKey != hotplugKey { diff --git a/overlord/ifacestate/schemas/schemas.go b/overlord/ifacestate/schemas/schemas.go new file mode 100644 index 0000000000..34ba31c302 --- /dev/null +++ b/overlord/ifacestate/schemas/schemas.go @@ -0,0 +1,44 @@ +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2022 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +// Package schemas holds structs for reading and writing interface-related data. +package schemas + +import "github.com/snapcore/snapd/snap" + +// Connection holds properties of an interface connection. +type Connection struct { + Auto bool `json:"auto,omitempty" yaml:"auto"` + ByGadget bool `json:"by-gadget,omitempty" yaml:"by-gadget"` + Interface string `json:"interface,omitempty" yaml:"interface"` + // Undesired tracks connections that were manually disconnected after being auto-connected, + // so that they are not automatically reconnected again in the future. + Undesired bool `json:"undesired,omitempty" yaml:"undesired"` + StaticPlugAttrs map[string]interface{} `json:"plug-static,omitempty" yaml:"plug-static,omitempty"` + DynamicPlugAttrs map[string]interface{} `json:"plug-dynamic,omitempty" yaml:"plug-dynamic,omitempty"` + StaticSlotAttrs map[string]interface{} `json:"slot-static,omitempty" yaml:"slot-static,omitempty"` + DynamicSlotAttrs map[string]interface{} `json:"slot-dynamic,omitempty" yaml:"slot-dynamic,omitempty"` + // Hotplug-related attributes: HotplugGone indicates a connection that + // disappeared because the device was removed, but may potentially be + // restored in the future if we see the device again. HotplugKey is the + // key of the associated device; it's empty for connections of regular + // slots. + HotplugGone bool `json:"hotplug-gone,omitempty" yaml:"hotplug-gone,omitempty"` + HotplugKey snap.HotplugKey `json:"hotplug-key,omitempty" yaml:"hotplug-key,omitempty"` +} |
