diff --git a/cmd/genman/gen_kubectl_man.go b/cmd/genman/gen_kubectl_man.go new file mode 100644 index 00000000000..53391429edb --- /dev/null +++ b/cmd/genman/gen_kubectl_man.go @@ -0,0 +1,177 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd" + "github.com/cpuguy83/go-md2man/mangen" + "github.com/russross/blackfriday" + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +func main() { + // use os.Args instead of "flags" because "flags" will mess up the man pages! + docsDir := "docs/man/man1/" + if len(os.Args) == 2 { + docsDir = os.Args[1] + } else if len(os.Args) > 2 { + fmt.Fprintf(os.Stderr, "usage: %s [output directory]\n", os.Args[0]) + os.Exit(1) + } + + docsDir, err := filepath.Abs(docsDir) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + stat, err := os.Stat(docsDir) + if err != nil { + fmt.Fprintf(os.Stderr, "output directory %s does not exist\n", docsDir) + os.Exit(1) + } + + if !stat.IsDir() { + fmt.Fprintf(os.Stderr, "output directory %s is not a directory\n", docsDir) + os.Exit(1) + } + docsDir = docsDir + "/" + + // Set environment variables used by kubectl so the output is consistent, + // regardless of where we run. + os.Setenv("HOME", "/home/username") + kubectl := cmd.NewFactory(nil).NewKubectlCommand(ioutil.Discard) + genMarkdown(kubectl, "", docsDir) + for _, c := range kubectl.Commands() { + genMarkdown(c, "kubectl", docsDir) + } +} + +func preamble(out *bytes.Buffer, name, short, long string) { + out.WriteString(`% KUBERNETES(1) kubernetes User Manuals +% Eric Paris +% Jan 2015 +# NAME +`) + fmt.Fprintf(out, "%s \\- %s\n\n", name, short) + fmt.Fprintf(out, "# SYNOPSIS\n") + fmt.Fprintf(out, "**%s** [OPTIONS]\n\n", name) + fmt.Fprintf(out, "# DESCRIPTION\n") + fmt.Fprintf(out, "%s\n\n", long) +} + +func printFlags(out *bytes.Buffer, flags *pflag.FlagSet) { + flags.VisitAll(func(flag *pflag.Flag) { + format := "**--%s**=%s\n\t%s\n\n" + if flag.Value.Type() == "string" { + // put quotes on the value + format = "**--%s**=%q\n\t%s\n\n" + } + if len(flag.Shorthand) > 0 { + format = "**-%s**, " + format + } else { + format = "%s" + format + } + fmt.Fprintf(out, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage) + }) +} + +func printOptions(out *bytes.Buffer, command *cobra.Command) { + var flags *pflag.FlagSet + if command.HasFlags() { + flags = command.Flags() + } else if !command.HasParent() && command.HasPersistentFlags() { + flags = command.PersistentFlags() + } + if flags == nil { + return + } + fmt.Fprintf(out, "# OPTIONS\n") + printFlags(out, flags) + fmt.Fprintf(out, "\n") +} + +func genMarkdown(command *cobra.Command, parent, docsDir string) { + dparent := strings.Replace(parent, " ", "-", -1) + name := command.Name() + dname := name + if len(parent) > 0 { + dname = dparent + "-" + name + name = parent + " " + name + } + + out := new(bytes.Buffer) + short := command.Short + long := command.Long + if len(long) == 0 { + long = short + } + + preamble(out, name, short, long) + printOptions(out, command) + + if len(command.Commands()) > 0 || len(parent) > 0 { + fmt.Fprintf(out, "# SEE ALSO\n") + if len(parent) > 0 { + fmt.Fprintf(out, "**%s(1)**, ", dparent) + } + for _, c := range command.Commands() { + fmt.Fprintf(out, "**%s-%s(1)**, ", dname, c.Name()) + genMarkdown(c, name, docsDir) + } + fmt.Fprintf(out, "\n") + } + + out.WriteString(` +# HISTORY +January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! +`) + + renderer := mangen.ManRenderer(0) + extensions := 0 + extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS + extensions |= blackfriday.EXTENSION_TABLES + extensions |= blackfriday.EXTENSION_FENCED_CODE + extensions |= blackfriday.EXTENSION_AUTOLINK + extensions |= blackfriday.EXTENSION_SPACE_HEADERS + extensions |= blackfriday.EXTENSION_FOOTNOTES + extensions |= blackfriday.EXTENSION_TITLEBLOCK + + final := blackfriday.Markdown(out.Bytes(), renderer, extensions) + + filename := docsDir + dname + ".1" + outFile, err := os.Create(filename) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer outFile.Close() + _, err = outFile.Write(final) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + +} diff --git a/docs/kubectl.md b/docs/kubectl.md index 2be2c5a3707..699578576ac 100644 --- a/docs/kubectl.md +++ b/docs/kubectl.md @@ -11,14 +11,12 @@ Usage: ``` kubectl version [flags] -Flags: - -c, --client=false: Client version only (no server required). - -Global Flags: + Available Flags: --alsologtostderr=false: log to standard error as well as files --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. --certificate-authority="": Path to a cert. file for the certificate authority. + -c, --client=false: Client version only (no server required). --client-certificate="": Path to a client key file for TLS. --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use @@ -49,14 +47,9 @@ Usage: ``` kubectl proxy [flags] -Flags: - --api-prefix="/api/": Prefix to serve the proxied API under. - -p, --port=8001: The port on which to run the proxy. - -w, --www="": Also serve static files from the given directory under the specified prefix. - -P, --www-prefix="/static/": Prefix to serve static files under, if static file directory is specified. - -Global Flags: + Available Flags: --alsologtostderr=false: log to standard error as well as files + --api-prefix="/api/": Prefix to serve the proxied API under. --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. --certificate-authority="": Path to a cert. file for the certificate authority. @@ -73,6 +66,7 @@ Global Flags: --logtostderr=true: log to standard error instead of files --match-server-version=false: Require server version to match client version --namespace="": If present, the namespace scope for this CLI request. + -p, --port=8001: The port on which to run the proxy. -s, --server="": The address and port of the Kubernetes API server --stderrthreshold=2: logs at or above this threshold go to stderr --token="": Bearer token for authentication to the API server. @@ -80,6 +74,8 @@ Global Flags: --v=0: log level for V logs --validate=false: If true, use a schema to validate the input before sending it --vmodule=: comma-separated list of pattern=N settings for file-filtered logging + -w, --www="": Also serve static files from the given directory under the specified prefix. + -P, --www-prefix="/static/": Prefix to serve static files under, if static file directory is specified. ``` @@ -113,16 +109,7 @@ Usage: ``` kubectl get [(-o|--output=)json|yaml|template|...] [] [flags] -Flags: - --no-headers=false: When using the default output, don't print headers. - -o, --output="": Output format. One of: json|yaml|template|templatefile. - --output-version="": Output the formatted object with the given version (default api-version). - -l, --selector="": Selector (label query) to filter on - -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. - -w, --watch=false: After listing/getting the requested object, watch for changes. - --watch-only=false: Watch for changes to the requested object(s), without listing/getting first. - -Global Flags: + Available Flags: --alsologtostderr=false: log to standard error as well as files --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. @@ -140,13 +127,20 @@ Global Flags: --logtostderr=true: log to standard error instead of files --match-server-version=false: Require server version to match client version --namespace="": If present, the namespace scope for this CLI request. + --no-headers=false: When using the default output, don't print headers. + -o, --output="": Output format. One of: json|yaml|template|templatefile. + --output-version="": Output the formatted object with the given version (default api-version). + -l, --selector="": Selector (label query) to filter on -s, --server="": The address and port of the Kubernetes API server --stderrthreshold=2: logs at or above this threshold go to stderr + -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. --token="": Bearer token for authentication to the API server. --user="": The name of the kubeconfig user to use --v=0: log level for V logs --validate=false: If true, use a schema to validate the input before sending it --vmodule=: comma-separated list of pattern=N settings for file-filtered logging + -w, --watch=false: After listing/getting the requested object, watch for changes. + --watch-only=false: Watch for changes to the requested object(s), without listing/getting first. ``` @@ -160,8 +154,7 @@ Usage: ``` kubectl describe [flags] - -Global Flags: + Available Flags: --alsologtostderr=false: log to standard error as well as files --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. @@ -170,7 +163,6 @@ Global Flags: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use - -h, --help=false: help for describe --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": Path to the kubeconfig file to use for CLI requests. --log_backtrace_at=:0: when logging hits line file:N, emit a stack trace @@ -206,10 +198,7 @@ Usage: ``` kubectl create -f filename [flags] -Flags: - -f, --filename=[]: Filename, directory, or URL to file to use to create the resource - -Global Flags: + Available Flags: --alsologtostderr=false: log to standard error as well as files --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. @@ -218,6 +207,7 @@ Global Flags: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use + -f, --filename=[]: Filename, directory, or URL to file to use to create the resource -h, --help=false: help for create --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": Path to the kubeconfig file to use for CLI requests. @@ -257,11 +247,7 @@ Usage: ``` kubectl update -f filename [flags] -Flags: - -f, --filename=[]: Filename, directory, or URL to file to use to update the resource. - --patch="": A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated. - -Global Flags: + Available Flags: --alsologtostderr=false: log to standard error as well as files --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. @@ -270,6 +256,7 @@ Global Flags: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use + -f, --filename=[]: Filename, directory, or URL to file to use to update the resource. -h, --help=false: help for update --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": Path to the kubeconfig file to use for CLI requests. @@ -279,6 +266,7 @@ Global Flags: --logtostderr=true: log to standard error instead of files --match-server-version=false: Require server version to match client version --namespace="": If present, the namespace scope for this CLI request. + --patch="": A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated. -s, --server="": The address and port of the Kubernetes API server --stderrthreshold=2: logs at or above this threshold go to stderr --token="": Bearer token for authentication to the API server. @@ -319,11 +307,7 @@ Usage: ``` kubectl delete ([-f filename] | ( [( | -l