The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/2325
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Add manpage option to lxc
From ef3d24f434aea1239af6ed4ce7695bcbeee74853 Mon Sep 17 00:00:00 2001 From: Carlos <cneirabus...@gmail.com> Date: Thu, 25 Aug 2016 15:31:06 -0300 Subject: [PATCH 1/8] change lxc --help output to stdout Signed-off-by: Carlos <cneirabus...@gmail.com> --- lxc/#main.go# | 303 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lxc/.#main.go | 1 + lxc/help.go | 2 +- 3 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 lxc/#main.go# create mode 120000 lxc/.#main.go diff --git a/lxc/#main.go# b/lxc/#main.go# new file mode 100644 index 0000000..6b9a26c --- /dev/null +++ b/lxc/#main.go# @@ -0,0 +1,303 @@ +package main + +import ( + "fmt" + "os" + "os/exec" + "path" + "strings" + "syscall" + + "github.com/lxc/lxd" + "github.com/lxc/lxd/shared" + "github.com/lxc/lxd/shared/gnuflag" + "github.com/lxc/lxd/shared/i18n" + "github.com/lxc/lxd/shared/logging" +) + +var configPath string + +func main() { + if err := run(); err != nil { + msg := fmt.Sprintf(i18n.G("error: %v"), err) + + lxdErr := lxd.GetLocalLXDErr(err) + switch lxdErr { + case syscall.ENOENT: + msg = i18n.G("LXD socket not found; is LXD installed and running?") + case syscall.ECONNREFUSED: + msg = i18n.G("Connection refused; is LXD running?") + case syscall.EACCES: + msg = i18n.G("Permission denied, are you in the lxd group?") + } + + fmt.Fprintln(os.Stderr, fmt.Sprintf("%s", msg)) + os.Exit(1) + } +} + +func run() error { + verbose := gnuflag.Bool("verbose", false, i18n.G("Enables verbose mode.")) + debug := gnuflag.Bool("debug", false, i18n.G("Enables debug mode.")) + forceLocal := gnuflag.Bool("force-local", false, i18n.G("Force using the local unix socket.")) + noAlias := gnuflag.Bool("no-alias", false, i18n.G("Ignore aliases when determining what command to run.")) + + configDir := "$HOME/.config/lxc" + if os.Getenv("LXD_CONF") != "" { + configDir = os.Getenv("LXD_CONF") + } + configPath = os.ExpandEnv(path.Join(configDir, "config.yml")) + + if len(os.Args) >= 3 && os.Args[1] == "config" && os.Args[2] == "profile" { + fmt.Fprintf(os.Stderr, i18n.G("`lxc config profile` is deprecated, please use `lxc profile`")+"\n") + os.Args = append(os.Args[:1], os.Args[2:]...) + } + + if len(os.Args) >= 2 && (os.Args[1] == "-h" || os.Args[1] == "--help") { + os.Args[1] = "help" + } + + if len(os.Args) >= 2 && (os.Args[1] == "--all") { + os.Args[1] = "help" + os.Args = append(os.Args, "--all") + } + + if len(os.Args) == 2 && os.Args[1] == "--version" { + os.Args[1] = "version" + } + + if len(os.Args) < 2 { + commands["help"].run(nil, nil) + os.Exit(1) + } + + var config *lxd.Config + var err error + + if *forceLocal { + config = &lxd.DefaultConfig + } else { + config, err = lxd.LoadConfig(configPath) + if err != nil { + return err + } + } + + // This is quite impolite, but it seems gnuflag needs us to shift our + // own exename out of the arguments before parsing them. However, this + // is useful for execIfAlias, which wants to know exactly the command + // line we received, and in some cases is called before this shift, and + // in others after. So, let's save the original args. + origArgs := os.Args + name := os.Args[1] + + /* at this point we haven't parsed the args, so we have to look for + * --no-alias by hand. + */ + if !shared.StringInSlice("--no-alias", origArgs) { + execIfAliases(config, origArgs) + } + cmd, ok := commands[name] + if !ok { + commands["help"].run(nil, nil) + fmt.Fprintf(os.Stderr, "\n"+i18n.G("error: unknown command: %s")+"\n", name) + os.Exit(1) + } + cmd.flags() + gnuflag.Usage = func() { + fmt.Fprintf(os.Stderr, i18n.G("Usage: %s")+"\n\n"+i18n.G("Options:")+"\n\n", strings.TrimSpace(cmd.usage())) + gnuflag.PrintDefaults() + } + + os.Args = os.Args[1:] + gnuflag.Parse(true) + + shared.Log, err = logging.GetLogger("", "", *verbose, *debug, nil) + if err != nil { + return err + } + + // If the user is running a command that may attempt to connect to the local daemon + // and this is the first time the client has been run by the user, then check to see + // if LXD has been properly configured. Don't display the message if the var path + // does not exist (LXD not installed), as the user may be targeting a remote daemon. + if os.Args[0] != "help" && os.Args[0] != "version" && shared.PathExists(shared.VarPath("")) && !shared.PathExists(config.ConfigDir) { + + // Create the config dir so that we don't get in here again for this user. + err = os.MkdirAll(config.ConfigDir, 0750) + if err != nil { + return err + } + + fmt.Fprintf(os.Stderr, i18n.G("If this is your first time using LXD, you should also run: sudo lxd init")+"\n") + fmt.Fprintf(os.Stderr, i18n.G("To start your first container, try: lxc launch ubuntu:16.04")+"\n\n") + } + + err = cmd.run(config, gnuflag.Args()) + if err == errArgs { + /* If we got an error about invalid arguments, let's try to + * expand this as an alias + */ + if !*noAlias { + execIfAliases(config, origArgs) + } + fmt.Fprintf(os.Stderr, "%s\n\n"+i18n.G("error: %v")+"\n", cmd.usage(), err) + os.Exit(1) + } + return err +} + +type command interface { + usage() string + flags() + showByDefault() bool + run(config *lxd.Config, args []string) error +} + +var commands = map[string]command{ + "config": &configCmd{}, + "copy": ©Cmd{}, + "delete": &deleteCmd{}, + "exec": &execCmd{}, + "file": &fileCmd{}, + "finger": &fingerCmd{}, + "help": &helpCmd{}, + "image": &imageCmd{}, + "info": &infoCmd{}, + "init": &initCmd{}, + "launch": &launchCmd{}, + "list": &listCmd{}, + "monitor": &monitorCmd{}, + "move": &moveCmd{}, + "pause": &actionCmd{ + action: shared.Freeze, + name: "pause", + additionalHelp: i18n.G("The opposite of `lxc pause` is `lxc start`."), + }, + "profile": &profileCmd{}, + "publish": &publishCmd{}, + "remote": &remoteCmd{}, + "restart": &actionCmd{ + action: shared.Restart, + hasTimeout: true, + visible: true, + name: "restart", + timeout: -1, + }, + "restore": &restoreCmd{}, + "snapshot": &snapshotCmd{}, + "start": &actionCmd{ + action: shared.Start, + visible: true, + name: "start", + }, + "stop": &actionCmd{ + action: shared.Stop, + hasTimeout: true, + visible: true, + name: "stop", + timeout: -1, + }, + "version": &versionCmd{}, +} + +// defaultAliases contains LXC's built-in command line aliases. The built-in +// aliases are checked only if no user-defined alias was found. +var defaultAliases = map[string]string{ + "shell": "exec @ARGS@ -- login -f root", + + "cp": "copy", + "ls": "list", + "mv": "move", + "rm": "delete", + + "image cp": "image copy", + "image ls": "image list", + "image rm": "image delete", + + "image alias ls": "image alias list", + "image alias rm": "image alias delete", + + "remote ls": "remote list", + "remote mv": "remote rename", + "remote rm": "remote remove", + + "config device ls": "config device list", + "config device rm": "config device remove", +} + +var errArgs = fmt.Errorf(i18n.G("wrong number of subcommand arguments")) + +func findAlias(aliases map[string]string, origArgs []string) ([]string, []string, bool) { + foundAlias := false + aliasKey := []string{} + aliasValue := []string{} + + for k, v := range aliases { + foundAlias = true + for i, key := range strings.Split(k, " ") { + if len(origArgs) <= i+1 || origArgs[i+1] != key { + foundAlias = false + break + } + } + + if foundAlias { + aliasKey = strings.Split(k, " ") + aliasValue = strings.Split(v, " ") + break + } + } + + return aliasKey, aliasValue, foundAlias +} + +func expandAlias(config *lxd.Config, origArgs []string) ([]string, bool) { + aliasKey, aliasValue, foundAlias := findAlias(config.Aliases, origArgs) + if !foundAlias { + aliasKey, aliasValue, foundAlias = findAlias(defaultAliases, origArgs) + if !foundAlias { + return []string{}, false + } + } + + newArgs := []string{origArgs[0]} + hasReplacedArgsVar := false + + for i, aliasArg := range aliasValue { + if aliasArg == "@ARGS@" && len(origArgs) > i { + newArgs = append(newArgs, origArgs[i+1:]...) + hasReplacedArgsVar = true + } else { + newArgs = append(newArgs, aliasArg) + } + } + + if !hasReplacedArgsVar { + /* add the rest of the arguments */ + newArgs = append(newArgs, origArgs[len(aliasKey)+1:]...) + } + + /* don't re-do aliases the next time; this allows us to have recursive + * aliases, e.g. `lxc list` to `lxc list -c n` + */ + newArgs = append(newArgs[:2], append([]string{"--no-alias"}, newArgs[2:]...)...) + + return newArgs, true +} + +func execIfAliases(config *lxd.Config, origArgs []string) { + newArgs, expanded := expandAlias(config, origArgs) + if !expanded { + return + } + + path, err := exec.LookPath(origArgs[0]) + if err != nil { + fmt.Fprintf(os.Stderr, i18n.G("processing aliases failed %s\n"), err) + os.Exit(5) + } + ret := syscall.Exec(path, newArgs, syscall.Environ()) + fmt.Fprintf(os.Stderr, i18n.G("processing aliases failed %s\n"), ret) + os.Exit(5) +} diff --git a/lxc/.#main.go b/lxc/.#main.go new file mode 120000 index 0000000..4abc121 --- /dev/null +++ b/lxc/.#main.go @@ -0,0 +1 @@ +cnb@f24vm1.2369:1472136537 \ No newline at end of file diff --git a/lxc/help.go b/lxc/help.go index 678e218..235c71d 100644 --- a/lxc/help.go +++ b/lxc/help.go @@ -39,7 +39,7 @@ func (c *helpCmd) run(_ *lxd.Config, args []string) error { if !ok { fmt.Fprintf(os.Stderr, i18n.G("error: unknown command: %s")+"\n", name) } else { - fmt.Fprintf(os.Stderr, cmd.usage()+"\n") + fmt.Fprintf(os.StdOut, cmd.usage()+"\n") } } return nil From ffc5075187c2a133063b81fb0f5c4cd2e1748ad7 Mon Sep 17 00:00:00 2001 From: Carlos <cneirabus...@gmail.com> Date: Thu, 25 Aug 2016 16:04:35 -0300 Subject: [PATCH 2/8] change lxc config --help to stdout --- lxc/help.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxc/help.go b/lxc/help.go index 678e218..235c71d 100644 --- a/lxc/help.go +++ b/lxc/help.go @@ -39,7 +39,7 @@ func (c *helpCmd) run(_ *lxd.Config, args []string) error { if !ok { fmt.Fprintf(os.Stderr, i18n.G("error: unknown command: %s")+"\n", name) } else { - fmt.Fprintf(os.Stderr, cmd.usage()+"\n") + fmt.Fprintf(os.StdOut, cmd.usage()+"\n") } } return nil From cde4bfc444c8e56c349e7bfdadfc96ec7ed91146 Mon Sep 17 00:00:00 2001 From: Carlos <cneirabus...@gmail.com> Date: Thu, 25 Aug 2016 17:27:35 -0300 Subject: [PATCH 3/8] :q Signed-off-by: Carlos <cneirabus...@gmail.com> --- lxc/help.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxc/help.go b/lxc/help.go index 235c71d..dd1b199 100644 --- a/lxc/help.go +++ b/lxc/help.go @@ -39,7 +39,7 @@ func (c *helpCmd) run(_ *lxd.Config, args []string) error { if !ok { fmt.Fprintf(os.Stderr, i18n.G("error: unknown command: %s")+"\n", name) } else { - fmt.Fprintf(os.StdOut, cmd.usage()+"\n") + fmt.Fprintf( os.Stdout, cmd.usage()+"\n") } } return nil From a7030a0b9d7f40f1d8ad75f6372b4103be9a3bca Mon Sep 17 00:00:00 2001 From: Carlos <cneirabus...@gmail.com> Date: Thu, 25 Aug 2016 18:14:38 -0300 Subject: [PATCH 4/8] lxc help change stderr to stdout Signed-off-by: Carlos <cneirabus...@gmail.com> --- lxc/#main.go# | 303 ---------------------------------------------------------- lxc/.#main.go | 1 - 2 files changed, 304 deletions(-) delete mode 100644 lxc/#main.go# delete mode 120000 lxc/.#main.go diff --git a/lxc/#main.go# b/lxc/#main.go# deleted file mode 100644 index 6b9a26c..0000000 --- a/lxc/#main.go# +++ /dev/null @@ -1,303 +0,0 @@ -package main - -import ( - "fmt" - "os" - "os/exec" - "path" - "strings" - "syscall" - - "github.com/lxc/lxd" - "github.com/lxc/lxd/shared" - "github.com/lxc/lxd/shared/gnuflag" - "github.com/lxc/lxd/shared/i18n" - "github.com/lxc/lxd/shared/logging" -) - -var configPath string - -func main() { - if err := run(); err != nil { - msg := fmt.Sprintf(i18n.G("error: %v"), err) - - lxdErr := lxd.GetLocalLXDErr(err) - switch lxdErr { - case syscall.ENOENT: - msg = i18n.G("LXD socket not found; is LXD installed and running?") - case syscall.ECONNREFUSED: - msg = i18n.G("Connection refused; is LXD running?") - case syscall.EACCES: - msg = i18n.G("Permission denied, are you in the lxd group?") - } - - fmt.Fprintln(os.Stderr, fmt.Sprintf("%s", msg)) - os.Exit(1) - } -} - -func run() error { - verbose := gnuflag.Bool("verbose", false, i18n.G("Enables verbose mode.")) - debug := gnuflag.Bool("debug", false, i18n.G("Enables debug mode.")) - forceLocal := gnuflag.Bool("force-local", false, i18n.G("Force using the local unix socket.")) - noAlias := gnuflag.Bool("no-alias", false, i18n.G("Ignore aliases when determining what command to run.")) - - configDir := "$HOME/.config/lxc" - if os.Getenv("LXD_CONF") != "" { - configDir = os.Getenv("LXD_CONF") - } - configPath = os.ExpandEnv(path.Join(configDir, "config.yml")) - - if len(os.Args) >= 3 && os.Args[1] == "config" && os.Args[2] == "profile" { - fmt.Fprintf(os.Stderr, i18n.G("`lxc config profile` is deprecated, please use `lxc profile`")+"\n") - os.Args = append(os.Args[:1], os.Args[2:]...) - } - - if len(os.Args) >= 2 && (os.Args[1] == "-h" || os.Args[1] == "--help") { - os.Args[1] = "help" - } - - if len(os.Args) >= 2 && (os.Args[1] == "--all") { - os.Args[1] = "help" - os.Args = append(os.Args, "--all") - } - - if len(os.Args) == 2 && os.Args[1] == "--version" { - os.Args[1] = "version" - } - - if len(os.Args) < 2 { - commands["help"].run(nil, nil) - os.Exit(1) - } - - var config *lxd.Config - var err error - - if *forceLocal { - config = &lxd.DefaultConfig - } else { - config, err = lxd.LoadConfig(configPath) - if err != nil { - return err - } - } - - // This is quite impolite, but it seems gnuflag needs us to shift our - // own exename out of the arguments before parsing them. However, this - // is useful for execIfAlias, which wants to know exactly the command - // line we received, and in some cases is called before this shift, and - // in others after. So, let's save the original args. - origArgs := os.Args - name := os.Args[1] - - /* at this point we haven't parsed the args, so we have to look for - * --no-alias by hand. - */ - if !shared.StringInSlice("--no-alias", origArgs) { - execIfAliases(config, origArgs) - } - cmd, ok := commands[name] - if !ok { - commands["help"].run(nil, nil) - fmt.Fprintf(os.Stderr, "\n"+i18n.G("error: unknown command: %s")+"\n", name) - os.Exit(1) - } - cmd.flags() - gnuflag.Usage = func() { - fmt.Fprintf(os.Stderr, i18n.G("Usage: %s")+"\n\n"+i18n.G("Options:")+"\n\n", strings.TrimSpace(cmd.usage())) - gnuflag.PrintDefaults() - } - - os.Args = os.Args[1:] - gnuflag.Parse(true) - - shared.Log, err = logging.GetLogger("", "", *verbose, *debug, nil) - if err != nil { - return err - } - - // If the user is running a command that may attempt to connect to the local daemon - // and this is the first time the client has been run by the user, then check to see - // if LXD has been properly configured. Don't display the message if the var path - // does not exist (LXD not installed), as the user may be targeting a remote daemon. - if os.Args[0] != "help" && os.Args[0] != "version" && shared.PathExists(shared.VarPath("")) && !shared.PathExists(config.ConfigDir) { - - // Create the config dir so that we don't get in here again for this user. - err = os.MkdirAll(config.ConfigDir, 0750) - if err != nil { - return err - } - - fmt.Fprintf(os.Stderr, i18n.G("If this is your first time using LXD, you should also run: sudo lxd init")+"\n") - fmt.Fprintf(os.Stderr, i18n.G("To start your first container, try: lxc launch ubuntu:16.04")+"\n\n") - } - - err = cmd.run(config, gnuflag.Args()) - if err == errArgs { - /* If we got an error about invalid arguments, let's try to - * expand this as an alias - */ - if !*noAlias { - execIfAliases(config, origArgs) - } - fmt.Fprintf(os.Stderr, "%s\n\n"+i18n.G("error: %v")+"\n", cmd.usage(), err) - os.Exit(1) - } - return err -} - -type command interface { - usage() string - flags() - showByDefault() bool - run(config *lxd.Config, args []string) error -} - -var commands = map[string]command{ - "config": &configCmd{}, - "copy": ©Cmd{}, - "delete": &deleteCmd{}, - "exec": &execCmd{}, - "file": &fileCmd{}, - "finger": &fingerCmd{}, - "help": &helpCmd{}, - "image": &imageCmd{}, - "info": &infoCmd{}, - "init": &initCmd{}, - "launch": &launchCmd{}, - "list": &listCmd{}, - "monitor": &monitorCmd{}, - "move": &moveCmd{}, - "pause": &actionCmd{ - action: shared.Freeze, - name: "pause", - additionalHelp: i18n.G("The opposite of `lxc pause` is `lxc start`."), - }, - "profile": &profileCmd{}, - "publish": &publishCmd{}, - "remote": &remoteCmd{}, - "restart": &actionCmd{ - action: shared.Restart, - hasTimeout: true, - visible: true, - name: "restart", - timeout: -1, - }, - "restore": &restoreCmd{}, - "snapshot": &snapshotCmd{}, - "start": &actionCmd{ - action: shared.Start, - visible: true, - name: "start", - }, - "stop": &actionCmd{ - action: shared.Stop, - hasTimeout: true, - visible: true, - name: "stop", - timeout: -1, - }, - "version": &versionCmd{}, -} - -// defaultAliases contains LXC's built-in command line aliases. The built-in -// aliases are checked only if no user-defined alias was found. -var defaultAliases = map[string]string{ - "shell": "exec @ARGS@ -- login -f root", - - "cp": "copy", - "ls": "list", - "mv": "move", - "rm": "delete", - - "image cp": "image copy", - "image ls": "image list", - "image rm": "image delete", - - "image alias ls": "image alias list", - "image alias rm": "image alias delete", - - "remote ls": "remote list", - "remote mv": "remote rename", - "remote rm": "remote remove", - - "config device ls": "config device list", - "config device rm": "config device remove", -} - -var errArgs = fmt.Errorf(i18n.G("wrong number of subcommand arguments")) - -func findAlias(aliases map[string]string, origArgs []string) ([]string, []string, bool) { - foundAlias := false - aliasKey := []string{} - aliasValue := []string{} - - for k, v := range aliases { - foundAlias = true - for i, key := range strings.Split(k, " ") { - if len(origArgs) <= i+1 || origArgs[i+1] != key { - foundAlias = false - break - } - } - - if foundAlias { - aliasKey = strings.Split(k, " ") - aliasValue = strings.Split(v, " ") - break - } - } - - return aliasKey, aliasValue, foundAlias -} - -func expandAlias(config *lxd.Config, origArgs []string) ([]string, bool) { - aliasKey, aliasValue, foundAlias := findAlias(config.Aliases, origArgs) - if !foundAlias { - aliasKey, aliasValue, foundAlias = findAlias(defaultAliases, origArgs) - if !foundAlias { - return []string{}, false - } - } - - newArgs := []string{origArgs[0]} - hasReplacedArgsVar := false - - for i, aliasArg := range aliasValue { - if aliasArg == "@ARGS@" && len(origArgs) > i { - newArgs = append(newArgs, origArgs[i+1:]...) - hasReplacedArgsVar = true - } else { - newArgs = append(newArgs, aliasArg) - } - } - - if !hasReplacedArgsVar { - /* add the rest of the arguments */ - newArgs = append(newArgs, origArgs[len(aliasKey)+1:]...) - } - - /* don't re-do aliases the next time; this allows us to have recursive - * aliases, e.g. `lxc list` to `lxc list -c n` - */ - newArgs = append(newArgs[:2], append([]string{"--no-alias"}, newArgs[2:]...)...) - - return newArgs, true -} - -func execIfAliases(config *lxd.Config, origArgs []string) { - newArgs, expanded := expandAlias(config, origArgs) - if !expanded { - return - } - - path, err := exec.LookPath(origArgs[0]) - if err != nil { - fmt.Fprintf(os.Stderr, i18n.G("processing aliases failed %s\n"), err) - os.Exit(5) - } - ret := syscall.Exec(path, newArgs, syscall.Environ()) - fmt.Fprintf(os.Stderr, i18n.G("processing aliases failed %s\n"), ret) - os.Exit(5) -} diff --git a/lxc/.#main.go b/lxc/.#main.go deleted file mode 120000 index 4abc121..0000000 --- a/lxc/.#main.go +++ /dev/null @@ -1 +0,0 @@ -cnb@f24vm1.2369:1472136537 \ No newline at end of file From 1d2a30a50fcf9685b8580c9a48216c2b221f4849 Mon Sep 17 00:00:00 2001 From: Carlos Neira <cneirabus...@gmail.com> Date: Fri, 26 Aug 2016 18:50:11 -0300 Subject: [PATCH 5/8] lxc help change stderr to stdout Signed-off-by: Carlos <cneirabus...@gmail.com> --- lxc/help.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxc/help.go b/lxc/help.go index dd1b199..b01732a 100644 --- a/lxc/help.go +++ b/lxc/help.go @@ -39,7 +39,7 @@ func (c *helpCmd) run(_ *lxd.Config, args []string) error { if !ok { fmt.Fprintf(os.Stderr, i18n.G("error: unknown command: %s")+"\n", name) } else { - fmt.Fprintf( os.Stdout, cmd.usage()+"\n") + fmt.Fprintf(os.Stdout, cmd.usage()+"\n") } } return nil From cb8c7cde9c11090b68d8da2a184897a225841203 Mon Sep 17 00:00:00 2001 From: Carlos Neira <cneirabus...@gmail.com> Date: Tue, 30 Aug 2016 13:05:53 -0300 Subject: [PATCH 6/8] lxc add manpage option, that just prints all help subcommands Signed-off-by: Carlos Neira <cneirabus...@gmail.com> --- lxc/help.go | 1 + lxc/main.go | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lxc/help.go b/lxc/help.go index b01732a..4514777 100644 --- a/lxc/help.go +++ b/lxc/help.go @@ -65,6 +65,7 @@ func (c *helpCmd) run(_ *lxd.Config, args []string) error { fmt.Println(" --debug " + i18n.G("Print debug information.")) fmt.Println(" --verbose " + i18n.G("Print verbose information.")) fmt.Println(" --version " + i18n.G("Show client version.")) + fmt.Println(" --manpage " + i18n.G("Show lxc manpage.")) fmt.Println() fmt.Println(i18n.G("Environment:")) fmt.Println(" LXD_CONF " + i18n.G("Path to an alternate client configuration directory.")) diff --git a/lxc/main.go b/lxc/main.go index 6b9a26c..cb31b29 100644 --- a/lxc/main.go +++ b/lxc/main.go @@ -65,7 +65,9 @@ func run() error { if len(os.Args) == 2 && os.Args[1] == "--version" { os.Args[1] = "version" } - + if len(os.Args) == 2 && os.Args[1] == "--manpage" { + os.Args[1] = "manpage" + } if len(os.Args) < 2 { commands["help"].run(nil, nil) os.Exit(1) @@ -199,6 +201,7 @@ var commands = map[string]command{ timeout: -1, }, "version": &versionCmd{}, + "manpage": &manpageCmd{}, } // defaultAliases contains LXC's built-in command line aliases. The built-in From 243d867c089d4c3c4f461839e9636fb458af89a8 Mon Sep 17 00:00:00 2001 From: Carlos Neira <cneirabus...@gmail.com> Date: Tue, 30 Aug 2016 13:11:11 -0300 Subject: [PATCH 7/8] lxc add manpage option, that just prints all help subcommands Signed-off-by: Carlos Neira <cneirabus...@gmail.com> --- lxc/manpage.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 lxc/manpage.go diff --git a/lxc/manpage.go b/lxc/manpage.go new file mode 100644 index 0000000..3b2de27 --- /dev/null +++ b/lxc/manpage.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "github.com/lxc/lxd" + "github.com/lxc/lxd/shared" + "github.com/lxc/lxd/shared/i18n" +) + +type manpageCmd struct{} + +func (c *manpageCmd) showByDefault() bool { + return false +} + +func (c *manpageCmd) usage() string { + return i18n.G( + `Prints all subcommands help to create a lxd manpage`) +} + +func (c *manpageCmd) flags() { +} + +func (c *manpageCmd) run(_ *lxd.Config, args []string) error { + if len(args) > 0 { + return errArgs + } + for k, _ := range commands { + commands["help"].run(nil, []string{k}) + } + fmt.Println(shared.Version) + return nil +} From 5136b362521417f5b8c5e56374de56ccb8042d44 Mon Sep 17 00:00:00 2001 From: Carlos Neira <cneirabus...@gmail.com> Date: Tue, 30 Aug 2016 13:16:30 -0300 Subject: [PATCH 8/8] generate manpage issue #2280 Make it possible to generate a complete manpage of the lxc command #2280 --- lxc/manpage.go | 1 - 1 file changed, 1 deletion(-) diff --git a/lxc/manpage.go b/lxc/manpage.go index 3b2de27..a9ed72a 100644 --- a/lxc/manpage.go +++ b/lxc/manpage.go @@ -28,6 +28,5 @@ func (c *manpageCmd) run(_ *lxd.Config, args []string) error { for k, _ := range commands { commands["help"].run(nil, []string{k}) } - fmt.Println(shared.Version) return nil }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel