// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package impl

// The app invoker is responsible for managing the state of applications on the
// device manager.  The device manager manages the applications it installs and
// runs using the following directory structure.  Permissions and owners are
// noted as parentheses enclosed octal perms with an 'a' or 'd' suffix for app
// or device manager respectively.  For example: (755d)
//
// TODO(caprita): Not all is yet implemented.
//
// <config.Root>(711d)/
//   app-<hash 1>(711d)/                  - the application dir is named using a hash of the application title
//     installation-<id 1>(711d)/         - installations are labelled with ids
//       acls(700d)/
//         data(700d)                     - the AccessList data for this
//                                          installation. Controls access to
//                                          Instantiate, Uninstall, Update,
//                                          UpdateTo and Revert.
//         signature(700d)                - the signature for the AccessLists in data
//       <status>(700d)                   - one of the values for InstallationState enum
//       origin(700d)                     - object name for application envelope
//       config(700d)                     - Config provided by the installer
//       packages(700d)                   - set of packages specified by the installer
//       pkg(700d)/                       - downloaded packages
//         <pkg name>(700d)
//         <pkg name>.__info(700d)
//         ...
//       <version 1 timestamp>(711d)/     - timestamp of when the version was downloaded
//         bin(755d)                      - application binary
//         previous                       - symbolic link to previous version directory
//         envelope                       - application envelope (JSON-encoded)
//         packages(755d)/                - installed packages (from envelope+installer)
//           <pkg name>(755d)/
//           ...
//       <version 2 timestamp>(711d)
//       ...
//       current                          - symbolic link to the current version
//       instances(711d)/
//         instance-<id a>(711d)/         - instances are labelled with ids
//           credentials(700d)/           - holds vanadium credentials (unless running
//                                          through security agent)
//           root(700a)/                  - workspace that the instance is run from
//             packages                   - symbolic link to version's packages
//           logs(755a)/                  - stderr/stdout and log files generated by instance
//           info(700d)                   - metadata for the instance (such as app
//                                          cycle manager name and process id)
//           installation                 - symbolic link to installation for the instance
//           version                      - symbolic link to installation version for the instance
//           acls(700d)/
//             data(700d)                 - the AccessLists for this instance. These
//                                          AccessLists control access to Run,
//                                          Kill and Delete.
//             signature(700d)            - the signature for these AccessLists.
//           <status>(700d)               - one of the values for InstanceState enum
//           systemname(700d)             - the system name used to execute this instance
//           debugacls (711d)/
//             data(644)/                 - the Permissions for Debug access to the application. Shared
//                                          with the application.
//             signature(644)/            - the signature for these Permissions.
//         instance-<id b>(711d)
//         ...
//     installation-<id 2>(711d)
//     ...
//   app-<hash 2>(711d)
//   ...
//
// The device manager uses the suid helper binary to invoke an application as a
// specified user.  The path to the helper is specified as config.Helper.

// When device manager starts up, it goes through all instances and launches the
// ones that are not running.  If an instance fails to launch, it stays not
// running.
//
// Instantiate creates an instance.  Run launches the process.  Kill kills the
// process but leaves the workspace untouched.  Delete prevents future launches
// (it also eventually gc's the workspace, logs, and other instance state).
//
// If the process dies on its own, it stays dead and is assumed not running.
// TODO(caprita): Later, we'll add auto-restart option.
//
// Concurrency model: installations can be created independently of one another;
// installations can be removed at any time (TODO(caprita): ensure all instances
// are Deleted).  The first call to Uninstall will rename the installation dir
// as a first step; subsequent Uninstall's will fail.  Instances can be created
// independently of one another, as long as the installation exists (if it gets
// Uninstall'ed during a Instantiate, the Instantiate call may fail).
//
// The status file present in each instance is used to flag the state of the
// instance and prevent concurrent operations against the instance:
//
// - when an instance is created with Instantiate, it is placed in state
// 'not-running'.
//
// - Run attempts to transition from 'not-running' to 'launching' (if the
// instance was not in 'not-running' state, Run fails).  From 'launching', the
// instance transitions to 'running' upon success or back to 'not-running' upon
// failure.
//
// - Kill attempts to transition from 'running' to 'dying' (if the
// instance was not in 'running' state, Kill fails).  From 'dying', the
// instance transitions to 'not-running' upon success or back to 'running' upon
// failure.
//
// - Delete transitions from 'not-running' to 'deleted'.  If the initial
// state is not 'not-running', Delete fails.
//
// TODO(caprita): There is room for synergy between how device manager organizes
// its own workspace and that for the applications it runs.  In particular,
// previous, origin, and envelope could be part of a single config.  We'll
// refine that later.

import (
	"bytes"
	"crypto/md5"
	"crypto/rand"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"
	"text/template"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/security/access"
	"v.io/v23/services/appcycle"
	"v.io/v23/services/application"
	"v.io/v23/services/device"
	"v.io/v23/verror"
	"v.io/x/lib/vlog"
	"v.io/x/ref"
	vexec "v.io/x/ref/lib/exec"
	"v.io/x/ref/lib/mgmt"
	vsecurity "v.io/x/ref/lib/security"
	"v.io/x/ref/services/agent/agentlib"
	"v.io/x/ref/services/agent/keymgr"
	"v.io/x/ref/services/device/internal/config"
	"v.io/x/ref/services/internal/packages"
	"v.io/x/ref/services/internal/pathperms"
)

// instanceInfo holds state about a running instance.
type instanceInfo struct {
	AppCycleMgrName          string
	Pid                      int
	DeviceManagerPeerPattern string
	SecurityAgentHandle      []byte
}

func saveInstanceInfo(ctx *context.T, dir string, info *instanceInfo) error {
	jsonInfo, err := json.Marshal(info)
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", info, err))
	}
	infoPath := filepath.Join(dir, "info")
	if err := ioutil.WriteFile(infoPath, jsonInfo, 0600); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", infoPath, err))
	}
	return nil
}

func loadInstanceInfo(ctx *context.T, dir string) (*instanceInfo, error) {
	infoPath := filepath.Join(dir, "info")
	info := new(instanceInfo)
	if infoBytes, err := ioutil.ReadFile(infoPath); err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", infoPath, err))
	} else if err := json.Unmarshal(infoBytes, info); err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", infoBytes, err))
	}
	return info, nil
}

type securityAgentState struct {
	// Security agent key manager client.
	keyMgrAgent *keymgr.Agent
}

// appStart is the subset of the appService object needed to
// (re)start an application.
type appStartState struct {
	systemName  string
	instanceDir string
	callback    *callbackState
	// securityAgent holds state related to the security agent (nil if not
	// using the agent).
	securityAgent *securityAgentState
	// mtAddress is the address of the local mounttable.
	mtAddress string
}

