@marcel91200 / caddy Mirror · read-only
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 10, 23:45 UTC

master
go 177 lines 5.22 KB
Raw
1 package caddycmd
2
3 import (
4 "fmt"
5
6 "github.com/spf13/cobra"
7
8 "github.com/caddyserver/caddy/v2"
9 )
10
11 var defaultFactory = newRootCommandFactory(func() *cobra.Command {
12 bin := caddy.CustomBinaryName
13 if bin == "" {
14 bin = "caddy"
15 }
16
17 long := caddy.CustomLongDescription
18 if long == "" {
19 long = `Caddy is an extensible server platform written in Go.
20
21 At its core, Caddy merely manages configuration. Modules are plugged
22 in statically at compile-time to provide useful functionality. Caddy's
23 standard distribution includes common modules to serve HTTP, TLS,
24 and PKI applications, including the automation of certificates.
25
26 To run Caddy, use:
27
28 - 'caddy run' to run Caddy in the foreground (recommended).
29 - 'caddy start' to start Caddy in the background; only do this
30 if you will be keeping the terminal window open until you run
31 'caddy stop' to close the server.
32
33 When Caddy is started, it opens a locally-bound administrative socket
34 to which configuration can be POSTed via a restful HTTP API (see
35 https://caddyserver.com/docs/api).
36
37 Caddy's native configuration format is JSON. However, config adapters
38 can be used to convert other config formats to JSON when Caddy receives
39 its configuration. The Caddyfile is a built-in config adapter that is
40 popular for hand-written configurations due to its straightforward
41 syntax (see https://caddyserver.com/docs/caddyfile). Many third-party
42 adapters are available (see https://caddyserver.com/docs/config-adapters).
43 Use 'caddy adapt' to see how a config translates to JSON.
44
45 For convenience, the CLI can act as an HTTP client to give Caddy its
46 initial configuration for you. If a file named Caddyfile is in the
47 current working directory, it will do this automatically. Otherwise,
48 you can use the --config flag to specify the path to a config file.
49
50 Some special-purpose subcommands build and load a configuration file
51 for you directly from command line input; for example:
52
53 - caddy file-server
54 - caddy reverse-proxy
55 - caddy respond
56
57 These commands disable the administration endpoint because their
58 configuration is specified solely on the command line.
59
60 In general, the most common way to run Caddy is simply:
61
62 $ caddy run
63
64 Or, with a configuration file:
65
66 $ caddy run --config caddy.json
67
68 If running interactively in a terminal, running Caddy in the
69 background may be more convenient:
70
71 $ caddy start
72 ...
73 $ caddy stop
74
75 This allows you to run other commands while Caddy stays running.
76 Be sure to stop Caddy before you close the terminal!
77
78 Depending on the system, Caddy may need permission to bind to low
79 ports. One way to do this on Linux is to use setcap:
80
81 $ sudo setcap cap_net_bind_service=+ep $(which caddy)
82
83 Remember to run that command again after replacing the binary.
84
85 See the Caddy website for tutorials, configuration structure,
86 syntax, and module documentation: https://caddyserver.com/docs/
87
88 Custom Caddy builds are available on the Caddy download page at:
89 https://caddyserver.com/download
90
91 The xcaddy command can be used to build Caddy from source with or
92 without additional plugins: https://github.com/caddyserver/xcaddy
93
94 Where possible, Caddy should be installed using officially-supported
95 package installers: https://caddyserver.com/docs/install
96
97 Instructions for running Caddy in production are also available:
98 https://caddyserver.com/docs/running
99 `
100 }
101
102 return &cobra.Command{
103 Use: bin,
104 Long: long,
105 Example: ` $ caddy run
106 $ caddy run --config caddy.json
107 $ caddy reload --config caddy.json
108 $ caddy stop`,
109
110 // kind of annoying to have all the help text printed out if
111 // caddy has an error provisioning its modules, for instance...
112 SilenceUsage: true,
113 Version: onlyVersionText(),
114 }
115 })
116
117 const fullDocsFooter = `Full documentation is available at:
118 https://caddyserver.com/docs/command-line`
119
120 func init() {
121 defaultFactory.Use(func(rootCmd *cobra.Command) {
122 rootCmd.SetVersionTemplate("{{.Version}}\n")
123 rootCmd.SetHelpTemplate(rootCmd.HelpTemplate() + "\n" + fullDocsFooter + "\n")
124 })
125 }
126
127 func onlyVersionText() string {
128 _, f := caddy.Version()
129 return f
130 }
131
132 func caddyCmdToCobra(caddyCmd Command) *cobra.Command {
133 cmd := &cobra.Command{
134 Use: caddyCmd.Name + " " + caddyCmd.Usage,
135 Short: caddyCmd.Short,
136 Long: caddyCmd.Long,
137 }
138 if caddyCmd.CobraFunc != nil {
139 caddyCmd.CobraFunc(cmd)
140 } else {
141 cmd.RunE = WrapCommandFuncForCobra(caddyCmd.Func)
142 cmd.Flags().AddGoFlagSet(caddyCmd.Flags)
143 }
144 return cmd
145 }
146
147 // WrapCommandFuncForCobra wraps a Caddy CommandFunc for use
148 // in a cobra command's RunE field.
149 func WrapCommandFuncForCobra(f CommandFunc) func(cmd *cobra.Command, _ []string) error {
150 return func(cmd *cobra.Command, _ []string) error {
151 status, err := f(Flags{cmd.Flags()})
152 if err != nil {
153 // Route the error through Caddy's logger so it receives the same
154 // colored, structured formatting as INFO/WARN output, rather than
155 // cobra's plain "Error: ..." line which lacks any highlighting.
156 caddy.Log().Error(err.Error())
157 cmd.SilenceErrors = true
158 }
159 if status > 1 {
160 return &exitError{ExitCode: status, Err: err}
161 }
162 return err
163 }
164 }
165
166 // exitError carries the exit code from CommandFunc to Main()
167 type exitError struct {
168 ExitCode int
169 Err error
170 }
171
172 func (e *exitError) Error() string {
173 if e.Err == nil {
174 return fmt.Sprintf("exiting with status %d", e.ExitCode)
175 }
176 return e.Err.Error()
177 }