blob: aefa724333fc8dd74eb93b470c35f8c22c87e6d8 [file] [log] [blame]
// 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 main
import (
"fmt"
"v.io/v23"
"v.io/v23/context"
"v.io/v23/naming"
"v.io/v23/rpc"
"v.io/v23/security"
"v.io/v23/services/device"
"v.io/x/lib/cmdline"
"v.io/x/ref/lib/v23cmd"
)
var cmdInstantiate = &cmdline.Command{
Runner: v23cmd.RunnerFunc(runInstantiate),
Name: "instantiate",
Short: "Create an instance of the given application.",
Long: "Create an instance of the given application, provide it with a blessing, and print the name of the new instance.",
ArgsName: "<application installation> <grant extension>",
ArgsLong: `
<application installation> is the vanadium object name of the
application installation from which to create an instance.
<grant extension> is used to extend the default blessing of the
current principal when blessing the app instance.`,
}
type granter struct {
rpc.CallOpt
extension string
}
func (g *granter) Grant(ctx *context.T, call security.Call) (security.Blessings, error) {
p := call.LocalPrincipal()
b, _ := p.BlessingStore().Default()
return p.Bless(call.RemoteBlessings().PublicKey(), b, g.extension, security.UnconstrainedUse())
}
func runInstantiate(ctx *context.T, env *cmdline.Env, args []string) error {
if expected, got := 2, len(args); expected != got {
return env.UsageErrorf("instantiate: incorrect number of arguments, expected %d, got %d", expected, got)
}
appInstallation, grant := args[0], args[1]
ctx, cancel := context.WithCancel(ctx)
defer cancel()
principal := v23.GetPrincipal(ctx)
call, err := device.ApplicationClient(appInstallation).Instantiate(ctx)
if err != nil {
return fmt.Errorf("Instantiate failed: %v", err)
}
for call.RecvStream().Advance() {
switch msg := call.RecvStream().Value().(type) {
case device.BlessServerMessageInstancePublicKey:
pubKey, err := security.UnmarshalPublicKey(msg.Value)
if err != nil {
return fmt.Errorf("Instantiate failed: %v", err)
}
// TODO(caprita,rthellend): Get rid of security.UnconstrainedUse().
toextend, _ := principal.BlessingStore().Default()
blessings, err := principal.Bless(pubKey, toextend, grant, security.UnconstrainedUse())
if err != nil {
return fmt.Errorf("Instantiate failed: %v", err)
}
call.SendStream().Send(device.BlessClientMessageAppBlessings{Value: blessings})
default:
fmt.Fprintf(env.Stderr, "Received unexpected message: %#v\n", msg)
}
}
var instanceID string
if instanceID, err = call.Finish(); err != nil {
return fmt.Errorf("Instantiate failed: %v", err)
}
fmt.Fprintf(env.Stdout, "%s\n", naming.Join(appInstallation, instanceID))
return nil
}