// appService implements the Device manager's Application interface.
type appService struct {
	config *config.State
	// suffix contains the name components of the current invocation name
	// suffix.  It is used to identify an application, installation, or
	// instance.
	suffix     []string
	uat        BlessingSystemAssociationStore
	permsStore *pathperms.PathStore
	// Reference to the devicemanager top-level AccessList list.
	deviceAccessList access.Permissions
	// reap is the app process monitoring subsystem.
	reap     reaper
	appStart *appStartState
}

func saveEnvelope(ctx *context.T, dir string, envelope *application.Envelope) error {
	jsonEnvelope, err := json.Marshal(envelope)
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", envelope, err))
	}
	path := filepath.Join(dir, "envelope")
	if err := ioutil.WriteFile(path, jsonEnvelope, 0600); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
	}
	return nil
}

func loadEnvelope(ctx *context.T, dir string) (*application.Envelope, error) {
	path := filepath.Join(dir, "envelope")
	envelope := new(application.Envelope)
	if envelopeBytes, err := ioutil.ReadFile(path); err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
	} else if err := json.Unmarshal(envelopeBytes, envelope); err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", envelopeBytes, err))
	}
	return envelope, nil
}

func saveConfig(ctx *context.T, dir string, config device.Config) error {
	jsonConfig, err := json.Marshal(config)
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", config, err))
	}
	path := filepath.Join(dir, "config")
	if err := ioutil.WriteFile(path, jsonConfig, 0600); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
	}
	return nil
}

func loadConfig(ctx *context.T, dir string) (device.Config, error) {
	path := filepath.Join(dir, "config")
	var config device.Config
	if configBytes, err := ioutil.ReadFile(path); err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
	} else if err := json.Unmarshal(configBytes, &config); err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", configBytes, err))
	}
	return config, nil
}

func savePackages(ctx *context.T, dir string, packages application.Packages) error {
	jsonPackages, err := json.Marshal(packages)
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", packages, err))
	}
	path := filepath.Join(dir, "packages")
	if err := ioutil.WriteFile(path, jsonPackages, 0600); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
	}
	return nil
}

func loadPackages(ctx *context.T, dir string) (application.Packages, error) {
	path := filepath.Join(dir, "packages")
	var packages application.Packages
	if packagesBytes, err := ioutil.ReadFile(path); err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
	} else if err := json.Unmarshal(packagesBytes, &packages); err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", packagesBytes, err))
	}
	return packages, nil
}

func saveOrigin(ctx *context.T, dir, originVON string) error {
	path := filepath.Join(dir, "origin")
	if err := ioutil.WriteFile(path, []byte(originVON), 0600); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
	}
	return nil
}

func loadOrigin(ctx *context.T, dir string) (string, error) {
	path := filepath.Join(dir, "origin")
	if originBytes, err := ioutil.ReadFile(path); err != nil {
		return "", verror.New(ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
	} else {
		return string(originBytes), nil
	}
}

// generateID returns a new unique id string.  The uniqueness is based on the
// current timestamp.  Not cryptographically secure.
func generateID() string {
	const timeFormat = "20060102-15:04:05.0000"
	return time.Now().UTC().Format(timeFormat)
}

// generateRandomString returns a cryptographically-strong random string.
func generateRandomString() (string, error) {
	b := make([]byte, 16)
	_, err := rand.Read(b)
	if err != nil {
		return "", err
	}
	return hex.EncodeToString(b), nil
}

// TODO(caprita): Nothing prevents different applications from sharing the same
// title, and thereby being installed in the same app dir.  Do we want to
// prevent that for the same user or across users?

// applicationDirName generates a cryptographic hash of the application title,
// to be used as a directory name for installations of the application with the
// given title.
func applicationDirName(title string) string {
	h := md5.New()
	h.Write([]byte(title))
	hash := strings.TrimRight(base64.URLEncoding.EncodeToString(h.Sum(nil)), "=")
	return "app-" + hash
}

func installationDirName(installationID string) string {
	return "installation-" + installationID
}

func instanceDirName(instanceID string) string {
	return "instance-" + instanceID
}

func mkdir(dir string) error {
	return mkdirPerm(dir, 0700)
}

func mkdirPerm(dir string, permissions int) error {
	perm := os.FileMode(permissions)
	if err := os.MkdirAll(dir, perm); err != nil {
		vlog.Errorf("MkdirAll(%v, %v) failed: %v", dir, perm, err)
		return err
	}
	return nil
}

func fetchAppEnvelope(ctx *context.T, origin string) (*application.Envelope, error) {
	envelope, err := fetchEnvelope(ctx, origin)
	if err != nil {
		return nil, err
	}
	if envelope.Title == application.DeviceManagerTitle {
		// Disallow device manager apps from being installed like a
		// regular app.
		return nil, verror.New(ErrInvalidOperation, ctx, "DeviceManager apps cannot be installed")
	}
	return envelope, nil
}

// newVersion sets up the directory for a new application version.
func newVersion(ctx *context.T, installationDir string, envelope *application.Envelope, oldVersionDir string) (string, error) {
	versionDir := filepath.Join(installationDir, generateVersionDirName())
	if err := mkdirPerm(versionDir, 0711); err != nil {
		return "", verror.New(ErrOperationFailed, ctx, err)
	}
	if err := saveEnvelope(ctx, versionDir, envelope); err != nil {
		return versionDir, err
	}
	pkgDir := filepath.Join(versionDir, "pkg")
	if err := mkdir(pkgDir); err != nil {
		return "", verror.New(ErrOperationFailed, ctx, err)
	}
	publisher := envelope.Publisher
	// TODO(caprita): Share binaries if already existing locally.
	if err := downloadBinary(ctx, publisher, &envelope.Binary, versionDir, "bin"); err != nil {
		return versionDir, err
	}
	if err := downloadPackages(ctx, publisher, envelope.Packages, pkgDir); err != nil {
		return versionDir, err
	}
	if err := installPackages(ctx, installationDir, versionDir); err != nil {
		return versionDir, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("installPackages(%v, %v) failed: %v", installationDir, versionDir, err))
	}
	if err := os.RemoveAll(pkgDir); err != nil {
		return versionDir, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("RemoveAll(%v) failed: %v", pkgDir, err))
	}
	if oldVersionDir != "" {
		previousLink := filepath.Join(versionDir, "previous")
		if err := os.Symlink(oldVersionDir, previousLink); err != nil {
			return versionDir, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", oldVersionDir, previousLink, err))
		}
	}
	// updateLink should be the last thing we do, after we've ensured the
	// new version is viable (currently, that just means it installs
	// properly).
	return versionDir, updateLink(versionDir, filepath.Join(installationDir, "current"))
}

