forked from snapcore/snapd
/
implicit.go
99 lines (87 loc) · 2.93 KB
/
implicit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2016-2017 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 ifacestate
import (
"fmt"
"github.com/snapcore/snapd/interfaces"
"github.com/snapcore/snapd/interfaces/builtin"
"github.com/snapcore/snapd/overlord/state"
"github.com/snapcore/snapd/release"
"github.com/snapcore/snapd/snap"
)
func shouldSnapdHostImplicitSlots(mapper SnapMapper) bool {
_, ok := mapper.(*CoreSnapdSystemMapper)
return ok
}
// addImplicitSlots adds implicitly defined slots and hotplug slots to a given snap.
//
// Only the OS snap has implicit and hotplug slots.
//
// It is assumed that slots have names matching the interface name. Existing
// slots are not changed, only missing slots are added.
func addImplicitSlots(st *state.State, snapInfo *snap.Info) error {
// Implicit slots can be added to the special "snapd" snap or to snaps with
// type "os". Currently there are no other snaps that gain implicit
// interfaces.
if snapInfo.Type() != snap.TypeOS && snapInfo.Type() != snap.TypeSnapd {
return nil
}
// If the manager has chosen to put implicit slots on the "snapd" snap
// then stop adding them to any other core snaps.
if shouldSnapdHostImplicitSlots(mapper) && snapInfo.Type() != snap.TypeSnapd {
return nil
}
hotplugSlots, err := getHotplugSlots(st)
if err != nil {
return err
}
// Ask each interface if it wants to be implicitly added.
for _, iface := range builtin.Interfaces() {
si := interfaces.StaticInfoOf(iface)
if (release.OnClassic && si.ImplicitOnClassic) || (!release.OnClassic && si.ImplicitOnCore) {
ifaceName := iface.Name()
if _, ok := snapInfo.Slots[ifaceName]; !ok {
snapInfo.Slots[ifaceName] = makeImplicitSlot(snapInfo, ifaceName)
}
}
}
// Add hotplug slots
for _, hslotInfo := range hotplugSlots {
if _, ok := snapInfo.Slots[hslotInfo.Name]; ok {
return fmt.Errorf("cannot add hotplug slot %s: slot already exists", hslotInfo.Name)
}
if hslotInfo.HotplugGone {
continue
}
snapInfo.Slots[hslotInfo.Name] = &snap.SlotInfo{
Name: hslotInfo.Name,
Snap: snapInfo,
Interface: hslotInfo.Interface,
Attrs: hslotInfo.StaticAttrs,
HotplugKey: hslotInfo.HotplugKey,
}
}
return nil
}
func makeImplicitSlot(snapInfo *snap.Info, ifaceName string) *snap.SlotInfo {
return &snap.SlotInfo{
Name: ifaceName,
Snap: snapInfo,
Interface: ifaceName,
}
}