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