func (i *appService) Install(ctx *context.T, call rpc.ServerCall, applicationVON string, config device.Config, packages application.Packages) (string, error) {
	if len(i.suffix) > 0 {
		return "", verror.New(ErrInvalidSuffix, ctx)
	}
	ctx, cancel := context.WithTimeout(ctx, rpcContextLongTimeout)
	defer cancel()
	envelope, err := fetchAppEnvelope(ctx, applicationVON)
	if err != nil {
		return "", err
	}
	installationID := generateID()
	installationDir := filepath.Join(i.config.Root, applicationDirName(envelope.Title), installationDirName(installationID))
	deferrer := func() {
		CleanupDir(installationDir, "")
	}
	if err := mkdirPerm(installationDir, 0711); err != nil {
		return "", verror.New(ErrOperationFailed, nil)
	}
	defer func() {
		if deferrer != nil {
			deferrer()
		}
	}()
	if newOrigin, ok := config[mgmt.AppOriginConfigKey]; ok {
		delete(config, mgmt.AppOriginConfigKey)
		applicationVON = newOrigin
	}
	if err := saveOrigin(ctx, installationDir, applicationVON); err != nil {
		return "", err
	}
	if err := saveConfig(ctx, installationDir, config); err != nil {
		return "", err
	}
	if err := savePackages(ctx, installationDir, packages); err != nil {
		return "", err
	}
	pkgDir := filepath.Join(installationDir, "pkg")
	if err := mkdir(pkgDir); err != nil {
		return "", verror.New(ErrOperationFailed, ctx, err)
	}
	// We use a zero value publisher, meaning that any signatures present in the
	// package files are not verified.
	// TODO(caprita): Issue warnings when signatures are present and ignored.
	if err := downloadPackages(ctx, security.Blessings{}, packages, pkgDir); err != nil {
		return "", err
	}
	if _, err := newVersion(ctx, installationDir, envelope, ""); err != nil {
		return "", err
	}
	// TODO(caprita,rjkroege): Should the installation AccessLists really be
	// seeded with the device AccessList? Instead, might want to hide the deviceAccessList
	// from the app?
	blessings, _ := security.RemoteBlessingNames(ctx, call.Security())
	if err := i.initializeSubAccessLists(installationDir, blessings, i.deviceAccessList.Copy()); err != nil {
		return "", err
	}
	if err := initializeInstallation(installationDir, device.InstallationStateActive); err != nil {
		return "", err
	}
	deferrer = nil
	// TODO(caprita): Using the title without cleaning out slashes
	// introduces extra name components that mess up the device manager's
	// apps object space.  We should fix this either by santizing the title,
	// or disallowing slashes in titles to begin with.
	return naming.Join(envelope.Title, installationID), nil
}

func openWriteFile(path string) (*os.File, error) {
	perm := os.FileMode(0644)
	return os.OpenFile(path, os.O_WRONLY|os.O_CREATE, perm)
}

// TODO(gauthamt): Make sure we pass the context to installationDirCore.
func installationDirCore(components []string, root string) (string, error) {
	if nComponents := len(components); nComponents != 2 {
		return "", verror.New(ErrInvalidSuffix, nil)
	}
	app, installation := components[0], components[1]
	installationDir := filepath.Join(root, applicationDirName(app), installationDirName(installation))
	if _, err := os.Stat(installationDir); err != nil {
		if os.IsNotExist(err) {
			return "", verror.New(verror.ErrNoExist, nil, naming.Join(components...))
		}
		return "", verror.New(ErrOperationFailed, nil, fmt.Sprintf("Stat(%v) failed: %v", installationDir, err))
	}
	return installationDir, nil
}

// agentPrincipal creates a Principal backed by the given agent connection,
// taking ownership of the connection.  The returned cancel function is to be
// called when the Principal is no longer in use.
func agentPrincipal(ctx *context.T, conn *os.File) (security.Principal, func(), error) {
	agentctx, cancel := context.WithCancel(ctx)
	var err error
	if agentctx, err = v23.WithNewStreamManager(agentctx); err != nil {
		cancel()
		conn.Close()
		return nil, nil, err
	}
	// TODO: This should use the same network as the agent we're using,
	// not whatever this process was compiled with.
	ep, err := v23.NewEndpoint(agentlib.AgentEndpoint(int(conn.Fd())))
	if err != nil {
		cancel()
		conn.Close()
		return nil, nil, err
	}
	p, err := agentlib.NewAgentPrincipal(agentctx, ep, v23.GetClient(agentctx))
	if err != nil {
		cancel()
		conn.Close()
		return nil, nil, err
	}
	conn.Close()
	return p, cancel, nil
}

// setupPrincipal sets up the instance's principal, with the right blessings.
func setupPrincipal(ctx *context.T, instanceDir string, call device.ApplicationInstantiateServerCall, securityAgent *securityAgentState, info *instanceInfo) error {
	var p security.Principal
	if securityAgent != nil {
		// TODO(caprita): Part of the cleanup upon destroying an
		// instance, we should tell the agent to drop the principal.
		handle, conn, err := securityAgent.keyMgrAgent.NewPrincipal(ctx, false)
		if err != nil {
			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("NewPrincipal() failed %v", err))
		}
		var cancel func()
		if p, cancel, err = agentPrincipal(ctx, conn); err != nil {
			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("agentPrincipal failed: %v", err))
		}
		defer cancel()
		info.SecurityAgentHandle = handle
		// conn will be closed when the connection to the agent is shut
		// down, as a result of cancel() shutting down the stream
		// manager.  No need to call conn.Close().
	} else {
		credentialsDir := filepath.Join(instanceDir, "credentials")
		// TODO(caprita): The app's system user id needs access to this dir.
		// Use the suidhelper to chown it.
		var err error
		if p, err = vsecurity.CreatePersistentPrincipal(credentialsDir, nil); err != nil {
			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("CreatePersistentPrincipal(%v, nil) failed: %v", credentialsDir, err))
		}
	}
	mPubKey, err := p.PublicKey().MarshalBinary()
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("PublicKey().MarshalBinary() failed: %v", err))
	}
	if err := call.SendStream().Send(device.BlessServerMessageInstancePublicKey{Value: mPubKey}); err != nil {
		return err
	}
	if !call.RecvStream().Advance() {
		return verror.New(ErrInvalidBlessing, ctx, fmt.Sprintf("no blessings on stream: %v", call.RecvStream().Err()))
	}
	msg := call.RecvStream().Value()
	appBlessings, ok := msg.(device.BlessClientMessageAppBlessings)
	if !ok {
		return verror.New(ErrInvalidBlessing, ctx, fmt.Sprintf("wrong message type: %#v", msg))
	}
	if appBlessings.Value.IsZero() {
		return verror.New(ErrInvalidBlessing, ctx)
	}
	if err := p.BlessingStore().SetDefault(appBlessings.Value); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.SetDefault() failed: %v", err))
	}
	if _, err := p.BlessingStore().Set(appBlessings.Value, security.AllPrincipals); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
	}
	if err := p.AddToRoots(appBlessings.Value); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("AddToRoots() failed: %v", err))
	}
	// In addition, we give the app separate blessings for the purpose of
	// communicating with the device manager.
	//
	// NOTE(caprita/ataly): Giving the app an unconstrained blessing from
	// the device manager's default presents the app with a blessing that's
	// potentially more powerful than what is strictly needed to allow
	// communication between device manager and app (which could be more
	// narrowly accomplished by using a custom-purpose self-signed blessing
	// that the device manger produces solely to talk to the app).
	//
	// TODO(caprita): Figure out if there is any feature value in providing
	// the app with a device manager-derived blessing (e.g., may the app
	// need to prove it's running on the device?).
	dmPrincipal := v23.GetPrincipal(ctx)
	dmBlessings, err := dmPrincipal.Bless(p.PublicKey(), dmPrincipal.BlessingStore().Default(), "callback", security.UnconstrainedUse())
	// Put the names of the device manager's default blessings as patterns
	// for the child, so that the child uses the right blessing when talking
	// back to the device manager.
	for n, _ := range dmPrincipal.BlessingsInfo(dmPrincipal.BlessingStore().Default()) {
		if _, err := p.BlessingStore().Set(dmBlessings, security.BlessingPattern(n)); err != nil {
			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
		}
	}
	// We also want to override the app cycle manager's server blessing in
	// the child (so that the device manager can send RPCs to it).  We
	// signal to the child's app manager to use a randomly generated pattern
	// to extract the right blessing to use from its store for this purpose.
	randomPattern, err := generateRandomString()
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("generateRandomString() failed: %v", err))
	}
	if _, err := p.BlessingStore().Set(dmBlessings, security.BlessingPattern(randomPattern)); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
	}
	info.DeviceManagerPeerPattern = randomPattern
	if err := p.AddToRoots(dmBlessings); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("AddToRoots() failed: %v", err))
	}
	return nil
}

