github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/cmd/juju/application/constraints.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package application
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/errors"
    12  	"github.com/juju/gnuflag"
    13  	"gopkg.in/juju/names.v2"
    14  
    15  	"github.com/juju/juju/api/application"
    16  	"github.com/juju/juju/cmd/juju/block"
    17  	"github.com/juju/juju/cmd/modelcmd"
    18  	"github.com/juju/juju/constraints"
    19  )
    20  
    21  var usageGetConstraintsSummary = `
    22  Displays machine constraints for an application.`[1:]
    23  
    24  var usageGetConstraintsDetails = `
    25  Shows machine constraints that have been set for an application with ` + "`juju set-\nconstraints`" + `.
    26  By default, the model is the current model.
    27  Application constraints are combined with model constraints, set with ` +
    28  	"`juju \nset-model-constraints`" + `, for commands (such as 'deploy') that provision
    29  machines for applications. Where model and application constraints overlap, the
    30  application constraints take precedence.
    31  Constraints for a specific model can be viewed with ` + "`juju get-model-\nconstraints`" + `.
    32  
    33  Examples:
    34      juju get-constraints mysql
    35      juju get-constraints -m mymodel apache2
    36  
    37  See also: 
    38      set-constraints
    39      get-model-constraints
    40      set-model-constraints`
    41  
    42  var usageSetConstraintsSummary = `
    43  Sets machine constraints for an application.`[1:]
    44  
    45  // setConstraintsDoc is multi-line since we need to use ` to denote
    46  // commands for ease in markdown.
    47  var usageSetConstraintsDetails = `
    48  Sets constraints for an application, which are used for all new machines 
    49  provisioned for that application. They can be viewed with `[1:] + "`juju get-\nconstraints`" + `.
    50  By default, the model is the current model.
    51  Application constraints are combined with model constraints, set with ` +
    52  	"`juju \nset-model-constraints`" + `, for commands (such as 'juju deploy') that 
    53  provision machines for applications. Where model and application constraints
    54  overlap, the application constraints take precedence.
    55  Constraints for a specific model can be viewed with ` + "`juju get-model-\nconstraints`" + `.
    56  This command requires that the application to have at least one unit. To apply 
    57  constraints to
    58  the first unit set them at the model level or pass them as an argument
    59  when deploying.
    60  
    61  Examples:
    62      juju set-constraints mysql mem=8G cores=4
    63      juju set-constraints -m mymodel apache2 mem=8G arch=amd64
    64  
    65  See also: 
    66      get-constraints
    67      get-model-constraints
    68      set-model-constraints`
    69  
    70  // NewServiceGetConstraintsCommand returns a command which gets application constraints.
    71  func NewServiceGetConstraintsCommand() cmd.Command {
    72  	return modelcmd.Wrap(&serviceGetConstraintsCommand{})
    73  }
    74  
    75  type serviceConstraintsAPI interface {
    76  	Close() error
    77  	GetConstraints(string) (constraints.Value, error)
    78  	SetConstraints(string, constraints.Value) error
    79  }
    80  
    81  type serviceConstraintsCommand struct {
    82  	modelcmd.ModelCommandBase
    83  	ApplicationName string
    84  	out             cmd.Output
    85  	api             serviceConstraintsAPI
    86  }
    87  
    88  func (c *serviceConstraintsCommand) getAPI() (serviceConstraintsAPI, error) {
    89  	if c.api != nil {
    90  		return c.api, nil
    91  	}
    92  	root, err := c.NewAPIRoot()
    93  	if err != nil {
    94  		return nil, errors.Trace(err)
    95  	}
    96  	return application.NewClient(root), nil
    97  }
    98  
    99  type serviceGetConstraintsCommand struct {
   100  	serviceConstraintsCommand
   101  }
   102  
   103  func (c *serviceGetConstraintsCommand) Info() *cmd.Info {
   104  	return &cmd.Info{
   105  		Name:    "get-constraints",
   106  		Args:    "<application>",
   107  		Purpose: usageGetConstraintsSummary,
   108  		Doc:     usageGetConstraintsDetails,
   109  	}
   110  }
   111  
   112  func formatConstraints(writer io.Writer, value interface{}) error {
   113  	fmt.Fprint(writer, value.(constraints.Value).String())
   114  	return nil
   115  }
   116  
   117  func (c *serviceGetConstraintsCommand) SetFlags(f *gnuflag.FlagSet) {
   118  	c.ModelCommandBase.SetFlags(f)
   119  	c.out.AddFlags(f, "constraints", map[string]cmd.Formatter{
   120  		"constraints": formatConstraints,
   121  		"yaml":        cmd.FormatYaml,
   122  		"json":        cmd.FormatJson,
   123  	})
   124  }
   125  
   126  func (c *serviceGetConstraintsCommand) Init(args []string) error {
   127  	if len(args) == 0 {
   128  		return errors.Errorf("no application name specified")
   129  	}
   130  	if !names.IsValidApplication(args[0]) {
   131  		return errors.Errorf("invalid application name %q", args[0])
   132  	}
   133  
   134  	c.ApplicationName, args = args[0], args[1:]
   135  	return cmd.CheckEmpty(args)
   136  }
   137  
   138  func (c *serviceGetConstraintsCommand) Run(ctx *cmd.Context) error {
   139  	apiclient, err := c.getAPI()
   140  	if err != nil {
   141  		return err
   142  	}
   143  	defer apiclient.Close()
   144  
   145  	cons, err := apiclient.GetConstraints(c.ApplicationName)
   146  	if err != nil {
   147  		return err
   148  	}
   149  	return c.out.Write(ctx, cons)
   150  }
   151  
   152  type serviceSetConstraintsCommand struct {
   153  	serviceConstraintsCommand
   154  	Constraints constraints.Value
   155  }
   156  
   157  // NewServiceSetConstraintsCommand returns a command which sets application constraints.
   158  func NewServiceSetConstraintsCommand() cmd.Command {
   159  	return modelcmd.Wrap(&serviceSetConstraintsCommand{})
   160  }
   161  
   162  func (c *serviceSetConstraintsCommand) Info() *cmd.Info {
   163  	return &cmd.Info{
   164  		Name:    "set-constraints",
   165  		Args:    "<application> <constraint>=<value> ...",
   166  		Purpose: usageSetConstraintsSummary,
   167  		Doc:     usageSetConstraintsDetails,
   168  	}
   169  }
   170  
   171  func (c *serviceSetConstraintsCommand) Init(args []string) (err error) {
   172  	if len(args) == 0 {
   173  		return errors.Errorf("no application name specified")
   174  	}
   175  	if !names.IsValidApplication(args[0]) {
   176  		return errors.Errorf("invalid application name %q", args[0])
   177  	}
   178  
   179  	c.ApplicationName, args = args[0], args[1:]
   180  
   181  	c.Constraints, err = constraints.Parse(args...)
   182  	return err
   183  }
   184  
   185  func (c *serviceSetConstraintsCommand) Run(_ *cmd.Context) (err error) {
   186  	apiclient, err := c.getAPI()
   187  	if err != nil {
   188  		return err
   189  	}
   190  	defer apiclient.Close()
   191  
   192  	err = apiclient.SetConstraints(c.ApplicationName, c.Constraints)
   193  	return block.ProcessBlockedError(err, block.BlockChange)
   194  }