github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/commands/main.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package commands 5 6 import ( 7 "fmt" 8 "os" 9 "os/exec" 10 "strings" 11 12 "github.com/juju/cmd" 13 "github.com/juju/loggo" 14 rcmd "github.com/juju/romulus/cmd/commands" 15 "github.com/juju/utils/featureflag" 16 "github.com/juju/version" 17 18 jujucmd "github.com/juju/juju/cmd" 19 "github.com/juju/juju/cmd/juju/action" 20 "github.com/juju/juju/cmd/juju/backups" 21 "github.com/juju/juju/cmd/juju/block" 22 "github.com/juju/juju/cmd/juju/cachedimages" 23 "github.com/juju/juju/cmd/juju/charmcmd" 24 "github.com/juju/juju/cmd/juju/cloud" 25 "github.com/juju/juju/cmd/juju/controller" 26 "github.com/juju/juju/cmd/juju/gui" 27 "github.com/juju/juju/cmd/juju/machine" 28 "github.com/juju/juju/cmd/juju/metricsdebug" 29 "github.com/juju/juju/cmd/juju/model" 30 "github.com/juju/juju/cmd/juju/service" 31 "github.com/juju/juju/cmd/juju/setmeterstatus" 32 "github.com/juju/juju/cmd/juju/space" 33 "github.com/juju/juju/cmd/juju/status" 34 "github.com/juju/juju/cmd/juju/storage" 35 "github.com/juju/juju/cmd/juju/subnet" 36 "github.com/juju/juju/cmd/juju/user" 37 "github.com/juju/juju/cmd/modelcmd" 38 "github.com/juju/juju/feature" 39 "github.com/juju/juju/juju" 40 "github.com/juju/juju/juju/osenv" 41 jujuversion "github.com/juju/juju/version" 42 // Import the providers. 43 _ "github.com/juju/juju/provider/all" 44 ) 45 46 var logger = loggo.GetLogger("juju.cmd.juju.commands") 47 48 func init() { 49 featureflag.SetFlagsFromEnvironment(osenv.JujuFeatureFlagEnvKey) 50 } 51 52 // TODO(ericsnow) Move the following to cmd/juju/main.go: 53 // jujuDoc 54 // Main 55 56 var jujuDoc = ` 57 juju provides easy, intelligent service orchestration on top of cloud 58 infrastructure providers such as Amazon EC2, HP Cloud, MaaS, OpenStack, Windows 59 Azure, or your local machine. 60 61 https://juju.ubuntu.com/ 62 ` 63 64 const juju1xCmdName = "juju-1" 65 66 var usageHelp = ` 67 Usage: juju [help] <command> 68 69 Summary: 70 Juju is model & service management software designed to leverage the power 71 of existing resource pools, particularly cloud-based ones. It has built-in 72 support for cloud providers such as Amazon EC2, Google GCE, Microsoft 73 Azure, OpenStack, and Rackspace. It also works very well with MAAS and 74 LXD. Juju allows for easy installation and management of workloads on a 75 chosen resource pool. 76 77 See https://jujucharms.com/docs/stable/help for documentation. 78 79 Common commands: 80 81 add-credential Adds or replaces credentials for a cloud. 82 add-relation Adds a relation between two services. 83 add-unit Adds extra units of a deployed service. 84 add-user Adds a Juju user to a controller. 85 bootstrap Initializes a cloud environment. 86 create-model Creates a hosted model. 87 deploy Deploys a new service. 88 expose Makes a service publicly available over the network. 89 list-controllers Lists all controllers. 90 list-models Lists models a user can access on a controller. 91 status Displays the current status of Juju, services, and units. 92 switch Selects or identifies the current controller and model. 93 94 Example help commands: 95 96 `[1:] + "`juju help`" + ` This help page 97 ` + "`juju help commands`" + ` Lists all commands 98 ` + "`juju help deploy`" + ` Shows help for command 'deploy' 99 ` 100 101 var x = []byte("\x96\x8c\x99\x8a\x9c\x94\x96\x91\x98\xdf\x9e\x92\x9e\x85\x96\x91\x98\xf5") 102 103 // Main registers subcommands for the juju executable, and hands over control 104 // to the cmd package. This function is not redundant with main, because it 105 // provides an entry point for testing with arbitrary command line arguments. 106 func Main(args []string) { 107 ctx, err := cmd.DefaultContext() 108 if err != nil { 109 fmt.Fprintf(os.Stderr, "error: %v\n", err) 110 os.Exit(2) 111 } 112 113 if shouldWarnJuju1x() { 114 warnJuju1x() 115 } 116 117 if err = juju.InitJujuXDGDataHome(); err != nil { 118 fmt.Fprintf(os.Stderr, "error: %s\n", err) 119 os.Exit(2) 120 } 121 122 for i := range x { 123 x[i] ^= 255 124 } 125 if len(args) == 2 && args[1] == string(x[0:2]) { 126 os.Stdout.Write(x[2:]) 127 os.Exit(0) 128 } 129 130 jcmd := NewJujuCommand(ctx) 131 os.Exit(cmd.Main(jcmd, ctx, args[1:])) 132 } 133 134 func warnJuju1x() { 135 ver := "1.x" 136 out, err := execCommand(juju1xCmdName, "version").Output() 137 if err == nil { 138 v := strings.TrimSpace(string(out)) 139 // parse so we can drop the series and arch 140 bin, err := version.ParseBinary(v) 141 if err == nil { 142 ver = bin.Number.String() 143 } 144 } 145 fmt.Fprintf(os.Stderr, ` 146 Welcome to Juju %s. If you meant to use Juju %s you can continue using it 147 with the command %s e.g. '%s switch'. 148 See https://jujucharms.com/docs/stable/introducing-2 for more details. 149 `[1:], jujuversion.Current, ver, juju1xCmdName, juju1xCmdName) 150 } 151 152 var execCommand = exec.Command 153 var execLookPath = exec.LookPath 154 155 func shouldWarnJuju1x() bool { 156 if _, err := execLookPath(juju1xCmdName); err != nil { 157 return false 158 } 159 return osenv.Juju1xEnvConfigExists() && 160 !juju2xConfigDataExists() 161 } 162 163 func juju2xConfigDataExists() bool { 164 _, err := os.Stat(osenv.JujuXDGDataHomeDir()) 165 return err == nil 166 } 167 168 // NewJujuCommand ... 169 func NewJujuCommand(ctx *cmd.Context) cmd.Command { 170 jcmd := jujucmd.NewSuperCommand(cmd.SuperCommandParams{ 171 Name: "juju", 172 Doc: jujuDoc, 173 MissingCallback: RunPlugin, 174 UserAliasesFilename: osenv.JujuXDGDataHomePath("aliases"), 175 }) 176 jcmd.AddHelpTopic("basics", "Basic Help Summary", usageHelp) 177 registerCommands(jcmd, ctx) 178 return jcmd 179 } 180 181 type commandRegistry interface { 182 Register(cmd.Command) 183 RegisterSuperAlias(name, super, forName string, check cmd.DeprecationCheck) 184 RegisterDeprecated(subcmd cmd.Command, check cmd.DeprecationCheck) 185 } 186 187 // TODO(ericsnow) Factor out the commands and aliases into a static 188 // registry that can be passed to the supercommand separately. 189 190 // registerCommands registers commands in the specified registry. 191 func registerCommands(r commandRegistry, ctx *cmd.Context) { 192 // Creation commands. 193 r.Register(newBootstrapCommand()) 194 r.Register(service.NewAddRelationCommand()) 195 196 // Destruction commands. 197 r.Register(service.NewRemoveRelationCommand()) 198 r.Register(service.NewRemoveServiceCommand()) 199 r.Register(service.NewRemoveUnitCommand()) 200 201 // Reporting commands. 202 r.Register(status.NewStatusCommand()) 203 r.Register(newSwitchCommand()) 204 r.Register(status.NewStatusHistoryCommand()) 205 206 // Error resolution and debugging commands. 207 r.Register(newRunCommand()) 208 r.Register(newSCPCommand()) 209 r.Register(newSSHCommand()) 210 r.Register(newResolvedCommand()) 211 r.Register(newDebugLogCommand()) 212 r.Register(newDebugHooksCommand()) 213 214 // Configuration commands. 215 r.Register(model.NewModelGetConstraintsCommand()) 216 r.Register(model.NewModelSetConstraintsCommand()) 217 r.Register(newSyncToolsCommand()) 218 r.Register(newUpgradeJujuCommand(nil)) 219 r.Register(service.NewUpgradeCharmCommand()) 220 221 // Charm publishing commands. 222 r.Register(newPublishCommand()) 223 224 // Charm tool commands. 225 r.Register(newHelpToolCommand()) 226 r.Register(charmcmd.NewSuperCommand()) 227 228 // Manage backups. 229 r.Register(backups.NewCreateCommand()) 230 r.Register(backups.NewDownloadCommand()) 231 r.Register(backups.NewShowCommand()) 232 r.Register(backups.NewListCommand()) 233 r.Register(backups.NewRemoveCommand()) 234 r.Register(backups.NewRestoreCommand()) 235 r.Register(backups.NewUploadCommand()) 236 237 // Manage authorized ssh keys. 238 r.Register(NewAddKeysCommand()) 239 r.Register(NewRemoveKeysCommand()) 240 r.Register(NewImportKeysCommand()) 241 r.Register(NewListKeysCommand()) 242 243 // Manage users and access 244 r.Register(user.NewAddCommand()) 245 r.Register(user.NewChangePasswordCommand()) 246 r.Register(user.NewShowUserCommand()) 247 r.Register(user.NewListCommand()) 248 r.Register(user.NewEnableCommand()) 249 r.Register(user.NewDisableCommand()) 250 r.Register(user.NewLoginCommand()) 251 r.Register(user.NewLogoutCommand()) 252 253 // Manage cached images 254 r.Register(cachedimages.NewRemoveCommand()) 255 r.Register(cachedimages.NewListCommand()) 256 257 // Manage machines 258 r.Register(machine.NewAddCommand()) 259 r.Register(machine.NewRemoveCommand()) 260 r.Register(machine.NewListMachinesCommand()) 261 r.Register(machine.NewShowMachineCommand()) 262 263 // Manage model 264 r.Register(model.NewGetCommand()) 265 r.Register(model.NewSetCommand()) 266 r.Register(model.NewUnsetCommand()) 267 r.Register(model.NewRetryProvisioningCommand()) 268 r.Register(model.NewDestroyCommand()) 269 r.Register(model.NewUsersCommand()) 270 r.Register(model.NewGrantCommand()) 271 r.Register(model.NewRevokeCommand()) 272 r.Register(model.NewShowCommand()) 273 274 if featureflag.Enabled(feature.Migration) { 275 r.Register(newMigrateCommand()) 276 } 277 278 // Manage and control actions 279 r.Register(action.NewStatusCommand()) 280 r.Register(action.NewRunCommand()) 281 r.Register(action.NewShowOutputCommand()) 282 r.Register(action.NewListCommand()) 283 284 // Manage controller availability 285 r.Register(newEnableHACommand()) 286 287 // Manage and control services 288 r.Register(service.NewAddUnitCommand()) 289 r.Register(service.NewGetCommand()) 290 r.Register(service.NewSetCommand()) 291 r.Register(service.NewDeployCommand()) 292 r.Register(service.NewExposeCommand()) 293 r.Register(service.NewUnexposeCommand()) 294 r.Register(service.NewServiceGetConstraintsCommand()) 295 r.Register(service.NewServiceSetConstraintsCommand()) 296 297 // Operation protection commands 298 r.Register(block.NewSuperBlockCommand()) 299 r.Register(block.NewUnblockCommand()) 300 301 // Manage storage 302 r.Register(storage.NewAddCommand()) 303 r.Register(storage.NewListCommand()) 304 r.Register(storage.NewPoolCreateCommand()) 305 r.Register(storage.NewPoolListCommand()) 306 r.Register(storage.NewShowCommand()) 307 308 // Manage spaces 309 r.Register(space.NewAddCommand()) 310 r.Register(space.NewListCommand()) 311 if featureflag.Enabled(feature.PostNetCLIMVP) { 312 r.Register(space.NewRemoveCommand()) 313 r.Register(space.NewUpdateCommand()) 314 r.Register(space.NewRenameCommand()) 315 } 316 317 // Manage subnets 318 r.Register(subnet.NewAddCommand()) 319 r.Register(subnet.NewListCommand()) 320 if featureflag.Enabled(feature.PostNetCLIMVP) { 321 r.Register(subnet.NewCreateCommand()) 322 r.Register(subnet.NewRemoveCommand()) 323 } 324 325 // Manage controllers 326 r.Register(controller.NewCreateModelCommand()) 327 r.Register(controller.NewDestroyCommand()) 328 r.Register(controller.NewListModelsCommand()) 329 r.Register(controller.NewKillCommand()) 330 r.Register(controller.NewListControllersCommand()) 331 r.Register(controller.NewListBlocksCommand()) 332 r.Register(controller.NewRegisterCommand()) 333 r.Register(controller.NewRemoveBlocksCommand()) 334 r.Register(controller.NewShowControllerCommand()) 335 336 // Debug Metrics 337 r.Register(metricsdebug.New()) 338 r.Register(metricsdebug.NewCollectMetricsCommand()) 339 r.Register(setmeterstatus.New()) 340 341 // Manage clouds and credentials 342 r.Register(cloud.NewUpdateCloudsCommand()) 343 r.Register(cloud.NewListCloudsCommand()) 344 r.Register(cloud.NewShowCloudCommand()) 345 r.Register(cloud.NewAddCloudCommand()) 346 r.Register(cloud.NewListCredentialsCommand()) 347 r.Register(cloud.NewDetectCredentialsCommand()) 348 r.Register(cloud.NewSetDefaultRegionCommand()) 349 r.Register(cloud.NewSetDefaultCredentialCommand()) 350 r.Register(cloud.NewAddCredentialCommand()) 351 r.Register(cloud.NewRemoveCredentialCommand()) 352 353 // Juju GUI commands. 354 r.Register(gui.NewGUICommand()) 355 r.Register(gui.NewUpgradeGUICommand()) 356 357 // Commands registered elsewhere. 358 for _, newCommand := range registeredCommands { 359 command := newCommand() 360 r.Register(command) 361 } 362 for _, newCommand := range registeredEnvCommands { 363 command := newCommand() 364 r.Register(modelcmd.Wrap(command)) 365 } 366 rcmd.RegisterAll(r) 367 }