// installationDir returns the path to the directory containing the app
// installation referred to by the invoker's suffix.  Returns an error if the
// suffix does not name an installation or if the named installation does not
// exist.
func (i *appService) installationDir() (string, error) {
	return installationDirCore(i.suffix, i.config.Root)
}

// installPackages installs all the packages for a new version.
func installPackages(ctx *context.T, installationDir, versionDir string) error {
	overridePackages, err := loadPackages(ctx, installationDir)
	if err != nil {
		return err
	}
	envelope, err := loadEnvelope(ctx, versionDir)
	if err != nil {
		return err
	}
	for pkg, _ := range overridePackages {
		delete(envelope.Packages, pkg)
	}
	packagesDir := filepath.Join(versionDir, "packages")
	if err := os.MkdirAll(packagesDir, os.FileMode(0755)); err != nil {
		return err
	}
	installFrom := func(pkgs application.Packages, sourceDir string) error {
		for pkg, _ := range pkgs {
			pkgFile := filepath.Join(sourceDir, "pkg", pkg)
			dst := filepath.Join(packagesDir, pkg)
			if err := packages.Install(pkgFile, dst); err != nil {
				return err
			}
		}
		return nil
	}
	if err := installFrom(envelope.Packages, versionDir); err != nil {
		return err
	}
	return installFrom(overridePackages, installationDir)
}

// initializeSubAccessLists updates the provided perms for instance-specific
// Permissions.
func (i *appService) initializeSubAccessLists(instanceDir string, blessings []string, perms access.Permissions) error {
	for _, b := range blessings {
		b = b + string(security.ChainSeparator) + string(security.NoExtension)
		for _, tag := range access.AllTypicalTags() {
			perms.Add(security.BlessingPattern(b), string(tag))
		}
	}
	permsDir := path.Join(instanceDir, "acls")
	return i.permsStore.Set(permsDir, perms, "")
}

func (i *appService) newInstance(ctx *context.T, call device.ApplicationInstantiateServerCall) (string, string, error) {
	installationDir, err := i.installationDir()
	if err != nil {
		return "", "", err
	}
	if !installationStateIs(installationDir, device.InstallationStateActive) {
		return "", "", verror.New(ErrInvalidOperation, ctx)
	}
	instanceID := generateID()
	instanceDir := filepath.Join(installationDir, "instances", instanceDirName(instanceID))
	// Set permissions for app to have access.
	if mkdirPerm(instanceDir, 0711) != nil {
		return "", "", verror.New(ErrOperationFailed, ctx)
	}
	rootDir := filepath.Join(instanceDir, "root")
	if err := mkdir(rootDir); err != nil {
		return instanceDir, instanceID, verror.New(ErrOperationFailed, ctx, err)
	}
	installationLink := filepath.Join(instanceDir, "installation")
	if err := os.Symlink(installationDir, installationLink); err != nil {
		return instanceDir, instanceID, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", installationDir, installationLink, err))
	}
	currLink := filepath.Join(installationDir, "current")
	versionDir, err := filepath.EvalSymlinks(currLink)
	if err != nil {
		return instanceDir, instanceID, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", currLink, err))
	}
	versionLink := filepath.Join(instanceDir, "version")
	if err := os.Symlink(versionDir, versionLink); err != nil {
		return instanceDir, instanceID, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", versionDir, versionLink, err))
	}
	packagesDir, packagesLink := filepath.Join(versionLink, "packages"), filepath.Join(rootDir, "packages")
	if err := os.Symlink(packagesDir, packagesLink); err != nil {
		return instanceDir, instanceID, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", packagesDir, packagesLink, err))
	}
	instanceInfo := new(instanceInfo)
	if err := setupPrincipal(ctx, instanceDir, call, i.appStart.securityAgent, instanceInfo); err != nil {
		return instanceDir, instanceID, err
	}
	if err := saveInstanceInfo(ctx, instanceDir, instanceInfo); err != nil {
		return instanceDir, instanceID, err
	}
	blessings, _ := security.RemoteBlessingNames(ctx, call.Security())
	permsCopy := i.deviceAccessList.Copy()
	if err := i.initializeSubAccessLists(instanceDir, blessings, permsCopy); err != nil {
		return instanceDir, instanceID, err
	}
	if err := initializeInstance(instanceDir, device.InstanceStateNotRunning); err != nil {
		return instanceDir, instanceID, err
	}
	// TODO(rjkroege): Divide the permission lists into those used by the device manager
	// and those used by the application itself.
	dmBlessings := security.LocalBlessingNames(ctx, call.Security())
	if err := setPermsForDebugging(dmBlessings, permsCopy, instanceDir, i.permsStore); err != nil {
		return instanceDir, instanceID, err
	}
	return instanceDir, instanceID, nil
}

