// basicEnv returns the app-level environment variables for a snap. // Despite this being a bit snap-specific, this is in helpers.go because it's // used by so many other modules, we run into circular dependencies if it's // somewhere more reasonable like the snappy module. func basicEnv(info *snap.Info) map[string]string { return map[string]string{ "SNAP": info.MountDir(), "SNAP_COMMON": info.CommonDataDir(), "SNAP_DATA": info.DataDir(), "SNAP_NAME": info.Name(), "SNAP_VERSION": info.Version, "SNAP_REVISION": info.Revision.String(), "SNAP_ARCH": arch.UbuntuArchitecture(), "SNAP_LIBRARY_PATH": "/var/lib/snapd/lib/gl:", "SNAP_REEXEC": os.Getenv("SNAP_REEXEC"), } }
// resolveSpecialVariable resolves one of the three $SNAP* variables at the // beginning of a given path. The variables are $SNAP, $SNAP_DATA and // $SNAP_COMMON. If there are no variables then $SNAP is implicitly assumed // (this is the behavior that was used before the variables were supporter). func resolveSpecialVariable(path string, snapInfo *snap.Info) string { if strings.HasPrefix(path, "$SNAP/") || path == "$SNAP" { return strings.Replace(path, "$SNAP", snapInfo.MountDir(), 1) } if strings.HasPrefix(path, "$SNAP_DATA/") || path == "$SNAP_DATA" { return strings.Replace(path, "$SNAP_DATA", snapInfo.DataDir(), 1) } if strings.HasPrefix(path, "$SNAP_COMMON/") || path == "$SNAP_COMMON" { return strings.Replace(path, "$SNAP_COMMON", snapInfo.CommonDataDir(), 1) } // NOTE: assume $SNAP by default if nothing else is provided, for compatibility return filepath.Join(snapInfo.MountDir(), path) }
// CopySnapData makes a copy of oldSnap data for newSnap in its data directories. func (b Backend) CopySnapData(newSnap, oldSnap *snap.Info, meter progress.Meter) error { // deal with the old data or // otherwise just create a empty data dir // Make sure the common data directory exists, even if this isn't a new // install. if err := os.MkdirAll(newSnap.CommonDataDir(), 0755); err != nil { return err } if oldSnap == nil { return os.MkdirAll(newSnap.DataDir(), 0755) } return copySnapData(oldSnap, newSnap) }
// Copy all data for oldSnap to newSnap // (but never overwrite) func copySnapData(oldSnap, newSnap *snap.Info) (err error) { oldDataDirs, err := snapDataDirs(oldSnap) if err != nil { return err } newSuffix := filepath.Base(newSnap.DataDir()) for _, oldDir := range oldDataDirs { // replace the trailing "../$old-suffix" with the "../$new-suffix" newDir := filepath.Join(filepath.Dir(oldDir), newSuffix) if err := copySnapDataDirectory(oldDir, newDir); err != nil { return err } } return nil }
// snapDataDirs returns the list of data directories for the given snap version func snapDataDirs(snap *snap.Info) ([]string, error) { // collect the directories, homes first found, err := filepath.Glob(snap.DataHomeDir()) if err != nil { return nil, err } // then system data found = append(found, snap.DataDir()) return found, nil }
func updateCurrentSymlinks(info *snap.Info) error { mountDir := info.MountDir() currentActiveSymlink := filepath.Join(mountDir, "..", "current") if err := os.Remove(currentActiveSymlink); err != nil && !os.IsNotExist(err) { logger.Noticef("Cannot remove %q: %v", currentActiveSymlink, err) } dataDir := info.DataDir() currentDataSymlink := filepath.Join(dataDir, "..", "current") if err := os.Remove(currentDataSymlink); err != nil && !os.IsNotExist(err) { logger.Noticef("Cannot remove %q: %v", currentDataSymlink, err) } if err := os.MkdirAll(info.DataDir(), 0755); err != nil { return err } if err := os.Symlink(filepath.Base(dataDir), currentDataSymlink); err != nil { return err } return os.Symlink(filepath.Base(mountDir), currentActiveSymlink) }