gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/common.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016-2018 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 "io/ioutil" 24 "path/filepath" 25 26 "gitee.com/mysnapcore/mysnapd/interfaces" 27 "gitee.com/mysnapcore/mysnapd/interfaces/apparmor" 28 "gitee.com/mysnapcore/mysnapd/interfaces/kmod" 29 "gitee.com/mysnapcore/mysnapd/interfaces/mount" 30 "gitee.com/mysnapcore/mysnapd/interfaces/seccomp" 31 "gitee.com/mysnapcore/mysnapd/interfaces/udev" 32 "gitee.com/mysnapcore/mysnapd/osutil" 33 "gitee.com/mysnapcore/mysnapd/snap" 34 ) 35 36 // evalSymlinks is either filepath.EvalSymlinks or a mocked function for 37 // applicable for testing. 38 var evalSymlinks = filepath.EvalSymlinks 39 40 // readDir is either ioutil.ReadDir or a mocked function for applicable for 41 // testing. 42 var readDir = ioutil.ReadDir 43 44 type commonInterface struct { 45 name string 46 summary string 47 docURL string 48 49 implicitOnCore bool 50 implicitOnClassic bool 51 52 affectsPlugOnRefresh bool 53 54 baseDeclarationPlugs string 55 baseDeclarationSlots string 56 57 connectedPlugAppArmor string 58 connectedPlugSecComp string 59 connectedPlugUDev []string 60 rejectAutoConnectPairs bool 61 62 connectedPlugUpdateNSAppArmor string 63 connectedPlugMount []osutil.MountEntry 64 65 connectedPlugKModModules []string 66 connectedSlotKModModules []string 67 permanentPlugKModModules []string 68 permanentSlotKModModules []string 69 70 usesPtraceTrace bool 71 suppressPtraceTrace bool 72 suppressHomeIx bool 73 usesSysModuleCapability bool 74 suppressSysModuleCapability bool 75 76 controlsDeviceCgroup bool 77 78 serviceSnippets []string 79 } 80 81 // Name returns the interface name. 82 func (iface *commonInterface) Name() string { 83 return iface.name 84 } 85 86 // StaticInfo returns various meta-data about this interface. 87 func (iface *commonInterface) StaticInfo() interfaces.StaticInfo { 88 return interfaces.StaticInfo{ 89 Summary: iface.summary, 90 DocURL: iface.docURL, 91 ImplicitOnCore: iface.implicitOnCore, 92 ImplicitOnClassic: iface.implicitOnClassic, 93 BaseDeclarationPlugs: iface.baseDeclarationPlugs, 94 BaseDeclarationSlots: iface.baseDeclarationSlots, 95 // affects the plug snap because of mount backend 96 AffectsPlugOnRefresh: iface.affectsPlugOnRefresh, 97 } 98 } 99 100 func (iface *commonInterface) ServicePermanentPlug(plug *snap.PlugInfo) []string { 101 return iface.serviceSnippets 102 } 103 104 func (iface *commonInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 105 if iface.usesPtraceTrace { 106 spec.SetUsesPtraceTrace() 107 } else if iface.suppressPtraceTrace { 108 spec.SetSuppressPtraceTrace() 109 } 110 if iface.suppressHomeIx { 111 spec.SetSuppressHomeIx() 112 } 113 if iface.usesSysModuleCapability { 114 spec.SetUsesSysModuleCapability() 115 } else if iface.suppressSysModuleCapability { 116 spec.SetSuppressSysModuleCapability() 117 } 118 if snippet := iface.connectedPlugAppArmor; snippet != "" { 119 spec.AddSnippet(snippet) 120 } 121 if snippet := iface.connectedPlugUpdateNSAppArmor; snippet != "" { 122 spec.AddUpdateNS(snippet) 123 } 124 return nil 125 } 126 127 // AutoConnect returns whether plug and slot should be implicitly 128 // auto-connected assuming they will be an unambiguous connection 129 // candidate and declaration-based checks allow. 130 // 131 // By default we allow what declarations allowed. 132 func (iface *commonInterface) AutoConnect(*snap.PlugInfo, *snap.SlotInfo) bool { 133 return !iface.rejectAutoConnectPairs 134 } 135 136 func (iface *commonInterface) KModConnectedPlug(spec *kmod.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 137 for _, m := range iface.connectedPlugKModModules { 138 if err := spec.AddModule(m); err != nil { 139 return err 140 } 141 } 142 return nil 143 } 144 145 func (iface *commonInterface) KModConnectedSlot(spec *kmod.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 146 for _, m := range iface.connectedSlotKModModules { 147 if err := spec.AddModule(m); err != nil { 148 return err 149 } 150 } 151 return nil 152 } 153 154 func (iface *commonInterface) MountConnectedPlug(spec *mount.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 155 for _, entry := range iface.connectedPlugMount { 156 if err := spec.AddMountEntry(entry); err != nil { 157 return err 158 } 159 } 160 return nil 161 } 162 163 func (iface *commonInterface) KModPermanentPlug(spec *kmod.Specification, plug *snap.PlugInfo) error { 164 for _, m := range iface.permanentPlugKModModules { 165 if err := spec.AddModule(m); err != nil { 166 return err 167 } 168 } 169 return nil 170 } 171 172 func (iface *commonInterface) KModPermanentSlot(spec *kmod.Specification, slot *snap.SlotInfo) error { 173 for _, m := range iface.permanentSlotKModModules { 174 if err := spec.AddModule(m); err != nil { 175 return err 176 } 177 } 178 return nil 179 } 180 181 func (iface *commonInterface) SecCompConnectedPlug(spec *seccomp.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 182 if iface.connectedPlugSecComp != "" { 183 spec.AddSnippet(iface.connectedPlugSecComp) 184 } 185 return nil 186 } 187 188 func (iface *commonInterface) UDevConnectedPlug(spec *udev.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 189 // don't tag devices if the interface controls it's own device cgroup 190 if iface.controlsDeviceCgroup { 191 spec.SetControlsDeviceCgroup() 192 } else { 193 for _, rule := range iface.connectedPlugUDev { 194 spec.TagDevice(rule) 195 } 196 } 197 198 return nil 199 }