func (i appStartState) genCmd(ctx *context.T) (*exec.Cmd, error) {
	instanceDir := i.instanceDir
	systemName := i.systemName
	nsRoot := i.mtAddress

	versionLink := filepath.Join(instanceDir, "version")
	versionDir, err := filepath.EvalSymlinks(versionLink)
	if err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
	}
	envelope, err := loadEnvelope(ctx, versionDir)
	if err != nil {
		return nil, err
	}
	binPath := filepath.Join(versionDir, "bin")
	if _, err := os.Stat(binPath); err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Stat(%v) failed: %v", binPath, err))
	}

	saArgs := suidAppCmdArgs{targetUser: systemName, binpath: binPath}

	// Pass the displayed name of the program (argv0 as seen in ps output)
	// Envelope data comes from the user so we sanitize it for safety
	_, relativeBinaryName := naming.SplitAddressName(envelope.Binary.File)
	rawAppName := envelope.Title + "@" + relativeBinaryName + "/app"
	sanitize := func(r rune) rune {
		if strconv.IsPrint(r) {
			return r
		} else {
			return '_'
		}
	}
	appName := strings.Map(sanitize, rawAppName)
	saArgs.progname = appName

	// Set the app's default namespace root to the local namespace.
	saArgs.env = []string{ref.EnvNamespacePrefix + "=" + nsRoot}
	saArgs.env = append(saArgs.env, envelope.Env...)
	rootDir := filepath.Join(instanceDir, "root")
	saArgs.dir = rootDir
	saArgs.workspace = rootDir

	logDir := filepath.Join(instanceDir, "logs")
	suidHelper.chownTree(suidHelper.getCurrentUser(), instanceDir, os.Stdout, os.Stdin)
	if err := mkdirPerm(logDir, 0755); err != nil {
		return nil, err
	}
	saArgs.logdir = logDir
	timestamp := time.Now().UnixNano()

	stdoutLog := filepath.Join(logDir, fmt.Sprintf("STDOUT-%d", timestamp))
	if saArgs.stdout, err = openWriteFile(stdoutLog); err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("OpenFile(%v) failed: %v", stdoutLog, err))
	}
	stderrLog := filepath.Join(logDir, fmt.Sprintf("STDERR-%d", timestamp))
	if saArgs.stderr, err = openWriteFile(stderrLog); err != nil {
		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("OpenFile(%v) failed: %v", stderrLog, err))
	}

	// Args to be passed by helper to the app.
	appArgs := []string{"--log_dir=../logs"}
	appArgs = append(appArgs, envelope.Args...)

	saArgs.appArgs = appArgs
	return suidHelper.getAppCmd(&saArgs)
}

func (i appStartState) startCmd(ctx *context.T, cmd *exec.Cmd) (int, error) {
	instanceDir := i.instanceDir
	info, err := loadInstanceInfo(ctx, instanceDir)
	if err != nil {
		return 0, err
	}
	// Setup up the child process callback.
	callbackState := i.callback
	listener := callbackState.listenFor(mgmt.AppCycleManagerConfigKey)
	defer listener.cleanup()
	cfg := vexec.NewConfig()
	installationLink := filepath.Join(instanceDir, "installation")
	installationDir, err := filepath.EvalSymlinks(installationLink)
	if err != nil {
		return 0, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", installationLink, err))
	}
	config, err := loadConfig(ctx, installationDir)
	if err != nil {
		return 0, err
	}
	for k, v := range config {
		cfg.Set(k, v)
	}
	cfg.Set(mgmt.ParentNameConfigKey, listener.name())
	cfg.Set(mgmt.ProtocolConfigKey, "tcp")
	cfg.Set(mgmt.AddressConfigKey, "127.0.0.1:0")
	cfg.Set(mgmt.ParentBlessingConfigKey, info.DeviceManagerPeerPattern)

	appPermsDir := filepath.Join(instanceDir, "debugacls", "data")
	cfg.Set("v23.permissions.file", "runtime:"+appPermsDir)

	// This adds to cmd.Extrafiles. The helper expects a fixed fd, so this call needs
	// to go before anything that conditionally adds to Extrafiles, like the agent
	// setup code immediately below.
	var handshaker appHandshaker
	handshaker.prepareToStart(ctx, cmd)
	defer handshaker.cleanup()

	// Set up any agent-specific state.
	// NOTE(caprita): This ought to belong in genCmd.
	var agentCleaner func()
	if sa := i.securityAgent; sa != nil {
		file, err := sa.keyMgrAgent.NewConnection(info.SecurityAgentHandle)
		if err != nil {
			vlog.Errorf("NewConnection(%v) failed: %v", info.SecurityAgentHandle, err)
			return 0, err
		}
		agentCleaner = func() {
			file.Close()
		}
		// We need to account for the file descriptors corresponding to
		// std{err|out|in} as well as the implementation-specific pipes
		// that the vexec library adds to ExtraFiles during
		// handle.Start.  vexec.FileOffset properly offsets fd
		// accordingly.
		fd := len(cmd.ExtraFiles) + vexec.FileOffset
		cmd.ExtraFiles = append(cmd.ExtraFiles, file)
		ep := agentlib.AgentEndpoint(fd)
		cfg.Set(mgmt.SecurityAgentEndpointConfigKey, ep)
	} else {
		cmd.Env = append(cmd.Env, ref.EnvCredentials+"="+filepath.Join(instanceDir, "credentials"))
	}
	handle := vexec.NewParentHandle(cmd, vexec.ConfigOpt{Config: cfg})
	defer func() {
		if handle != nil {
			if err := handle.Clean(); err != nil {
				vlog.Errorf("Clean() failed: %v", err)
			}
		}
	}()

	// Start the child process.
	startErr := handle.Start()
	// Perform unconditional cleanup before dealing with any error from
	// handle.Start()
	if agentCleaner != nil {
		agentCleaner()
	}
	// Now react to any error in handle.Start()
	if startErr != nil {
		return 0, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Start() failed: %v", err))
	}

	// Wait for the suidhelper to exit. This is blocking as we assume the
	// helper won't get stuck.
	if err := handle.Wait(0); err != nil {
		return 0, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Wait() on suidhelper failed: %v", err))
	}

	pid, childName, err := handshaker.doHandshake(handle, listener)

	if err != nil {
		return 0, err
	}

	info.AppCycleMgrName, info.Pid = childName, pid
	if err := saveInstanceInfo(ctx, instanceDir, info); err != nil {
		return 0, err
	}
	handle = nil
	return pid, nil
}

func (i appStartState) run(ctx *context.T, reap reaper) error {
	if err := transitionInstance(i.instanceDir, device.InstanceStateNotRunning, device.InstanceStateLaunching); err != nil {
		return err
	}
	var pid int

	cmd, err := i.genCmd(ctx)
	if err == nil {
		pid, err = i.startCmd(ctx, cmd)
	}
	if err != nil {
		transitionInstance(i.instanceDir, device.InstanceStateLaunching, device.InstanceStateNotRunning)
		return err
	}
	if err := transitionInstance(i.instanceDir, device.InstanceStateLaunching, device.InstanceStateRunning); err != nil {
		return err
	}
	reap.startWatching(i.instanceDir, pid)
	return nil
}

