github.com/bugraaydogar/snapd@v0.0.0-20210315170335-8c70bb858939/interfaces/systemd/spec.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016-2017 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 systemd 21 22 import ( 23 "fmt" 24 25 "github.com/snapcore/snapd/interfaces" 26 "github.com/snapcore/snapd/snap" 27 ) 28 29 // Specification assists in collecting custom systemd services associated with an interface. 30 // 31 // Unlike the Backend itself (which is stateless and non-persistent) this type 32 // holds internal state that is used by the mount backend during the interface 33 // setup process. 34 type Specification struct { 35 services map[string]*Service 36 } 37 38 // AddService adds a new systemd service unit. 39 func (spec *Specification) AddService(name string, s *Service) error { 40 if old, ok := spec.services[name]; ok && old != nil && s != nil && *old != *s { 41 return fmt.Errorf("interface requires conflicting system needs: service %q used to be defined as %#v, now re-defined as %#v", name, *old, *s) 42 } 43 if spec.services == nil { 44 spec.services = make(map[string]*Service) 45 } 46 spec.services[name] = s 47 return nil 48 } 49 50 // Services returns a deep copy of all the added services. 51 func (spec *Specification) Services() map[string]*Service { 52 if spec.services == nil { 53 return nil 54 } 55 result := make(map[string]*Service, len(spec.services)) 56 for k, v := range spec.services { 57 svc := *v 58 result[k] = &svc 59 } 60 return result 61 } 62 63 // Implementation of methods required by interfaces.Specification 64 65 // AddConnectedPlug records systemd-specific side-effects of having a connected plug. 66 func (spec *Specification) AddConnectedPlug(iface interfaces.Interface, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 67 type definer interface { 68 SystemdConnectedPlug(spec *Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error 69 } 70 if iface, ok := iface.(definer); ok { 71 return iface.SystemdConnectedPlug(spec, plug, slot) 72 } 73 return nil 74 } 75 76 // AddConnectedSlot records systemd-specific side-effects of having a connected slot. 77 func (spec *Specification) AddConnectedSlot(iface interfaces.Interface, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 78 type definer interface { 79 SystemdConnectedSlot(spec *Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error 80 } 81 if iface, ok := iface.(definer); ok { 82 return iface.SystemdConnectedSlot(spec, plug, slot) 83 } 84 return nil 85 } 86 87 // AddPermanentPlug records systemd-specific side-effects of having a plug. 88 func (spec *Specification) AddPermanentPlug(iface interfaces.Interface, plug *snap.PlugInfo) error { 89 type definer interface { 90 SystemdPermanentPlug(spec *Specification, plug *snap.PlugInfo) error 91 } 92 if iface, ok := iface.(definer); ok { 93 return iface.SystemdPermanentPlug(spec, plug) 94 } 95 return nil 96 } 97 98 // AddPermanentSlot records systemd-specific side-effects of having a slot. 99 func (spec *Specification) AddPermanentSlot(iface interfaces.Interface, slot *snap.SlotInfo) error { 100 type definer interface { 101 SystemdPermanentSlot(spec *Specification, slot *snap.SlotInfo) error 102 } 103 if iface, ok := iface.(definer); ok { 104 return iface.SystemdPermanentSlot(spec, slot) 105 } 106 return nil 107 }