github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/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  }