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  }