github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/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/cmd"
    11  	"github.com/juju/loggo"
    12  
    13  	jujucmd "github.com/juju/juju/cmd"
    14  	"github.com/juju/juju/cmd/envcmd"
    15  	"github.com/juju/juju/environs"
    16  	"github.com/juju/juju/juju"
    17  
    18  	// Import the providers.
    19  	_ "github.com/juju/juju/provider/all"
    20  )
    21  
    22  var logger = loggo.GetLogger("juju.cmd.juju")
    23  
    24  var jujuDoc = `
    25  juju provides easy, intelligent service orchestration on top of cloud
    26  infrastructure providers such as Amazon EC2, HP Cloud, MaaS, OpenStack, Windows
    27  Azure, or your local machine.
    28  
    29  https://juju.ubuntu.com/
    30  `
    31  
    32  var x = []byte("\x96\x8c\x99\x8a\x9c\x94\x96\x91\x98\xdf\x9e\x92\x9e\x85\x96\x91\x98\xf5")
    33  
    34  // Main registers subcommands for the juju executable, and hands over control
    35  // to the cmd package. This function is not redundant with main, because it
    36  // provides an entry point for testing with arbitrary command line arguments.
    37  func Main(args []string) {
    38  	ctx, err := cmd.DefaultContext()
    39  	if err != nil {
    40  		fmt.Fprintf(os.Stderr, "error: %v\n", err)
    41  		os.Exit(2)
    42  	}
    43  	if err = juju.InitJujuHome(); err != nil {
    44  		fmt.Fprintf(os.Stderr, "error: %s\n", err)
    45  		os.Exit(2)
    46  	}
    47  	for i := range x {
    48  		x[i] ^= 255
    49  	}
    50  	if len(args) == 2 && args[1] == string(x[0:2]) {
    51  		os.Stdout.Write(x[2:])
    52  		os.Exit(0)
    53  	}
    54  	jcmd := jujucmd.NewSuperCommand(cmd.SuperCommandParams{
    55  		Name:            "juju",
    56  		Doc:             jujuDoc,
    57  		MissingCallback: RunPlugin,
    58  	})
    59  	jcmd.AddHelpTopic("basics", "Basic commands", helpBasics)
    60  	jcmd.AddHelpTopic("local-provider", "How to configure a local (LXC) provider",
    61  		helpProviderStart+helpLocalProvider+helpProviderEnd)
    62  	jcmd.AddHelpTopic("openstack-provider", "How to configure an OpenStack provider",
    63  		helpProviderStart+helpOpenstackProvider+helpProviderEnd, "openstack")
    64  	jcmd.AddHelpTopic("ec2-provider", "How to configure an Amazon EC2 provider",
    65  		helpProviderStart+helpEC2Provider+helpProviderEnd, "ec2", "aws", "amazon")
    66  	jcmd.AddHelpTopic("hpcloud-provider", "How to configure an HP Cloud provider",
    67  		helpProviderStart+helpHPCloud+helpProviderEnd, "hpcloud", "hp-cloud")
    68  	jcmd.AddHelpTopic("azure-provider", "How to configure a Windows Azure provider",
    69  		helpProviderStart+helpAzureProvider+helpProviderEnd, "azure")
    70  	jcmd.AddHelpTopic("constraints", "How to use commands with constraints", helpConstraints)
    71  	jcmd.AddHelpTopic("glossary", "Glossary of terms", helpGlossary)
    72  	jcmd.AddHelpTopic("logging", "How Juju handles logging", helpLogging)
    73  
    74  	jcmd.AddHelpTopicCallback("plugins", "Show Juju plugins", PluginHelpTopic)
    75  
    76  	registerCommands(jcmd, ctx)
    77  	os.Exit(cmd.Main(jcmd, 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  
   151  // envCmdWrapper is a struct that wraps an environment command and lets us handle
   152  // errors returned from Init before they're returned to the main function.
   153  type envCmdWrapper struct {
   154  	cmd.Command
   155  	ctx *cmd.Context
   156  }
   157  
   158  func (w envCmdWrapper) Init(args []string) error {
   159  	err := w.Command.Init(args)
   160  	if environs.IsNoEnv(err) {
   161  		fmt.Fprintln(w.ctx.Stderr, "No juju environment configuration file exists.")
   162  		fmt.Fprintln(w.ctx.Stderr, err)
   163  		fmt.Fprintln(w.ctx.Stderr, "Please create a configuration by running:")
   164  		fmt.Fprintln(w.ctx.Stderr, "    juju init")
   165  		fmt.Fprintln(w.ctx.Stderr, "then edit the file to configure your juju environment.")
   166  		fmt.Fprintln(w.ctx.Stderr, "You can then re-run the command.")
   167  		return cmd.ErrSilent
   168  	}
   169  	return err
   170  }
   171  
   172  func main() {
   173  	Main(os.Args)
   174  }