github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/cmd/snap-update-ns/system.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2017 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 main 21 22 import ( 23 "fmt" 24 25 "github.com/snapcore/snapd/dirs" 26 "github.com/snapcore/snapd/snap" 27 ) 28 29 // SystemProfileUpdateContext contains information about update to system-wide mount namespace. 30 type SystemProfileUpdateContext struct { 31 CommonProfileUpdateContext 32 } 33 34 // NewSystemProfileUpdateContext returns encapsulated information for performing a per-user mount namespace update. 35 func NewSystemProfileUpdateContext(instanceName string, fromSnapConfine bool) *SystemProfileUpdateContext { 36 return &SystemProfileUpdateContext{CommonProfileUpdateContext: CommonProfileUpdateContext{ 37 instanceName: instanceName, 38 fromSnapConfine: fromSnapConfine, 39 currentProfilePath: currentSystemProfilePath(instanceName), 40 desiredProfilePath: desiredSystemProfilePath(instanceName), 41 }} 42 } 43 44 // Assumptions returns information about file system mutability rules. 45 // 46 // System mount profiles can write to /tmp (this is required for constructing 47 // writable mimics) to /var/snap (where $SNAP_DATA is for services), /snap/$SNAP_NAME, 48 // and, in case of instances, /snap/$SNAP_INSTANCE_NAME. 49 func (upCtx *SystemProfileUpdateContext) Assumptions() *Assumptions { 50 // Allow creating directories related to this snap name. 51 // 52 // Note that we allow /var/snap instead of /var/snap/$SNAP_NAME because 53 // content interface connections can readily create missing mount points on 54 // both sides of the interface connection. 55 // 56 // We scope /snap/$SNAP_NAME because only one side of the connection can be 57 // created, as snaps are read-only, the mimic construction will kick-in and 58 // create the missing directory but this directory is only visible from the 59 // snap that we are operating on (either plug or slot side, the point is, 60 // the mount point is not universally visible). 61 // 62 // /snap/$SNAP_NAME needs to be there as the code that creates such mount 63 // points must traverse writable host filesystem that contains /snap/*/ and 64 // normally such access is off-limits. This approach allows /snap/foo 65 // without allowing /snap/bin, for example. 66 // 67 // /snap/$SNAP_INSTANCE_NAME and /snap/$SNAP_NAME are added to allow 68 // remapping for parallel installs only when the snap has an instance key 69 as := &Assumptions{} 70 instanceName := upCtx.InstanceName() 71 as.AddUnrestrictedPaths("/tmp", "/var/snap", "/snap/"+instanceName) 72 if snapName := snap.InstanceSnap(instanceName); snapName != instanceName { 73 as.AddUnrestrictedPaths("/snap/" + snapName) 74 } 75 return as 76 } 77 78 // desiredSystemProfilePath returns the path of the fstab-like file with the desired, system-wide mount profile for a snap. 79 func desiredSystemProfilePath(snapName string) string { 80 return fmt.Sprintf("%s/snap.%s.fstab", dirs.SnapMountPolicyDir, snapName) 81 } 82 83 // currentSystemProfilePath returns the path of the fstab-like file with the applied, system-wide mount profile for a snap. 84 func currentSystemProfilePath(snapName string) string { 85 return fmt.Sprintf("%s/snap.%s.fstab", dirs.SnapRunNsDir, snapName) 86 }