func (i *appService) Instantiate(ctx *context.T, call device.ApplicationInstantiateServerCall) (string, error) {
	helper := i.config.Helper
	instanceDir, instanceID, err := i.newInstance(ctx, call)
	if err != nil {
		CleanupDir(instanceDir, helper)
		return "", err
	}
	systemName := suidHelper.usernameForPrincipal(ctx, call.Security(), i.uat)
	if err := saveSystemNameForInstance(instanceDir, systemName); err != nil {
		CleanupDir(instanceDir, helper)
		return "", err
	}
	return instanceID, nil
}

// instanceDir returns the path to the directory containing the app instance
// referred to by the given suffix relative to the given root directory.
// TODO(gauthamt): Make sure we pass the context to instanceDir.
func instanceDir(root string, suffix []string) (string, error) {
	if nComponents := len(suffix); nComponents != 3 {
		return "", verror.New(ErrInvalidSuffix, nil)
	}
	app, installation, instance := suffix[0], suffix[1], suffix[2]
	instancesDir := filepath.Join(root, applicationDirName(app), installationDirName(installation), "instances")
	instanceDir := filepath.Join(instancesDir, instanceDirName(instance))
	return instanceDir, nil
}

// instanceDir returns the path to the directory containing the app instance
// referred to by the invoker's suffix, as well as the corresponding not-running
// instance dir.  Returns an error if the suffix does not name an instance.
func (i *appService) instanceDir() (string, error) {
	return instanceDir(i.config.Root, i.suffix)
}

func (i *appService) Run(ctx *context.T, call rpc.ServerCall) error {
	instanceDir, err := i.instanceDir()
	if err != nil {
		return err
	}

	systemName := suidHelper.usernameForPrincipal(ctx, call.Security(), i.uat)
	startSystemName, err := readSystemNameForInstance(instanceDir)
	if err != nil {
		return err
	}

	if startSystemName != systemName {
		return verror.New(verror.ErrNoAccess, ctx, "Not allowed to resume an application under a different system name.")
	}

	i.appStart.instanceDir = instanceDir
	i.appStart.systemName = systemName
	return i.appStart.run(ctx, i.reap)
}

func stopAppRemotely(ctx *context.T, appVON string, deadline time.Duration) error {
	appStub := appcycle.AppCycleClient(appVON)
	ctx, cancel := context.WithTimeout(ctx, deadline)
	defer cancel()
	stream, err := appStub.Stop(ctx)
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("%v.Stop() failed: %v", appVON, err))
	}
	rstream := stream.RecvStream()
	for rstream.Advance() {
		vlog.VI(2).Infof("%v.Stop() task update: %v", appVON, rstream.Value())
	}
	if err := rstream.Err(); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Advance() failed: %v", err))
	}
	if err := stream.Finish(); err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Finish() failed: %v", err))
	}
	return nil
}

func stop(ctx *context.T, instanceDir string, reap reaper, deadline time.Duration) error {
	info, err := loadInstanceInfo(ctx, instanceDir)
	if err != nil {
		return err
	}
	err = stopAppRemotely(ctx, info.AppCycleMgrName, deadline)
	reap.forciblySuspend(instanceDir)
	if err == nil {
		reap.stopWatching(instanceDir)
	}
	return err
}

func (i *appService) Delete(ctx *context.T, _ rpc.ServerCall) error {
	instanceDir, err := i.instanceDir()
	if err != nil {
		return err
	}
	return transitionInstance(instanceDir, device.InstanceStateNotRunning, device.InstanceStateDeleted)
}

func (i *appService) Kill(ctx *context.T, _ rpc.ServerCall, deadline time.Duration) error {
	instanceDir, err := i.instanceDir()
	if err != nil {
		return err
	}
	if err := transitionInstance(instanceDir, device.InstanceStateRunning, device.InstanceStateDying); err != nil {
		return err
	}
	if err := stop(ctx, instanceDir, i.reap, deadline); err != nil {
		transitionInstance(instanceDir, device.InstanceStateDying, device.InstanceStateRunning)
		return err
	}
	return transitionInstance(instanceDir, device.InstanceStateDying, device.InstanceStateNotRunning)
}

func (i *appService) Uninstall(*context.T, rpc.ServerCall) error {
	installationDir, err := i.installationDir()
	if err != nil {
		return err
	}
	return transitionInstallation(installationDir, device.InstallationStateActive, device.InstallationStateUninstalled)
}

func updateInstance(instanceDir string, ctx *context.T) (err error) {
	// Only not-running instances can be updated.
	if err := transitionInstance(instanceDir, device.InstanceStateNotRunning, device.InstanceStateUpdating); err != nil {
		return err
	}
	defer func() {
		terr := transitionInstance(instanceDir, device.InstanceStateUpdating, device.InstanceStateNotRunning)
		if err == nil {
			err = terr
		}
	}()
	// Check if a newer version of the installation is available.
	versionLink := filepath.Join(instanceDir, "version")
	versionDir, err := filepath.EvalSymlinks(versionLink)
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
	}
	latestVersionLink := filepath.Join(instanceDir, "installation", "current")
	latestVersionDir, err := filepath.EvalSymlinks(latestVersionLink)
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", latestVersionLink, err))
	}
	if versionDir == latestVersionDir {
		return verror.New(ErrUpdateNoOp, ctx)
	}
	// Update to the newer version.  Note, this is the only mutation
	// performed to the instance, and, since it's atomic, the state of the
	// instance is consistent at all times.
	return updateLink(latestVersionDir, versionLink)
}

func updateInstallation(ctx *context.T, installationDir string) error {
	if !installationStateIs(installationDir, device.InstallationStateActive) {
		return verror.New(ErrInvalidOperation, ctx)
	}
	originVON, err := loadOrigin(ctx, installationDir)
	if err != nil {
		return err
	}
	ctx, cancel := context.WithTimeout(ctx, rpcContextLongTimeout)
	defer cancel()
	newEnvelope, err := fetchAppEnvelope(ctx, originVON)
	if err != nil {
		return err
	}
	currLink := filepath.Join(installationDir, "current")
	oldVersionDir, err := filepath.EvalSymlinks(currLink)
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", currLink, err))
	}
	// NOTE(caprita): A race can occur between two competing updates, where
	// both use the old version as their baseline.  This can result in both
	// updates succeeding even if they are updating the app installation to
	// the same new envelope.  This will result in one of the updates
	// becoming the new 'current'.  Both versions will point their
	// 'previous' link to the old version.  This doesn't appear to be of
	// practical concern, so we avoid the complexity of synchronizing
	// updates.
	oldEnvelope, err := loadEnvelope(ctx, oldVersionDir)
	if err != nil {
		return err
	}
	if oldEnvelope.Title != newEnvelope.Title {
		return verror.New(ErrAppTitleMismatch, ctx)
	}
	if reflect.DeepEqual(oldEnvelope, newEnvelope) {
		return verror.New(ErrUpdateNoOp, ctx)
	}
	versionDir, err := newVersion(ctx, installationDir, newEnvelope, oldVersionDir)
	if err != nil {
		CleanupDir(versionDir, "")
		return err
	}
	return nil
}

