gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/all.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package builtin 21 22 import ( 23 "fmt" 24 "sort" 25 26 "gitee.com/mysnapcore/mysnapd/interfaces" 27 "gitee.com/mysnapcore/mysnapd/snap" 28 ) 29 30 func init() { 31 snap.SanitizePlugsSlots = SanitizePlugsSlots 32 33 // setup the ByName function using allInterfaces 34 interfaces.ByName = func(name string) (interfaces.Interface, error) { 35 iface, ok := allInterfaces[name] 36 if !ok { 37 return nil, fmt.Errorf("interface %q not found", name) 38 } 39 return iface, nil 40 } 41 } 42 43 var ( 44 allInterfaces map[string]interfaces.Interface 45 ) 46 47 // Interfaces returns all of the built-in interfaces. 48 func Interfaces() []interfaces.Interface { 49 ifaces := make([]interfaces.Interface, 0, len(allInterfaces)) 50 for _, iface := range allInterfaces { 51 ifaces = append(ifaces, iface) 52 } 53 sort.Sort(byIfaceName(ifaces)) 54 return ifaces 55 } 56 57 // registerIface appends the given interface into the list of all known interfaces. 58 func registerIface(iface interfaces.Interface) { 59 if allInterfaces[iface.Name()] != nil { 60 panic(fmt.Errorf("cannot register duplicate interface %q", iface.Name())) 61 } 62 if allInterfaces == nil { 63 allInterfaces = make(map[string]interfaces.Interface) 64 } 65 allInterfaces[iface.Name()] = iface 66 } 67 68 func SanitizePlugsSlots(snapInfo *snap.Info) { 69 var badPlugs []string 70 var badSlots []string 71 72 for plugName, plugInfo := range snapInfo.Plugs { 73 iface, ok := allInterfaces[plugInfo.Interface] 74 if !ok { 75 snapInfo.BadInterfaces[plugName] = fmt.Sprintf("unknown interface %q", plugInfo.Interface) 76 badPlugs = append(badPlugs, plugName) 77 continue 78 } 79 // Reject plug with invalid name 80 if err := snap.ValidatePlugName(plugName); err != nil { 81 snapInfo.BadInterfaces[plugName] = err.Error() 82 badPlugs = append(badPlugs, plugName) 83 continue 84 } 85 if err := interfaces.BeforePreparePlug(iface, plugInfo); err != nil { 86 snapInfo.BadInterfaces[plugName] = err.Error() 87 badPlugs = append(badPlugs, plugName) 88 continue 89 } 90 } 91 92 for slotName, slotInfo := range snapInfo.Slots { 93 iface, ok := allInterfaces[slotInfo.Interface] 94 if !ok { 95 snapInfo.BadInterfaces[slotName] = fmt.Sprintf("unknown interface %q", slotInfo.Interface) 96 badSlots = append(badSlots, slotName) 97 continue 98 } 99 // Reject slot with invalid name 100 if err := snap.ValidateSlotName(slotName); err != nil { 101 snapInfo.BadInterfaces[slotName] = err.Error() 102 badSlots = append(badSlots, slotName) 103 continue 104 } 105 if err := interfaces.BeforePrepareSlot(iface, slotInfo); err != nil { 106 snapInfo.BadInterfaces[slotName] = err.Error() 107 badSlots = append(badSlots, slotName) 108 continue 109 } 110 } 111 112 // remove any bad plugs and slots 113 for _, plugName := range badPlugs { 114 delete(snapInfo.Plugs, plugName) 115 for _, app := range snapInfo.Apps { 116 delete(app.Plugs, plugName) 117 } 118 for _, hook := range snapInfo.Hooks { 119 delete(hook.Plugs, plugName) 120 } 121 } 122 for _, slotName := range badSlots { 123 delete(snapInfo.Slots, slotName) 124 for _, app := range snapInfo.Apps { 125 delete(app.Slots, slotName) 126 127 var activatesOn []*snap.SlotInfo 128 for _, slot := range app.ActivatesOn { 129 if slot.Name != slotName { 130 activatesOn = append(activatesOn, slot) 131 } 132 } 133 app.ActivatesOn = activatesOn 134 } 135 for _, hook := range snapInfo.Hooks { 136 delete(hook.Slots, slotName) 137 } 138 } 139 } 140 141 func MockInterface(iface interfaces.Interface) func() { 142 name := iface.Name() 143 allInterfaces[name] = iface 144 return func() { 145 delete(allInterfaces, name) 146 } 147 } 148 149 type byIfaceName []interfaces.Interface 150 151 func (c byIfaceName) Len() int { return len(c) } 152 func (c byIfaceName) Swap(i, j int) { c[i], c[j] = c[j], c[i] } 153 func (c byIfaceName) Less(i, j int) bool { 154 return c[i].Name() < c[j].Name() 155 }