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