func (i *appService) Update(ctx *context.T, _ rpc.ServerCall) error {
	if installationDir, err := i.installationDir(); err == nil {
		return updateInstallation(ctx, installationDir)
	}
	if instanceDir, err := i.instanceDir(); err == nil {
		return updateInstance(instanceDir, ctx)
	}
	return verror.New(ErrInvalidSuffix, nil)
}

func (*appService) UpdateTo(_ *context.T, _ rpc.ServerCall, von string) error {
	// TODO(jsimsa): Implement.
	return nil
}

func (i *appService) Revert(ctx *context.T, _ rpc.ServerCall) error {
	installationDir, err := i.installationDir()
	if err != nil {
		return err
	}
	if !installationStateIs(installationDir, device.InstallationStateActive) {
		return verror.New(ErrInvalidOperation, ctx)
	}
	// NOTE(caprita): A race can occur between an update and a revert, where
	// both use the same current version as their starting point.  This will
	// render the update inconsequential.  This doesn't appear to be of
	// practical concern, so we avoid the complexity of synchronizing
	// updates and revert operations.
	currLink := filepath.Join(installationDir, "current")
	currVersionDir, err := filepath.EvalSymlinks(currLink)
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", currLink, err))
	}
	previousLink := filepath.Join(currVersionDir, "previous")
	if _, err := os.Lstat(previousLink); err != nil {
		if os.IsNotExist(err) {
			// No 'previous' link -- must be the first version.
			return verror.New(ErrUpdateNoOp, ctx)
		}
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Lstat(%v) failed: %v", previousLink, err))
	}
	prevVersionDir, err := filepath.EvalSymlinks(previousLink)
	if err != nil {
		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", previousLink, err))
	}
	return updateLink(prevVersionDir, currLink)
}

type treeNode struct {
	children map[string]*treeNode
}

func newTreeNode() *treeNode {
	return &treeNode{children: make(map[string]*treeNode)}
}

func (n *treeNode) find(names []string, create bool) *treeNode {
	for {
		if len(names) == 0 {
			return n
		}
		if next, ok := n.children[names[0]]; ok {
			n = next
			names = names[1:]
			continue
		}
		if create {
			nn := newTreeNode()
			n.children[names[0]] = nn
			n = nn
			names = names[1:]
			continue
		}
		return nil
	}
}

func (i *appService) scanEnvelopes(ctx *context.T, tree *treeNode, appDir string) {
	// Find all envelopes, extract installID.
	envGlob := []string{i.config.Root, appDir, "installation-*", "*", "envelope"}
	envelopes, err := filepath.Glob(filepath.Join(envGlob...))
	if err != nil {
		vlog.Errorf("unexpected error: %v", err)
		return
	}
	for _, path := range envelopes {
		env, err := loadEnvelope(ctx, filepath.Dir(path))
		if err != nil {
			continue
		}
		relpath, _ := filepath.Rel(i.config.Root, path)
		elems := strings.Split(relpath, string(filepath.Separator))
		if len(elems) != len(envGlob)-1 {
			vlog.Errorf("unexpected number of path components: %q (%q)", elems, path)
			continue
		}
		installID := strings.TrimPrefix(elems[1], "installation-")
		tree.find([]string{env.Title, installID}, true)
	}
	return
}

func (i *appService) scanInstances(ctx *context.T, tree *treeNode) {
	if len(i.suffix) < 2 {
		return
	}
	title := i.suffix[0]
	installDir, err := installationDirCore(i.suffix[:2], i.config.Root)
	if err != nil {
		return
	}
	// Add the node corresponding to the installation itself.
	tree.find(i.suffix[:2], true)
	// Find all instances.
	infoGlob := []string{installDir, "instances", "instance-*", "info"}
	instances, err := filepath.Glob(filepath.Join(infoGlob...))
	if err != nil {
		vlog.Errorf("unexpected error: %v", err)
		return
	}
	for _, path := range instances {
		instanceDir := filepath.Dir(path)
		i.scanInstance(ctx, tree, title, instanceDir)
	}
	return
}

func (i *appService) scanInstance(ctx *context.T, tree *treeNode, title, instanceDir string) {
	if _, err := loadInstanceInfo(ctx, instanceDir); err != nil {
		return
	}
	relpath, _ := filepath.Rel(i.config.Root, instanceDir)
	elems := strings.Split(relpath, string(filepath.Separator))
	if len(elems) < 4 {
		vlog.Errorf("unexpected number of path components: %q (%q)", elems, instanceDir)
		return
	}
	installID := strings.TrimPrefix(elems[1], "installation-")
	instanceID := strings.TrimPrefix(elems[3], "instance-")
	tree.find([]string{title, installID, instanceID, "logs"}, true)
	if instanceStateIs(instanceDir, device.InstanceStateRunning) {
		for _, obj := range []string{"pprof", "stats"} {
			tree.find([]string{title, installID, instanceID, obj}, true)
		}
	}
}

func (i *appService) GlobChildren__(ctx *context.T, _ rpc.ServerCall) (<-chan string, error) {
	tree := newTreeNode()
	switch len(i.suffix) {
	case 0:
		i.scanEnvelopes(ctx, tree, "app-*")
	case 1:
		appDir := applicationDirName(i.suffix[0])
		i.scanEnvelopes(ctx, tree, appDir)
	case 2:
		i.scanInstances(ctx, tree)
	case 3:
		dir, err := i.instanceDir()
		if err != nil {
			break
		}
		i.scanInstance(ctx, tree, i.suffix[0], dir)
	default:
		return nil, verror.New(verror.ErrNoExist, nil, i.suffix)
	}
	n := tree.find(i.suffix, false)
	if n == nil {
		return nil, verror.New(ErrInvalidSuffix, nil)
	}
	ch := make(chan string)
	go func() {
		for child, _ := range n.children {
			ch <- child
		}
		close(ch)
	}()
	return ch, nil
}

// TODO(rjkroege): Refactor to eliminate redundancy with newAppSpecificAuthorizer.
func dirFromSuffix(suffix []string, root string) (string, bool, error) {
	if len(suffix) == 2 {
		p, err := installationDirCore(suffix, root)
		if err != nil {
			vlog.Errorf("dirFromSuffix failed: %v", err)
			return "", false, err
		}
		return p, false, nil
	} else if len(suffix) > 2 {
		p, err := instanceDir(root, suffix[0:3])
		if err != nil {
			vlog.Errorf("dirFromSuffix failed: %v", err)
			return "", false, err
		}
		return p, true, nil
	}
	return "", false, verror.New(ErrInvalidSuffix, nil)
}

