github.com/rigado/snapd@v2.42.5-go-mod+incompatible/interfaces/builtin/utils.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  	"bytes"
    24  	"fmt"
    25  	"sort"
    26  
    27  	"github.com/snapcore/snapd/interfaces"
    28  	"github.com/snapcore/snapd/release"
    29  	"github.com/snapcore/snapd/snap"
    30  )
    31  
    32  // The maximum number of Usb bInterfaceNumber.
    33  const UsbMaxInterfaces = 32
    34  
    35  // AppLabelExpr returns the specification of the apparmor label describing
    36  // all the apps bound to a given slot. The result has one of three forms,
    37  // depending on how apps are bound to the slot:
    38  //
    39  // - "snap.$snap_instance.$app" if there is exactly one app bound
    40  // - "snap.$snap_instance.{$app1,...$appN}" if there are some, but not all, apps bound
    41  // - "snap.$snap_instance.*" if all apps are bound to the slot
    42  func appLabelExpr(apps map[string]*snap.AppInfo, snap *snap.Info) string {
    43  	var buf bytes.Buffer
    44  	fmt.Fprintf(&buf, `"snap.%s.`, snap.InstanceName())
    45  	if len(apps) == 1 {
    46  		for appName := range apps {
    47  			buf.WriteString(appName)
    48  		}
    49  	} else if len(apps) == len(snap.Apps) {
    50  		buf.WriteByte('*')
    51  	} else {
    52  		appNames := make([]string, 0, len(apps))
    53  		for appName := range apps {
    54  			appNames = append(appNames, appName)
    55  		}
    56  		sort.Strings(appNames)
    57  		buf.WriteByte('{')
    58  		for _, appName := range appNames {
    59  			buf.WriteString(appName)
    60  			buf.WriteByte(',')
    61  		}
    62  		buf.Truncate(buf.Len() - 1)
    63  		buf.WriteByte('}')
    64  	}
    65  	buf.WriteByte('"')
    66  	return buf.String()
    67  }
    68  
    69  func slotAppLabelExpr(slot *interfaces.ConnectedSlot) string {
    70  	return appLabelExpr(slot.Apps(), slot.Snap())
    71  }
    72  
    73  func plugAppLabelExpr(plug *interfaces.ConnectedPlug) string {
    74  	return appLabelExpr(plug.Apps(), plug.Snap())
    75  }
    76  
    77  // determine if permanent slot side is provided by the system
    78  // on classic system some implicit slots can be provided by system or by
    79  // application snap e.g. avahi (it can be installed as deb or snap)
    80  // - slot owned by the system (core,snapd snap)  usually requires no action
    81  // - slot owned by application snap typically requires rules update
    82  func implicitSystemPermanentSlot(slot *snap.SlotInfo) bool {
    83  	if release.OnClassic &&
    84  		(slot.Snap.GetType() == snap.TypeOS || slot.Snap.GetType() == snap.TypeSnapd) {
    85  		return true
    86  	}
    87  	return false
    88  }
    89  
    90  // determine if connected slot side is provided by the system
    91  // as for isPermanentSlotSystemSlot() slot can be owned by app or system
    92  func implicitSystemConnectedSlot(slot *interfaces.ConnectedSlot) bool {
    93  	if release.OnClassic &&
    94  		(slot.Snap().GetType() == snap.TypeOS || slot.Snap().GetType() == snap.TypeSnapd) {
    95  		return true
    96  	}
    97  	return false
    98  }