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  }