gitee.com/mysnapcore/mysnapd@v0.1.0/snap/snapenv/snapenv.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2014-2015 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 snapenv 21 22 import ( 23 "os" 24 "os/user" 25 "path/filepath" 26 27 "gitee.com/mysnapcore/mysnapd/arch" 28 "gitee.com/mysnapcore/mysnapd/dirs" 29 "gitee.com/mysnapcore/mysnapd/features" 30 "gitee.com/mysnapcore/mysnapd/logger" 31 "gitee.com/mysnapcore/mysnapd/osutil" 32 "gitee.com/mysnapcore/mysnapd/osutil/sys" 33 "gitee.com/mysnapcore/mysnapd/snap" 34 ) 35 36 // PreservedUnsafePrefix is used to escape env variables that are 37 // usually stripped out by ld.so when starting a setuid process, to preserve 38 // them through snap-confine (for classic confined snaps). 39 const PreservedUnsafePrefix = "SNAP_SAVED_" 40 41 var userCurrent = user.Current 42 43 // ExtendEnvForRun extends the given environment with what is is 44 // required for snap-{confine,exec}, that means SNAP_{NAME,REVISION} 45 // etc are all set. 46 // 47 // It ensures all SNAP_* override any pre-existing environment 48 // variables. 49 func ExtendEnvForRun(env osutil.Environment, info *snap.Info, opts *dirs.SnapDirOptions) { 50 // Set various SNAP_ environment variables as well as some non-SNAP variables, 51 // depending on snap confinement mode. Note that this does not include environment 52 // set by snap-exec. 53 for k, v := range snapEnv(info, opts) { 54 env[k] = v 55 } 56 } 57 58 func snapEnv(info *snap.Info, opts *dirs.SnapDirOptions) osutil.Environment { 59 // Environment variables with basic properties of a snap. 60 env := basicEnv(info) 61 if usr, err := userCurrent(); err == nil && usr.HomeDir != "" { 62 // Environment variables with values specific to the calling user. 63 for k, v := range userEnv(info, usr.HomeDir, opts) { 64 env[k] = v 65 } 66 } 67 return env 68 } 69 70 // basicEnv returns the app-level environment variables for a snap. 71 // Despite this being a bit snap-specific, this is in helpers.go because it's 72 // used by so many other modules, we run into circular dependencies if it's 73 // somewhere more reasonable like the snappy module. 74 func basicEnv(info *snap.Info) osutil.Environment { 75 env := osutil.Environment{ 76 // This uses CoreSnapMountDir because the computed environment 77 // variables are conveyed to the started application process which 78 // shall *either* execute with the new mount namespace where snaps are 79 // always mounted on /snap OR it is a classically confined snap where 80 // /snap is a part of the distribution package. 81 // 82 // For parallel-installs the mount namespace setup is making the 83 // environment of each snap instance appear as if it's the only 84 // snap, i.e. SNAP paths point to the same locations within the 85 // mount namespace 86 "SNAP": filepath.Join(dirs.CoreSnapMountDir, info.SnapName(), info.Revision.String()), 87 "SNAP_COMMON": snap.CommonDataDir(info.SnapName()), 88 "SNAP_DATA": snap.DataDir(info.SnapName(), info.Revision), 89 "SNAP_NAME": info.SnapName(), 90 "SNAP_INSTANCE_NAME": info.InstanceName(), 91 "SNAP_INSTANCE_KEY": info.InstanceKey, 92 "SNAP_VERSION": info.Version, 93 "SNAP_REVISION": info.Revision.String(), 94 "SNAP_ARCH": arch.DpkgArchitecture(), 95 // see https://github.com/snapcore/snapd/pull/2732#pullrequestreview-18827193 96 "SNAP_LIBRARY_PATH": "/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void", 97 "SNAP_REEXEC": os.Getenv("SNAP_REEXEC"), 98 } 99 100 // Add the ubuntu-save specific environment variable if 101 // the snap folder exists in the save directory. 102 if exists, isDir, err := osutil.DirExists(snap.CommonDataSaveDir(info.InstanceName())); err == nil && exists && isDir { 103 env["SNAP_SAVE_DATA"] = snap.CommonDataSaveDir(info.InstanceName()) 104 } else if err != nil { 105 logger.Noticef("cannot determine existence of save data directory for snap %q: %v", 106 info.InstanceName(), err) 107 } 108 return env 109 } 110 111 // userEnv returns the user-level environment variables for a snap. 112 // Despite this being a bit snap-specific, this is in helpers.go because it's 113 // used by so many other modules, we run into circular dependencies if it's 114 // somewhere more reasonable like the snappy module. 115 func userEnv(info *snap.Info, home string, opts *dirs.SnapDirOptions) osutil.Environment { 116 if opts == nil { 117 opts = &dirs.SnapDirOptions{} 118 } 119 120 // To keep things simple the user variables always point to the 121 // instance-specific directories. 122 env := osutil.Environment{ 123 "SNAP_USER_COMMON": info.UserCommonDataDir(home, opts), 124 "SNAP_USER_DATA": info.UserDataDir(home, opts), 125 } 126 if info.NeedsClassic() { 127 // Snaps using classic confinement don't have an override for 128 // HOME but may have an override for XDG_RUNTIME_DIR. 129 if !features.ClassicPreservesXdgRuntimeDir.IsEnabled() { 130 env["XDG_RUNTIME_DIR"] = info.UserXdgRuntimeDir(sys.Geteuid()) 131 } 132 } else { 133 // Snaps using strict or devmode confinement get an override for both 134 // HOME and XDG_RUNTIME_DIR. 135 env["HOME"] = info.UserDataDir(home, opts) 136 env["XDG_RUNTIME_DIR"] = info.UserXdgRuntimeDir(sys.Geteuid()) 137 } 138 // Provide the location of the real home directory. 139 env["SNAP_REAL_HOME"] = home 140 141 if opts.MigratedToExposedHome { 142 env["XDG_DATA_HOME"] = filepath.Join(info.UserDataDir(home, opts), "xdg-data") 143 env["XDG_CONFIG_HOME"] = filepath.Join(info.UserDataDir(home, opts), "xdg-config") 144 env["XDG_CACHE_HOME"] = filepath.Join(info.UserDataDir(home, opts), "xdg-cache") 145 146 env["SNAP_USER_HOME"] = info.UserExposedHomeDir(home) 147 env["HOME"] = info.UserExposedHomeDir(home) 148 } 149 return env 150 }