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