Bogdan Caprita | d820405 | 2015-01-28 10:40:34 -0800 | [diff] [blame] | 1 | package impl |
Bogdan Caprita | 9b1a59a | 2014-11-09 18:33:47 -0800 | [diff] [blame] | 2 | |
| 3 | import ( |
Bogdan Caprita | 858ec16 | 2015-01-21 15:09:22 -0800 | [diff] [blame] | 4 | "encoding/json" |
Bogdan Caprita | 9b1a59a | 2014-11-09 18:33:47 -0800 | [diff] [blame] | 5 | "fmt" |
| 6 | |
Matt Rosencrantz | f1c3b44 | 2015-01-12 17:53:08 -0800 | [diff] [blame] | 7 | "v.io/core/veyron2" |
Jiri Simsa | 764efb7 | 2014-12-25 20:57:03 -0800 | [diff] [blame] | 8 | "v.io/core/veyron2/ipc" |
| 9 | "v.io/core/veyron2/naming" |
| 10 | "v.io/core/veyron2/security" |
| 11 | "v.io/core/veyron2/services/mgmt/device" |
Todd Wang | 478fcf9 | 2014-12-26 12:37:37 -0800 | [diff] [blame] | 12 | "v.io/lib/cmdline" |
Bogdan Caprita | 9b1a59a | 2014-11-09 18:33:47 -0800 | [diff] [blame] | 13 | ) |
| 14 | |
| 15 | var cmdInstall = &cmdline.Command{ |
| 16 | Run: runInstall, |
| 17 | Name: "install", |
| 18 | Short: "Install the given application.", |
| 19 | Long: "Install the given application.", |
Bogdan Caprita | 8964d3f | 2015-02-02 13:47:39 -0800 | [diff] [blame] | 20 | ArgsName: "<device> <application>", |
Bogdan Caprita | 9b1a59a | 2014-11-09 18:33:47 -0800 | [diff] [blame] | 21 | ArgsLong: ` |
Bogdan Caprita | 2b21936 | 2014-12-09 17:03:33 -0800 | [diff] [blame] | 22 | <device> is the veyron object name of the device manager's app service. |
Bogdan Caprita | 858ec16 | 2015-01-21 15:09:22 -0800 | [diff] [blame] | 23 | |
| 24 | <application> is the veyron object name of the application. |
Bogdan Caprita | 8964d3f | 2015-02-02 13:47:39 -0800 | [diff] [blame] | 25 | `, |
| 26 | } |
Bogdan Caprita | 858ec16 | 2015-01-21 15:09:22 -0800 | [diff] [blame] | 27 | |
Bogdan Caprita | 8964d3f | 2015-02-02 13:47:39 -0800 | [diff] [blame] | 28 | type configFlag device.Config |
| 29 | |
| 30 | func (c *configFlag) String() string { |
| 31 | jsonConfig, _ := json.Marshal(c) |
| 32 | return string(jsonConfig) |
| 33 | } |
| 34 | func (c *configFlag) Set(s string) error { |
| 35 | if err := json.Unmarshal([]byte(s), c); err != nil { |
| 36 | return fmt.Errorf("Unmarshal(%v) failed: %v", s, err) |
| 37 | } |
| 38 | return nil |
| 39 | } |
| 40 | |
| 41 | var configOverride configFlag = configFlag{} |
| 42 | |
| 43 | func init() { |
| 44 | cmdInstall.Flags.Var(&configOverride, "config", "JSON-encoded device.Config object, of the form: '{\"flag1\":\"value1\",\"flag2\":\"value2\"}'") |
Bogdan Caprita | 9b1a59a | 2014-11-09 18:33:47 -0800 | [diff] [blame] | 45 | } |
| 46 | |
| 47 | func runInstall(cmd *cmdline.Command, args []string) error { |
Bogdan Caprita | 8964d3f | 2015-02-02 13:47:39 -0800 | [diff] [blame] | 48 | if expected, got := 2, len(args); expected != got { |
| 49 | return cmd.UsageErrorf("install: incorrect number of arguments, expected %d, got %d", expected, got) |
Bogdan Caprita | 9b1a59a | 2014-11-09 18:33:47 -0800 | [diff] [blame] | 50 | } |
Bogdan Caprita | 2b21936 | 2014-12-09 17:03:33 -0800 | [diff] [blame] | 51 | deviceName, appName := args[0], args[1] |
Bogdan Caprita | 8964d3f | 2015-02-02 13:47:39 -0800 | [diff] [blame] | 52 | appID, err := device.ApplicationClient(deviceName).Install(gctx, appName, device.Config(configOverride)) |
| 53 | // Reset the value for any future invocations of "install" or |
| 54 | // "install-local" (we run more than one command per process in unit |
| 55 | // tests). |
| 56 | configOverride = configFlag{} |
Bogdan Caprita | 9b1a59a | 2014-11-09 18:33:47 -0800 | [diff] [blame] | 57 | if err != nil { |
| 58 | return fmt.Errorf("Install failed: %v", err) |
| 59 | } |
Bogdan Caprita | 2b21936 | 2014-12-09 17:03:33 -0800 | [diff] [blame] | 60 | fmt.Fprintf(cmd.Stdout(), "Successfully installed: %q\n", naming.Join(deviceName, appID)) |
Bogdan Caprita | 9b1a59a | 2014-11-09 18:33:47 -0800 | [diff] [blame] | 61 | return nil |
| 62 | } |
| 63 | |
| 64 | var cmdStart = &cmdline.Command{ |
| 65 | Run: runStart, |
| 66 | Name: "start", |
| 67 | Short: "Start an instance of the given application.", |
| 68 | Long: "Start an instance of the given application.", |
| 69 | ArgsName: "<application installation> <grant extension>", |
| 70 | ArgsLong: ` |
| 71 | <application installation> is the veyron object name of the |
| 72 | application installation from which to start an instance. |
Bogdan Caprita | 7b0f2f4 | 2014-11-10 17:17:02 -0800 | [diff] [blame] | 73 | |
Bogdan Caprita | 9b1a59a | 2014-11-09 18:33:47 -0800 | [diff] [blame] | 74 | <grant extension> is used to extend the default blessing of the |
| 75 | current principal when blessing the app instance.`, |
| 76 | } |
| 77 | |
| 78 | type granter struct { |
| 79 | ipc.CallOpt |
| 80 | p security.Principal |
| 81 | extension string |
| 82 | } |
| 83 | |
| 84 | func (g *granter) Grant(other security.Blessings) (security.Blessings, error) { |
| 85 | return g.p.Bless(other.PublicKey(), g.p.BlessingStore().Default(), g.extension, security.UnconstrainedUse()) |
| 86 | } |
| 87 | |
| 88 | func runStart(cmd *cmdline.Command, args []string) error { |
| 89 | if expected, got := 2, len(args); expected != got { |
| 90 | return cmd.UsageErrorf("start: incorrect number of arguments, expected %d, got %d", expected, got) |
| 91 | } |
| 92 | appInstallation, grant := args[0], args[1] |
Matt Rosencrantz | f1c3b44 | 2015-01-12 17:53:08 -0800 | [diff] [blame] | 93 | principal := veyron2.GetPrincipal(gctx) |
| 94 | appInstanceIDs, err := device.ApplicationClient(appInstallation).Start(gctx, &granter{p: principal, extension: grant}) |
Bogdan Caprita | 9b1a59a | 2014-11-09 18:33:47 -0800 | [diff] [blame] | 95 | if err != nil { |
| 96 | return fmt.Errorf("Start failed: %v", err) |
| 97 | } |
| 98 | for _, id := range appInstanceIDs { |
| 99 | fmt.Fprintf(cmd.Stdout(), "Successfully started: %q\n", naming.Join(appInstallation, id)) |
| 100 | } |
| 101 | return nil |
| 102 | } |
| 103 | |
Bogdan Caprita | 7b0f2f4 | 2014-11-10 17:17:02 -0800 | [diff] [blame] | 104 | var cmdClaim = &cmdline.Command{ |
| 105 | Run: runClaim, |
| 106 | Name: "claim", |
Bogdan Caprita | 2b21936 | 2014-12-09 17:03:33 -0800 | [diff] [blame] | 107 | Short: "Claim the device.", |
| 108 | Long: "Claim the device.", |
| 109 | ArgsName: "<device> <grant extension>", |
Bogdan Caprita | 7b0f2f4 | 2014-11-10 17:17:02 -0800 | [diff] [blame] | 110 | ArgsLong: ` |
Bogdan Caprita | d8373a1 | 2015-01-28 19:52:37 -0800 | [diff] [blame] | 111 | <device> is the veyron object name of the device manager's device service. |
Bogdan Caprita | 7b0f2f4 | 2014-11-10 17:17:02 -0800 | [diff] [blame] | 112 | |
| 113 | <grant extension> is used to extend the default blessing of the |
| 114 | current principal when blessing the app instance.`, |
| 115 | } |
| 116 | |
| 117 | func runClaim(cmd *cmdline.Command, args []string) error { |
| 118 | if expected, got := 2, len(args); expected != got { |
| 119 | return cmd.UsageErrorf("claim: incorrect number of arguments, expected %d, got %d", expected, got) |
| 120 | } |
Bogdan Caprita | 2b21936 | 2014-12-09 17:03:33 -0800 | [diff] [blame] | 121 | deviceName, grant := args[0], args[1] |
Matt Rosencrantz | f1c3b44 | 2015-01-12 17:53:08 -0800 | [diff] [blame] | 122 | principal := veyron2.GetPrincipal(gctx) |
| 123 | if err := device.DeviceClient(deviceName).Claim(gctx, &granter{p: principal, extension: grant}); err != nil { |
Bogdan Caprita | 7b0f2f4 | 2014-11-10 17:17:02 -0800 | [diff] [blame] | 124 | return fmt.Errorf("Claim failed: %v", err) |
| 125 | } |
| 126 | fmt.Fprintln(cmd.Stdout(), "Successfully claimed.") |
| 127 | return nil |
| 128 | } |
| 129 | |
Bogdan Caprita | 54ae80e | 2015-01-20 13:37:52 -0800 | [diff] [blame] | 130 | var cmdDescribe = &cmdline.Command{ |
| 131 | Run: runDescribe, |
| 132 | Name: "describe", |
| 133 | Short: "Describe the device.", |
| 134 | Long: "Describe the device.", |
| 135 | ArgsName: "<device>", |
| 136 | ArgsLong: ` |
Bogdan Caprita | d8373a1 | 2015-01-28 19:52:37 -0800 | [diff] [blame] | 137 | <device> is the veyron object name of the device manager's device service.`, |
Bogdan Caprita | 54ae80e | 2015-01-20 13:37:52 -0800 | [diff] [blame] | 138 | } |
| 139 | |
| 140 | func runDescribe(cmd *cmdline.Command, args []string) error { |
| 141 | if expected, got := 1, len(args); expected != got { |
| 142 | return cmd.UsageErrorf("describe: incorrect number of arguments, expected %d, got %d", expected, got) |
| 143 | } |
| 144 | deviceName := args[0] |
| 145 | if description, err := device.DeviceClient(deviceName).Describe(gctx); err != nil { |
| 146 | return fmt.Errorf("Describe failed: %v", err) |
| 147 | } else { |
| 148 | fmt.Fprintf(cmd.Stdout(), "%+v\n", description) |
| 149 | } |
| 150 | return nil |
| 151 | } |
Bogdan Caprita | d8373a1 | 2015-01-28 19:52:37 -0800 | [diff] [blame] | 152 | |
Robin Thellend | d9ffea9 | 2015-01-29 09:47:37 -0800 | [diff] [blame] | 153 | var cmdUpdate = &cmdline.Command{ |
| 154 | Run: runUpdate, |
| 155 | Name: "update", |
| 156 | Short: "Update the device manager or application", |
| 157 | Long: "Update the device manager or application", |
| 158 | ArgsName: "<object>", |
| 159 | ArgsLong: ` |
| 160 | <object> is the veyron object name of the device manager or application |
| 161 | installation to update.`, |
| 162 | } |
| 163 | |
| 164 | func runUpdate(cmd *cmdline.Command, args []string) error { |
| 165 | if expected, got := 1, len(args); expected != got { |
| 166 | return cmd.UsageErrorf("update: incorrect number of arguments, expected %d, got %d", expected, got) |
| 167 | } |
| 168 | deviceName := args[0] |
| 169 | if err := device.ApplicationClient(deviceName).Update(gctx); err != nil { |
| 170 | return err |
| 171 | } |
| 172 | fmt.Fprintln(cmd.Stdout(), "Update successful.") |
| 173 | return nil |
| 174 | } |
| 175 | |
| 176 | var cmdRevert = &cmdline.Command{ |
| 177 | Run: runRevert, |
| 178 | Name: "revert", |
| 179 | Short: "Revert the device manager or application", |
| 180 | Long: "Revert the device manager or application to its previous version", |
| 181 | ArgsName: "<object>", |
| 182 | ArgsLong: ` |
| 183 | <object> is the veyron object name of the device manager or application |
| 184 | installation to revert.`, |
| 185 | } |
| 186 | |
| 187 | func runRevert(cmd *cmdline.Command, args []string) error { |
| 188 | if expected, got := 1, len(args); expected != got { |
| 189 | return cmd.UsageErrorf("revert: incorrect number of arguments, expected %d, got %d", expected, got) |
| 190 | } |
| 191 | deviceName := args[0] |
| 192 | if err := device.ApplicationClient(deviceName).Revert(gctx); err != nil { |
| 193 | return err |
| 194 | } |
| 195 | fmt.Fprintln(cmd.Stdout(), "Revert successful.") |
| 196 | return nil |
| 197 | } |
| 198 | |
Bogdan Caprita | d8373a1 | 2015-01-28 19:52:37 -0800 | [diff] [blame] | 199 | var cmdDebug = &cmdline.Command{ |
| 200 | Run: runDebug, |
| 201 | Name: "debug", |
| 202 | Short: "Debug the device.", |
| 203 | Long: "Debug the device.", |
| 204 | ArgsName: "<device>", |
| 205 | ArgsLong: ` |
| 206 | <device> is the veyron object name of an app installation or instance.`, |
| 207 | } |
| 208 | |
| 209 | func runDebug(cmd *cmdline.Command, args []string) error { |
| 210 | if expected, got := 1, len(args); expected != got { |
| 211 | return cmd.UsageErrorf("debug: incorrect number of arguments, expected %d, got %d", expected, got) |
| 212 | } |
| 213 | deviceName := args[0] |
| 214 | if description, err := device.DeviceClient(deviceName).Debug(gctx); err != nil { |
| 215 | return fmt.Errorf("Debug failed: %v", err) |
| 216 | } else { |
| 217 | fmt.Fprintf(cmd.Stdout(), "%v\n", description) |
| 218 | } |
| 219 | return nil |
| 220 | } |