// TODO(rjkroege): Consider maintaining an in-memory Permissions cache.
func (i *appService) SetPermissions(ctx *context.T, call rpc.ServerCall, perms access.Permissions, version string) error {
	dir, isInstance, err := dirFromSuffix(i.suffix, i.config.Root)
	if err != nil {
		return err
	}
	if isInstance {
		dmBlessings := security.LocalBlessingNames(ctx, call.Security())
		if err := setPermsForDebugging(dmBlessings, perms, dir, i.permsStore); err != nil {
			return err
		}
	}
	return i.permsStore.Set(path.Join(dir, "acls"), perms, version)
}

func (i *appService) GetPermissions(*context.T, rpc.ServerCall) (perms access.Permissions, version string, err error) {
	dir, _, err := dirFromSuffix(i.suffix, i.config.Root)
	if err != nil {
		return nil, "", err
	}
	return i.permsStore.Get(path.Join(dir, "acls"))
}

func (i *appService) Debug(ctx *context.T, call rpc.ServerCall) (string, error) {
	switch len(i.suffix) {
	case 2:
		return i.installationDebug(ctx)
	case 3:
		return i.instanceDebug(ctx, call.Security())
	default:
		return "", verror.New(ErrInvalidSuffix, nil)
	}
}

func (i *appService) installationDebug(ctx *context.T) (string, error) {
	const installationDebug = `Installation dir: {{.InstallationDir}}

Origin: {{.Origin}}

Envelope: {{printf "%+v" .Envelope}}

Config: {{printf "%+v" .Config}}
`
	installationDebugTemplate, err := template.New("installation-debug").Parse(installationDebug)
	if err != nil {
		return "", err
	}

	installationDir, err := i.installationDir()
	if err != nil {
		return "", err
	}
	debugInfo := struct {
		InstallationDir, Origin string
		Envelope                *application.Envelope
		Config                  device.Config
	}{}
	debugInfo.InstallationDir = installationDir

	if origin, err := loadOrigin(ctx, installationDir); err != nil {
		return "", err
	} else {
		debugInfo.Origin = origin
	}

	currLink := filepath.Join(installationDir, "current")
	if envelope, err := loadEnvelope(ctx, currLink); err != nil {
		return "", err
	} else {
		debugInfo.Envelope = envelope
	}

	if config, err := loadConfig(ctx, installationDir); err != nil {
		return "", err
	} else {
		debugInfo.Config = config
	}

	var buf bytes.Buffer
	if err := installationDebugTemplate.Execute(&buf, debugInfo); err != nil {
		return "", err
	}
	return buf.String(), nil

}

func (i *appService) instanceDebug(ctx *context.T, call security.Call) (string, error) {
	const instanceDebug = `Instance dir: {{.InstanceDir}}

System name / start system name: {{.SystemName}} / {{.StartSystemName}}

Cmd: {{printf "%+v" .Cmd}}

Info: {{printf "%+v" .Info}}

Principal: {{.PrincipalType}}
Public Key: {{.Principal.PublicKey}}
Blessing Store: {{.Principal.BlessingStore.DebugString}}
Roots: {{.Principal.Roots.DebugString}}
`
	instanceDebugTemplate, err := template.New("instance-debug").Parse(instanceDebug)
	if err != nil {
		return "", err
	}

	instanceDir, err := i.instanceDir()
	if err != nil {
		return "", err
	}
	debugInfo := struct {
		InstanceDir, SystemName, StartSystemName string
		Cmd                                      *exec.Cmd
		Info                                     *instanceInfo
		Principal                                security.Principal
		PrincipalType                            string
	}{}
	debugInfo.InstanceDir = instanceDir

	debugInfo.SystemName = suidHelper.usernameForPrincipal(ctx, call, i.uat)
	if startSystemName, err := readSystemNameForInstance(instanceDir); err != nil {
		return "", err
	} else {
		debugInfo.StartSystemName = startSystemName
	}
	as := *i.appStart
	as.instanceDir = instanceDir
	as.systemName = debugInfo.SystemName
	if cmd, err := as.genCmd(ctx); err != nil {
		return "", err
	} else {
		debugInfo.Cmd = cmd
	}
	if info, err := loadInstanceInfo(ctx, instanceDir); err != nil {
		return "", err
	} else {
		debugInfo.Info = info
	}

	if sa := i.appStart.securityAgent; sa != nil {
		file, err := sa.keyMgrAgent.NewConnection(debugInfo.Info.SecurityAgentHandle)
		if err != nil {
			vlog.Errorf("NewConnection(%v) failed: %v", debugInfo.Info.SecurityAgentHandle, err)
			return "", err
		}
		var cancel func()
		if debugInfo.Principal, cancel, err = agentPrincipal(ctx, file); err != nil {
			return "", err
		}
		defer cancel()
		debugInfo.PrincipalType = "Agent-based"
	} else {
		credentialsDir := filepath.Join(instanceDir, "credentials")
		var err error
		if debugInfo.Principal, err = vsecurity.LoadPersistentPrincipal(credentialsDir, nil); err != nil {
			return "", err
		}
		debugInfo.PrincipalType = fmt.Sprintf("Credentials dir-based (%v)", credentialsDir)
	}
	var buf bytes.Buffer
	if err := instanceDebugTemplate.Execute(&buf, debugInfo); err != nil {
		return "", err
	}
	return buf.String(), nil
}

func (i *appService) Status(ctx *context.T, _ rpc.ServerCall) (device.Status, error) {
	switch len(i.suffix) {
	case 2:
		status, err := i.installationStatus(ctx)
		return device.StatusInstallation{Value: status}, err
	case 3:
		status, err := i.instanceStatus(ctx)
		return device.StatusInstance{Value: status}, err
	default:
		return nil, verror.New(ErrInvalidSuffix, ctx)
	}
}

func (i *appService) installationStatus(ctx *context.T) (device.InstallationStatus, error) {
	installationDir, err := i.installationDir()
	if err != nil {
		return device.InstallationStatus{}, err
	}
	state, err := getInstallationState(installationDir)
	if err != nil {
		return device.InstallationStatus{}, err
	}
	versionLink := filepath.Join(installationDir, "current")
	versionDir, err := filepath.EvalSymlinks(versionLink)
	if err != nil {
		return device.InstallationStatus{}, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
	}
	return device.InstallationStatus{
		State:   state,
		Version: filepath.Base(versionDir),
	}, nil
}

func (i *appService) instanceStatus(ctx *context.T) (device.InstanceStatus, error) {
	instanceDir, err := i.instanceDir()
	if err != nil {
		return device.InstanceStatus{}, err
	}
	state, err := getInstanceState(instanceDir)
	if err != nil {
		return device.InstanceStatus{}, err
	}
	versionLink := filepath.Join(instanceDir, "version")
	versionDir, err := filepath.EvalSymlinks(versionLink)
	if err != nil {
		return device.InstanceStatus{}, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
	}
	return device.InstanceStatus{
		State:   state,
		Version: filepath.Base(versionDir),
	}, nil
}
