...

Source file src/k8s.io/kubernetes/cmd/genman/gen_kube_man.go

Documentation: k8s.io/kubernetes/cmd/genman

     1  /*
     2  Copyright 2014 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io"
    23  	"os"
    24  	"strings"
    25  
    26  	mangen "github.com/cpuguy83/go-md2man/v2/md2man"
    27  	"github.com/spf13/cobra"
    28  	"github.com/spf13/pflag"
    29  	"k8s.io/cli-runtime/pkg/genericiooptions"
    30  	kubectlcmd "k8s.io/kubectl/pkg/cmd"
    31  	"k8s.io/kubernetes/cmd/genutils"
    32  	apiservapp "k8s.io/kubernetes/cmd/kube-apiserver/app"
    33  	cmapp "k8s.io/kubernetes/cmd/kube-controller-manager/app"
    34  	proxyapp "k8s.io/kubernetes/cmd/kube-proxy/app"
    35  	schapp "k8s.io/kubernetes/cmd/kube-scheduler/app"
    36  	kubeadmapp "k8s.io/kubernetes/cmd/kubeadm/app/cmd"
    37  	kubeletapp "k8s.io/kubernetes/cmd/kubelet/app"
    38  )
    39  
    40  func main() {
    41  	// use os.Args instead of "flags" because "flags" will mess up the man pages!
    42  	path := "docs/man/man1"
    43  	module := ""
    44  	if len(os.Args) == 3 {
    45  		path = os.Args[1]
    46  		module = os.Args[2]
    47  	} else {
    48  		fmt.Fprintf(os.Stderr, "usage: %s [output directory] [module] \n", os.Args[0])
    49  		os.Exit(1)
    50  	}
    51  
    52  	outDir, err := genutils.OutDir(path)
    53  	if err != nil {
    54  		fmt.Fprintf(os.Stderr, "failed to get output directory: %v\n", err)
    55  		os.Exit(1)
    56  	}
    57  
    58  	// Set environment variables used by command so the output is consistent,
    59  	// regardless of where we run.
    60  	os.Setenv("HOME", "/home/username")
    61  
    62  	switch module {
    63  	case "kube-apiserver":
    64  		// generate manpage for kube-apiserver
    65  		apiserver := apiservapp.NewAPIServerCommand()
    66  		genMarkdown(apiserver, "", outDir)
    67  		for _, c := range apiserver.Commands() {
    68  			genMarkdown(c, "kube-apiserver", outDir)
    69  		}
    70  	case "kube-controller-manager":
    71  		// generate manpage for kube-controller-manager
    72  		controllermanager := cmapp.NewControllerManagerCommand()
    73  		genMarkdown(controllermanager, "", outDir)
    74  		for _, c := range controllermanager.Commands() {
    75  			genMarkdown(c, "kube-controller-manager", outDir)
    76  		}
    77  	case "kube-proxy":
    78  		// generate manpage for kube-proxy
    79  		proxy := proxyapp.NewProxyCommand()
    80  		genMarkdown(proxy, "", outDir)
    81  		for _, c := range proxy.Commands() {
    82  			genMarkdown(c, "kube-proxy", outDir)
    83  		}
    84  	case "kube-scheduler":
    85  		// generate manpage for kube-scheduler
    86  		scheduler := schapp.NewSchedulerCommand()
    87  		genMarkdown(scheduler, "", outDir)
    88  		for _, c := range scheduler.Commands() {
    89  			genMarkdown(c, "kube-scheduler", outDir)
    90  		}
    91  	case "kubelet":
    92  		// generate manpage for kubelet
    93  		kubelet := kubeletapp.NewKubeletCommand()
    94  		genMarkdown(kubelet, "", outDir)
    95  		for _, c := range kubelet.Commands() {
    96  			genMarkdown(c, "kubelet", outDir)
    97  		}
    98  	case "kubectl":
    99  		// generate manpage for kubectl
   100  		kubectl := kubectlcmd.NewKubectlCommand(kubectlcmd.KubectlOptions{IOStreams: genericiooptions.IOStreams{In: bytes.NewReader(nil), Out: io.Discard, ErrOut: io.Discard}})
   101  		genMarkdown(kubectl, "", outDir)
   102  		for _, c := range kubectl.Commands() {
   103  			genMarkdown(c, "kubectl", outDir)
   104  		}
   105  	case "kubeadm":
   106  		// generate manpage for kubeadm
   107  		kubeadm := kubeadmapp.NewKubeadmCommand(bytes.NewReader(nil), io.Discard, io.Discard)
   108  		genMarkdown(kubeadm, "", outDir)
   109  		for _, c := range kubeadm.Commands() {
   110  			genMarkdown(c, "kubeadm", outDir)
   111  		}
   112  	default:
   113  		fmt.Fprintf(os.Stderr, "Module %s is not supported", module)
   114  		os.Exit(1)
   115  	}
   116  }
   117  
   118  func preamble(out *bytes.Buffer, name, short, long string) {
   119  	out.WriteString(`% KUBERNETES(1) kubernetes User Manuals
   120  % Eric Paris
   121  % Jan 2015
   122  # NAME
   123  `)
   124  	fmt.Fprintf(out, "%s \\- %s\n\n", name, short)
   125  	fmt.Fprintf(out, "# SYNOPSIS\n")
   126  	fmt.Fprintf(out, "**%s** [OPTIONS]\n\n", name)
   127  	fmt.Fprintf(out, "# DESCRIPTION\n")
   128  	fmt.Fprintf(out, "%s\n\n", long)
   129  }
   130  
   131  func printFlags(out *bytes.Buffer, flags *pflag.FlagSet) {
   132  	flags.VisitAll(func(flag *pflag.Flag) {
   133  		format := "**--%s**=%s\n\t%s\n\n"
   134  		if flag.Value.Type() == "string" {
   135  			// put quotes on the value
   136  			format = "**--%s**=%q\n\t%s\n\n"
   137  		}
   138  
   139  		// Todo, when we mark a shorthand is deprecated, but specify an empty message.
   140  		// The flag.ShorthandDeprecated is empty as the shorthand is deprecated.
   141  		// Using len(flag.ShorthandDeprecated) > 0 can't handle this, others are ok.
   142  		if !(len(flag.ShorthandDeprecated) > 0) && len(flag.Shorthand) > 0 {
   143  			format = "**-%s**, " + format
   144  			fmt.Fprintf(out, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
   145  		} else {
   146  			fmt.Fprintf(out, format, flag.Name, flag.DefValue, flag.Usage)
   147  		}
   148  	})
   149  }
   150  
   151  func printOptions(out *bytes.Buffer, command *cobra.Command) {
   152  	flags := command.NonInheritedFlags()
   153  	if flags.HasFlags() {
   154  		fmt.Fprintf(out, "# OPTIONS\n")
   155  		printFlags(out, flags)
   156  		fmt.Fprintf(out, "\n")
   157  	}
   158  	flags = command.InheritedFlags()
   159  	if flags.HasFlags() {
   160  		fmt.Fprintf(out, "# OPTIONS INHERITED FROM PARENT COMMANDS\n")
   161  		printFlags(out, flags)
   162  		fmt.Fprintf(out, "\n")
   163  	}
   164  }
   165  
   166  func genMarkdown(command *cobra.Command, parent, docsDir string) {
   167  	dparent := strings.Replace(parent, " ", "-", -1)
   168  	name := command.Name()
   169  	dname := name
   170  	if len(parent) > 0 {
   171  		dname = dparent + "-" + name
   172  		name = parent + " " + name
   173  	}
   174  
   175  	out := new(bytes.Buffer)
   176  	short := command.Short
   177  	long := command.Long
   178  	if len(long) == 0 {
   179  		long = short
   180  	}
   181  
   182  	preamble(out, name, short, long)
   183  	printOptions(out, command)
   184  
   185  	if len(command.Example) > 0 {
   186  		fmt.Fprintf(out, "# EXAMPLE\n")
   187  		fmt.Fprintf(out, "```\n%s\n```\n", command.Example)
   188  	}
   189  
   190  	if len(command.Commands()) > 0 || len(parent) > 0 {
   191  		fmt.Fprintf(out, "# SEE ALSO\n")
   192  		if len(parent) > 0 {
   193  			fmt.Fprintf(out, "**%s(1)**, ", dparent)
   194  		}
   195  		for _, c := range command.Commands() {
   196  			fmt.Fprintf(out, "**%s-%s(1)**, ", dname, c.Name())
   197  			genMarkdown(c, name, docsDir)
   198  		}
   199  		fmt.Fprintf(out, "\n")
   200  	}
   201  
   202  	out.WriteString(`
   203  # HISTORY
   204  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!
   205  `)
   206  
   207  	final := mangen.Render(out.Bytes())
   208  
   209  	filename := docsDir + dname + ".1"
   210  	outFile, err := os.Create(filename)
   211  	if err != nil {
   212  		fmt.Println(err)
   213  		os.Exit(1)
   214  	}
   215  	defer outFile.Close()
   216  	_, err = outFile.Write(final)
   217  	if err != nil {
   218  		fmt.Println(err)
   219  		os.Exit(1)
   220  	}
   221  
   222  }
   223  

View as plain text