github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/cmd/juju/set.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package main 5 6 import ( 7 "errors" 8 "fmt" 9 "strings" 10 11 "github.com/juju/cmd" 12 "launchpad.net/gnuflag" 13 14 "github.com/juju/juju/cmd/envcmd" 15 "github.com/juju/juju/juju" 16 ) 17 18 // SetCommand updates the configuration of a service. 19 type SetCommand struct { 20 envcmd.EnvCommandBase 21 ServiceName string 22 SettingsStrings map[string]string 23 SettingsYAML cmd.FileVar 24 } 25 26 const setDoc = ` 27 Set one or more configuration options for the specified service. See also the 28 unset command which sets one or more configuration options for a specified 29 service to their default value. 30 ` 31 32 func (c *SetCommand) Info() *cmd.Info { 33 return &cmd.Info{ 34 Name: "set", 35 Args: "<service> name=value ...", 36 Purpose: "set service config options", 37 Doc: "Set one or more configuration options for the specified service.", 38 } 39 } 40 41 func (c *SetCommand) SetFlags(f *gnuflag.FlagSet) { 42 f.Var(&c.SettingsYAML, "config", "path to yaml-formatted service config") 43 } 44 45 func (c *SetCommand) Init(args []string) error { 46 if len(args) == 0 || len(strings.Split(args[0], "=")) > 1 { 47 return errors.New("no service name specified") 48 } 49 if c.SettingsYAML.Path != "" && len(args) > 1 { 50 return errors.New("cannot specify --config when using key=value arguments") 51 } 52 c.ServiceName = args[0] 53 settings, err := parse(args[1:]) 54 if err != nil { 55 return err 56 } 57 c.SettingsStrings = settings 58 return nil 59 } 60 61 // Run updates the configuration of a service. 62 func (c *SetCommand) Run(ctx *cmd.Context) error { 63 api, err := juju.NewAPIClientFromName(c.EnvName) 64 if err != nil { 65 return err 66 } 67 defer api.Close() 68 69 if c.SettingsYAML.Path != "" { 70 b, err := c.SettingsYAML.Read(ctx) 71 if err != nil { 72 return err 73 } 74 return api.ServiceSetYAML(c.ServiceName, string(b)) 75 } else if len(c.SettingsStrings) == 0 { 76 return nil 77 } 78 return api.ServiceSet(c.ServiceName, c.SettingsStrings) 79 } 80 81 // parse parses the option k=v strings into a map of options to be 82 // updated in the config. Keys with empty values are returned separately 83 // and should be removed. 84 func parse(options []string) (map[string]string, error) { 85 kv := make(map[string]string) 86 for _, o := range options { 87 s := strings.SplitN(o, "=", 2) 88 if len(s) != 2 || s[0] == "" { 89 return nil, fmt.Errorf("invalid option: %q", o) 90 } 91 kv[s[0]] = s[1] 92 } 93 return kv, nil 94 }