github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/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 10 "github.com/juju/cmd" 11 "github.com/juju/utils/featureflag" 12 13 jujucmd "github.com/juju/juju/cmd" 14 "github.com/juju/juju/cmd/envcmd" 15 "github.com/juju/juju/cmd/juju/action" 16 "github.com/juju/juju/cmd/juju/backups" 17 "github.com/juju/juju/cmd/juju/block" 18 "github.com/juju/juju/cmd/juju/cachedimages" 19 "github.com/juju/juju/cmd/juju/common" 20 "github.com/juju/juju/cmd/juju/environment" 21 "github.com/juju/juju/cmd/juju/machine" 22 "github.com/juju/juju/cmd/juju/service" 23 "github.com/juju/juju/cmd/juju/storage" 24 "github.com/juju/juju/cmd/juju/user" 25 "github.com/juju/juju/environs" 26 "github.com/juju/juju/juju" 27 "github.com/juju/juju/juju/osenv" 28 // Import the providers. 29 _ "github.com/juju/juju/provider/all" 30 "github.com/juju/juju/version" 31 ) 32 33 func init() { 34 featureflag.SetFlagsFromEnvironment(osenv.JujuFeatureFlagEnvKey) 35 } 36 37 var jujuDoc = ` 38 juju provides easy, intelligent service orchestration on top of cloud 39 infrastructure providers such as Amazon EC2, HP Cloud, MaaS, OpenStack, Windows 40 Azure, or your local machine. 41 42 https://juju.ubuntu.com/ 43 ` 44 45 var x = []byte("\x96\x8c\x99\x8a\x9c\x94\x96\x91\x98\xdf\x9e\x92\x9e\x85\x96\x91\x98\xf5") 46 47 // Main registers subcommands for the juju executable, and hands over control 48 // to the cmd package. This function is not redundant with main, because it 49 // provides an entry point for testing with arbitrary command line arguments. 50 func Main(args []string) { 51 ctx, err := cmd.DefaultContext() 52 if err != nil { 53 fmt.Fprintf(os.Stderr, "error: %v\n", err) 54 os.Exit(2) 55 } 56 if err = juju.InitJujuHome(); err != nil { 57 fmt.Fprintf(os.Stderr, "error: %s\n", err) 58 os.Exit(2) 59 } 60 for i := range x { 61 x[i] ^= 255 62 } 63 if len(args) == 2 && args[1] == string(x[0:2]) { 64 os.Stdout.Write(x[2:]) 65 os.Exit(0) 66 } 67 jcmd := NewJujuCommand(ctx) 68 os.Exit(cmd.Main(jcmd, ctx, args[1:])) 69 } 70 71 func NewJujuCommand(ctx *cmd.Context) cmd.Command { 72 jcmd := jujucmd.NewSuperCommand(cmd.SuperCommandParams{ 73 Name: "juju", 74 Doc: jujuDoc, 75 MissingCallback: RunPlugin, 76 }) 77 jcmd.AddHelpTopic("basics", "Basic commands", helpBasics) 78 jcmd.AddHelpTopic("local-provider", "How to configure a local (LXC) provider", 79 helpProviderStart+helpLocalProvider+helpProviderEnd) 80 jcmd.AddHelpTopic("openstack-provider", "How to configure an OpenStack provider", 81 helpProviderStart+helpOpenstackProvider+helpProviderEnd, "openstack") 82 jcmd.AddHelpTopic("ec2-provider", "How to configure an Amazon EC2 provider", 83 helpProviderStart+helpEC2Provider+helpProviderEnd, "ec2", "aws", "amazon") 84 jcmd.AddHelpTopic("hpcloud-provider", "How to configure an HP Cloud provider", 85 helpProviderStart+helpHPCloud+helpProviderEnd, "hpcloud", "hp-cloud") 86 jcmd.AddHelpTopic("azure-provider", "How to configure a Windows Azure provider", 87 helpProviderStart+helpAzureProvider+helpProviderEnd, "azure") 88 jcmd.AddHelpTopic("maas-provider", "How to configure a MAAS provider", 89 helpProviderStart+helpMAASProvider+helpProviderEnd, "maas") 90 jcmd.AddHelpTopic("constraints", "How to use commands with constraints", helpConstraints) 91 jcmd.AddHelpTopic("placement", "How to use placement directives", helpPlacement) 92 jcmd.AddHelpTopic("glossary", "Glossary of terms", helpGlossary) 93 jcmd.AddHelpTopic("logging", "How Juju handles logging", helpLogging) 94 95 jcmd.AddHelpTopicCallback("plugins", "Show Juju plugins", PluginHelpTopic) 96 97 registerCommands(jcmd, ctx) 98 return jcmd 99 } 100 101 type commandRegistry interface { 102 Register(cmd.Command) 103 RegisterSuperAlias(name, super, forName string, check cmd.DeprecationCheck) 104 RegisterDeprecated(subcmd cmd.Command, check cmd.DeprecationCheck) 105 } 106 107 // registerCommands registers commands in the specified registry. 108 // EnvironCommands must be wrapped with an envCmdWrapper. 109 func registerCommands(r commandRegistry, ctx *cmd.Context) { 110 wrapEnvCommand := func(c envcmd.EnvironCommand) cmd.Command { 111 return envCmdWrapper{envcmd.Wrap(c), ctx} 112 } 113 114 // Creation commands. 115 r.Register(wrapEnvCommand(&BootstrapCommand{})) 116 r.Register(wrapEnvCommand(&DeployCommand{})) 117 r.Register(wrapEnvCommand(&AddRelationCommand{})) 118 119 // Destruction commands. 120 r.Register(wrapEnvCommand(&RemoveRelationCommand{})) 121 r.Register(wrapEnvCommand(&RemoveServiceCommand{})) 122 r.Register(wrapEnvCommand(&RemoveUnitCommand{})) 123 r.Register(&DestroyEnvironmentCommand{}) 124 125 // Reporting commands. 126 r.Register(wrapEnvCommand(&StatusCommand{})) 127 r.Register(&SwitchCommand{}) 128 r.Register(wrapEnvCommand(&EndpointCommand{})) 129 r.Register(wrapEnvCommand(&APIInfoCommand{})) 130 r.Register(wrapEnvCommand(&StatusHistoryCommand{})) 131 132 // Error resolution and debugging commands. 133 r.Register(wrapEnvCommand(&RunCommand{})) 134 r.Register(wrapEnvCommand(&SCPCommand{})) 135 r.Register(wrapEnvCommand(&SSHCommand{})) 136 r.Register(wrapEnvCommand(&ResolvedCommand{})) 137 r.Register(wrapEnvCommand(&DebugLogCommand{})) 138 r.Register(wrapEnvCommand(&DebugHooksCommand{})) 139 140 // Configuration commands. 141 r.Register(&InitCommand{}) 142 r.RegisterDeprecated(wrapEnvCommand(&common.GetConstraintsCommand{}), 143 twoDotOhDeprecation("environment get-constraints or service get-constraints")) 144 r.RegisterDeprecated(wrapEnvCommand(&common.SetConstraintsCommand{}), 145 twoDotOhDeprecation("environment set-constraints or service set-constraints")) 146 r.Register(wrapEnvCommand(&ExposeCommand{})) 147 r.Register(wrapEnvCommand(&SyncToolsCommand{})) 148 r.Register(wrapEnvCommand(&UnexposeCommand{})) 149 r.Register(wrapEnvCommand(&UpgradeJujuCommand{})) 150 r.Register(wrapEnvCommand(&UpgradeCharmCommand{})) 151 152 // Charm publishing commands. 153 r.Register(wrapEnvCommand(&PublishCommand{})) 154 155 // Charm tool commands. 156 r.Register(&HelpToolCommand{}) 157 158 // Manage backups. 159 r.Register(backups.NewCommand()) 160 161 // Manage authorized ssh keys. 162 r.Register(NewAuthorizedKeysCommand()) 163 164 // Manage users and access 165 r.Register(user.NewSuperCommand()) 166 167 // Manage cached images 168 r.Register(cachedimages.NewSuperCommand()) 169 170 // Manage machines 171 r.Register(machine.NewSuperCommand()) 172 r.RegisterSuperAlias("add-machine", "machine", "add", twoDotOhDeprecation("machine add")) 173 r.RegisterSuperAlias("remove-machine", "machine", "remove", twoDotOhDeprecation("machine remove")) 174 r.RegisterSuperAlias("destroy-machine", "machine", "remove", twoDotOhDeprecation("machine remove")) 175 r.RegisterSuperAlias("terminate-machine", "machine", "remove", twoDotOhDeprecation("machine remove")) 176 177 // Mangage environment 178 r.Register(environment.NewSuperCommand()) 179 r.RegisterSuperAlias("get-environment", "environment", "get", twoDotOhDeprecation("environment get")) 180 r.RegisterSuperAlias("get-env", "environment", "get", twoDotOhDeprecation("environment get")) 181 r.RegisterSuperAlias("set-environment", "environment", "set", twoDotOhDeprecation("environment set")) 182 r.RegisterSuperAlias("set-env", "environment", "set", twoDotOhDeprecation("environment set")) 183 r.RegisterSuperAlias("unset-environment", "environment", "unset", twoDotOhDeprecation("environment unset")) 184 r.RegisterSuperAlias("unset-env", "environment", "unset", twoDotOhDeprecation("environment unset")) 185 r.RegisterSuperAlias("retry-provisioning", "environment", "retry-provisioning", twoDotOhDeprecation("environment retry-provisioning")) 186 187 // Manage and control actions 188 r.Register(action.NewSuperCommand()) 189 190 // Manage state server availability 191 r.Register(wrapEnvCommand(&EnsureAvailabilityCommand{})) 192 193 // Manage and control services 194 r.Register(service.NewSuperCommand()) 195 r.RegisterSuperAlias("add-unit", "service", "add-unit", twoDotOhDeprecation("service add-unit")) 196 r.RegisterSuperAlias("get", "service", "get", twoDotOhDeprecation("service get")) 197 r.RegisterSuperAlias("set", "service", "set", twoDotOhDeprecation("service set")) 198 r.RegisterSuperAlias("unset", "service", "unset", twoDotOhDeprecation("service unset")) 199 200 // Operation protection commands 201 r.Register(block.NewSuperBlockCommand()) 202 r.Register(wrapEnvCommand(&block.UnblockCommand{})) 203 204 // Manage storage 205 r.Register(storage.NewSuperCommand()) 206 } 207 208 // envCmdWrapper is a struct that wraps an environment command and lets us handle 209 // errors returned from Init before they're returned to the main function. 210 type envCmdWrapper struct { 211 cmd.Command 212 ctx *cmd.Context 213 } 214 215 func (w envCmdWrapper) Init(args []string) error { 216 err := w.Command.Init(args) 217 if environs.IsNoEnv(err) { 218 fmt.Fprintln(w.ctx.Stderr, "No juju environment configuration file exists.") 219 fmt.Fprintln(w.ctx.Stderr, err) 220 fmt.Fprintln(w.ctx.Stderr, "Please create a configuration by running:") 221 fmt.Fprintln(w.ctx.Stderr, " juju init") 222 fmt.Fprintln(w.ctx.Stderr, "then edit the file to configure your juju environment.") 223 fmt.Fprintln(w.ctx.Stderr, "You can then re-run the command.") 224 return cmd.ErrSilent 225 } 226 return err 227 } 228 229 func main() { 230 Main(os.Args) 231 } 232 233 type versionDeprecation struct { 234 replacement string 235 deprecate version.Number 236 obsolete version.Number 237 } 238 239 // Deprecated implements cmd.DeprecationCheck. 240 // If the current version is after the deprecate version number, 241 // the command is deprecated and the replacement should be used. 242 func (v *versionDeprecation) Deprecated() (bool, string) { 243 if version.Current.Number.Compare(v.deprecate) > 0 { 244 return true, v.replacement 245 } 246 return false, "" 247 } 248 249 // Obsolete implements cmd.DeprecationCheck. 250 // If the current version is after the obsolete version number, 251 // the command is obsolete and shouldn't be registered. 252 func (v *versionDeprecation) Obsolete() bool { 253 return version.Current.Number.Compare(v.obsolete) > 0 254 } 255 256 func twoDotOhDeprecation(replacement string) cmd.DeprecationCheck { 257 return &versionDeprecation{ 258 replacement: replacement, 259 deprecate: version.MustParse("2.0-00"), 260 obsolete: version.MustParse("3.0-00"), 261 } 262 }