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  }