github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/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  	"launchpad.net/gnuflag"
    12  
    13  	"github.com/juju/juju/cmd"
    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  }