launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/cmd/juju/main.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 "fmt" 8 "os" 9 10 "github.com/loggo/loggo" 11 "launchpad.net/errgo/errors" 12 13 "launchpad.net/juju-core/cmd" 14 "launchpad.net/juju-core/environs" 15 "launchpad.net/juju-core/juju" 16 17 // Import the providers. 18 _ "launchpad.net/juju-core/provider/all" 19 ) 20 21 var logger = loggo.GetLogger("juju.cmd.juju") 22 23 var mask = errors.Mask 24 25 var jujuDoc = ` 26 juju provides easy, intelligent service orchestration on top of cloud 27 infrastructure providers such as Amazon EC2, HP Cloud, MaaS, OpenStack, Windows 28 Azure, or your local machine. 29 30 https://juju.ubuntu.com/ 31 ` 32 33 var x = []byte("\x96\x8c\x99\x8a\x9c\x94\x96\x91\x98\xdf\x9e\x92\x9e\x85\x96\x91\x98\xf5") 34 35 // Main registers subcommands for the juju executable, and hands over control 36 // to the cmd package. This function is not redundant with main, because it 37 // provides an entry point for testing with arbitrary command line arguments. 38 func Main(args []string) { 39 if err := juju.InitJujuHome(); err != nil { 40 fmt.Fprintf(os.Stderr, "error: %s\n", err) 41 os.Exit(2) 42 } 43 for i := range x { 44 x[i] ^= 255 45 } 46 if len(args) == 2 && args[1] == string(x[0:2]) { 47 os.Stdout.Write(x[2:]) 48 os.Exit(0) 49 } 50 jujucmd := cmd.NewSuperCommand(cmd.SuperCommandParams{ 51 Name: "juju", 52 Doc: jujuDoc, 53 Log: &cmd.Log{}, 54 MissingCallback: RunPlugin, 55 }) 56 jujucmd.AddHelpTopic("basics", "Basic commands", helpBasics) 57 jujucmd.AddHelpTopic("local", "How to configure a local (LXC) provider", 58 helpProviderStart+helpLocalProvider+helpProviderEnd) 59 jujucmd.AddHelpTopic("openstack", "How to configure an OpenStack provider", 60 helpProviderStart+helpOpenstackProvider+helpProviderEnd) 61 jujucmd.AddHelpTopic("ec2", "How to configure an Amazon EC2 provider", 62 helpProviderStart+helpEC2Provider+helpProviderEnd) 63 jujucmd.AddHelpTopic("hpcloud", "How to configure an HP Cloud provider", 64 helpProviderStart+helpHPCloud+helpProviderEnd) 65 jujucmd.AddHelpTopic("azure", "How to configure a Windows Azure provider", 66 helpProviderStart+helpAzureProvider+helpProviderEnd) 67 jujucmd.AddHelpTopic("constraints", "How to use commands with constraints", helpConstraints) 68 jujucmd.AddHelpTopic("glossary", "Glossary of terms", helpGlossary) 69 jujucmd.AddHelpTopic("logging", "How Juju handles logging", helpLogging) 70 71 jujucmd.AddHelpTopicCallback("plugins", "Show Juju plugins", PluginHelpTopic) 72 73 // Creation commands. 74 jujucmd.Register(wrapCmd(&BootstrapCommand{})) 75 jujucmd.Register(wrapCmd(&AddMachineCommand{})) 76 jujucmd.Register(wrapCmd(&DeployCommand{})) 77 jujucmd.Register(wrapCmd(&AddRelationCommand{})) 78 jujucmd.Register(wrapCmd(&AddUnitCommand{})) 79 80 // Destruction commands. 81 jujucmd.Register(wrapCmd(&DestroyMachineCommand{})) 82 jujucmd.Register(wrapCmd(&DestroyRelationCommand{})) 83 jujucmd.Register(wrapCmd(&DestroyServiceCommand{})) 84 jujucmd.Register(wrapCmd(&DestroyUnitCommand{})) 85 jujucmd.Register(wrapCmd(&DestroyEnvironmentCommand{})) 86 87 // Reporting commands. 88 jujucmd.Register(wrapCmd(&StatusCommand{})) 89 jujucmd.Register(wrapCmd(&SwitchCommand{})) 90 jujucmd.Register(wrapCmd(&EndpointCommand{})) 91 92 // Error resolution and debugging commands. 93 jujucmd.Register(wrapCmd(&RunCommand{})) 94 jujucmd.Register(wrapCmd(&SCPCommand{})) 95 jujucmd.Register(wrapCmd(&SSHCommand{})) 96 jujucmd.Register(wrapCmd(&ResolvedCommand{})) 97 jujucmd.Register(wrapCmd(&DebugLogCommand{sshCmd: &SSHCommand{}})) 98 jujucmd.Register(wrapCmd(&DebugHooksCommand{})) 99 100 // Configuration commands. 101 jujucmd.Register(wrapCmd(&InitCommand{})) 102 jujucmd.Register(wrapCmd(&GetCommand{})) 103 jujucmd.Register(wrapCmd(&SetCommand{})) 104 jujucmd.Register(wrapCmd(&UnsetCommand{})) 105 jujucmd.Register(wrapCmd(&GetConstraintsCommand{})) 106 jujucmd.Register(wrapCmd(&SetConstraintsCommand{})) 107 jujucmd.Register(wrapCmd(&GetEnvironmentCommand{})) 108 jujucmd.Register(wrapCmd(&SetEnvironmentCommand{})) 109 jujucmd.Register(wrapCmd(&ExposeCommand{})) 110 jujucmd.Register(wrapCmd(&SyncToolsCommand{})) 111 jujucmd.Register(wrapCmd(&UnexposeCommand{})) 112 jujucmd.Register(wrapCmd(&UpgradeJujuCommand{})) 113 jujucmd.Register(wrapCmd(&UpgradeCharmCommand{})) 114 115 // Charm publishing commands. 116 jujucmd.Register(wrapCmd(&PublishCommand{})) 117 118 // Charm tool commands. 119 jujucmd.Register(wrapCmd(&HelpToolCommand{})) 120 121 // Manage authorised ssh keys. 122 jujucmd.Register(wrapCmd(NewAuthorisedKeysCommand())) 123 124 // Common commands. 125 jujucmd.Register(wrapCmd(&cmd.VersionCommand{})) 126 127 os.Exit(cmd.Main(jujucmd, cmd.DefaultContext(), args[1:])) 128 } 129 130 // wrapCmd encapsulates code that wraps some of the commands in a helper class 131 // that handles some common errors 132 func wrapCmd(c cmd.Command) cmd.Command { 133 if ec, ok := c.(envCmd); ok { 134 return envCmdWrapper{ec} 135 } 136 return c 137 } 138 139 // envCmd is a Command that interacts with the juju client environment 140 type envCmd interface { 141 cmd.Command 142 EnvironName() string 143 } 144 145 // envCmdWrapper is a struct that wraps an environment command and lets us handle 146 // errors returned from Run before they're returned to the main function 147 type envCmdWrapper struct { 148 envCmd 149 } 150 151 // Run in envCmdWrapper gives us an opportunity to handle errors after the command is 152 // run. This is used to give informative messages to the user. 153 func (c envCmdWrapper) Run(ctx *cmd.Context) error { 154 err := c.envCmd.Run(ctx) 155 if environs.IsNoEnv(err) && c.EnvironName() == "" { 156 fmt.Fprintln(ctx.Stderr, "No juju environment configuration file exists.") 157 fmt.Fprintln(ctx.Stderr, err) 158 fmt.Fprintln(ctx.Stderr, "Please create a configuration by running:") 159 fmt.Fprintln(ctx.Stderr, " juju init") 160 fmt.Fprintln(ctx.Stderr, "then edit the file to configure your juju environment.") 161 fmt.Fprintln(ctx.Stderr, "You can then re-run the command.") 162 return cmd.ErrSilent 163 } 164 165 return err 166 } 167 168 func main() { 169 Main(os.Args) 170 }