1
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
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
59
60 os.Setenv("HOME", "/home/username")
61
62 switch module {
63 case "kube-apiserver":
64
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
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
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
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
93 kubelet := kubeletapp.NewKubeletCommand()
94 genMarkdown(kubelet, "", outDir)
95 for _, c := range kubelet.Commands() {
96 genMarkdown(c, "kubelet", outDir)
97 }
98 case "kubectl":
99
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
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
136 format = "**--%s**=%q\n\t%s\n\n"
137 }
138
139
140
141
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