summaryrefslogtreecommitdiff
diff options
authorMiguel Pires <miguel.pires@canonical.com>2022-07-08 16:32:52 +0100
committerMiguel Pires <miguel.pires@canonical.com>2022-07-08 16:33:22 +0100
commit824d87a4272effbbdff2c61f8d08eeaaefb4b0ec (patch)
tree91872299d3e890646dde0a916bd77a0389c0fb49
parent5ed2c0b34484b74064b76419626b0a87959c469b (diff)
ifacestate: add shared iface schemas package
Signed-off-by: Miguel Pires <miguel.pires@canonical.com>
-rw-r--r--cmd/snap/cmd_debug_state.go30
-rw-r--r--overlord/ifacestate/export_test.go11
-rw-r--r--overlord/ifacestate/handlers.go11
-rw-r--r--overlord/ifacestate/helpers.go41
-rw-r--r--overlord/ifacestate/schemas/schemas.go44
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"`
+}