github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/interfaces/hotplug/proposed_slot.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2019 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 hotplug 21 22 import ( 23 "github.com/snapcore/snapd/interfaces/utils" 24 "github.com/snapcore/snapd/snap" 25 ) 26 27 // Definer can be implemented by interfaces that need to create slots in response to hotplug events. 28 type Definer interface { 29 // HotplugDeviceDetected is called for all devices and should return nil slot for those that are irrelevant for the interface. 30 // Error should only be returned in rare cases when device is relevant, but there is a problem with creating a proposed slot for it. 31 HotplugDeviceDetected(di *HotplugDeviceInfo) (*ProposedSlot, error) 32 } 33 34 // HotplugKeyHandler can be implemented by interfaces that need to provide a non-standard key for hotplug devices. 35 type HotplugKeyHandler interface { 36 HotplugKey(di *HotplugDeviceInfo) (snap.HotplugKey, error) 37 } 38 39 // HandledByGadgetPredicate can be implemented by hotplug interfaces to decide whether a device is already handled by given gadget slot. 40 type HandledByGadgetPredicate interface { 41 HandledByGadget(di *HotplugDeviceInfo, slot *snap.SlotInfo) bool 42 } 43 44 // ProposedSlot is a definition of the slot to create in response to a hotplug event. 45 type ProposedSlot struct { 46 // Name is how the interface wants to name the slot. When left empty, 47 // one will be generated on demand. The hotplug machinery appends a 48 // suffix to ensure uniqueness of the name. 49 Name string `json:"name"` 50 Label string `json:"label"` 51 Attrs map[string]interface{} `json:"attrs,omitempty"` 52 } 53 54 // Clean returns a copy of the input slot with normalized attributes and validated slot name (unless its empty). 55 func (slot *ProposedSlot) Clean() (*ProposedSlot, error) { 56 // only validate name if not empty, otherwise name is created by hotplug 57 // subsystem later on when the proposed slot is processed. 58 if slot.Name != "" { 59 if err := snap.ValidateSlotName(slot.Name); err != nil { 60 return nil, err 61 } 62 } 63 attrs := slot.Attrs 64 if attrs == nil { 65 attrs = make(map[string]interface{}) 66 } 67 68 return &ProposedSlot{ 69 Name: slot.Name, 70 Label: slot.Label, 71 Attrs: utils.NormalizeInterfaceAttributes(attrs).(map[string]interface{}), 72 }, nil 73 }