mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 08:23:48 +03:00
add comment about the sconf config file format at the top of the config files
hopefully this helps admins editing the file and prevent mistakes about config files. for issue #56 by kikoreis, thanks!
This commit is contained in:
parent
0d8603f9e1
commit
9534e464f9
8 changed files with 65 additions and 25 deletions
|
@ -34,7 +34,7 @@ func Port(port, fallback int) int {
|
|||
// Static is a parsed form of the mox.conf configuration file, before converting it
|
||||
// into a mox.Config after additional processing.
|
||||
type Static struct {
|
||||
DataDir string `sconf-doc:"Directory where all data is stored, e.g. queue, accounts and messages, ACME TLS certs/keys. If this is a relative path, it is relative to the directory of mox.conf."`
|
||||
DataDir string `sconf-doc:"NOTE: This config file is in 'sconf' format. Indent with tabs. Comments must be on their own line, they don't end a line. Do not escape or quote strings. Details: https://pkg.go.dev/github.com/mjl-/sconf.\n\n\nDirectory where all data is stored, e.g. queue, accounts and messages, ACME TLS certs/keys. If this is a relative path, it is relative to the directory of mox.conf."`
|
||||
LogLevel string `sconf-doc:"Default log level, one of: error, info, debug, trace, traceauth, tracedata. Trace logs SMTP and IMAP protocol transcripts, with traceauth also messages with passwords, and tracedata on top of that also the full data exchanges (full messages), which can be a large amount of data."`
|
||||
PackageLogLevels map[string]string `sconf:"optional" sconf-doc:"Overrides of log level per package (e.g. queue, smtpclient, smtpserver, imapserver, spf, dkim, dmarc, dmarcdb, autotls, junk, mtasts, tlsrpt)."`
|
||||
User string `sconf:"optional" sconf-doc:"User to switch to after binding to all sockets as root. Default: mox. If the value is not a known user, it is parsed as integer and used as uid and gid."`
|
||||
|
@ -94,7 +94,7 @@ type SpecialUseMailboxes struct {
|
|||
|
||||
// Dynamic is the parsed form of domains.conf, and is automatically reloaded when changed.
|
||||
type Dynamic struct {
|
||||
Domains map[string]Domain `sconf-doc:"Domains for which email is accepted. For internationalized domains, use their IDNA names in UTF-8."`
|
||||
Domains map[string]Domain `sconf-doc:"NOTE: This config file is in 'sconf' format. Indent with tabs. Comments must be on their own line, they don't end a line. Do not escape or quote strings. Details: https://pkg.go.dev/github.com/mjl-/sconf.\n\n\nDomains for which email is accepted. For internationalized domains, use their IDNA names in UTF-8."`
|
||||
Accounts map[string]Account `sconf-doc:"Accounts to which email can be delivered. An account can accept email for multiple domains, for multiple localparts, and deliver to multiple mailboxes."`
|
||||
WebDomainRedirects map[string]string `sconf:"optional" sconf-doc:"Redirect all requests from domain (key) to domain (value). Always redirects to HTTPS. For plain HTTP redirects, use a WebHandler with a WebRedirect."`
|
||||
WebHandlers []WebHandler `sconf:"optional" sconf-doc:"Handle webserver requests by serving static files, redirecting or reverse-proxying HTTP(s). The first matching WebHandler will handle the request. Built-in handlers, e.g. for account, admin, autoconfig and mta-sts always run first. If no handler matches, the response status code is file not found (404). If functionality you need is missng, simply forward the requests to an application that can provide the needed functionality."`
|
||||
|
|
|
@ -13,6 +13,11 @@ describe-static" and "mox config describe-domains":
|
|||
|
||||
# mox.conf
|
||||
|
||||
# NOTE: This config file is in 'sconf' format. Indent with tabs. Comments must be
|
||||
# on their own line, they don't end a line. Do not escape or quote strings.
|
||||
# Details: https://pkg.go.dev/github.com/mjl-/sconf.
|
||||
|
||||
|
||||
# Directory where all data is stored, e.g. queue, accounts and messages, ACME TLS
|
||||
# certs/keys. If this is a relative path, it is relative to the directory of
|
||||
# mox.conf.
|
||||
|
@ -526,6 +531,11 @@ describe-static" and "mox config describe-domains":
|
|||
|
||||
# domains.conf
|
||||
|
||||
# NOTE: This config file is in 'sconf' format. Indent with tabs. Comments must be
|
||||
# on their own line, they don't end a line. Do not escape or quote strings.
|
||||
# Details: https://pkg.go.dev/github.com/mjl-/sconf.
|
||||
|
||||
|
||||
# Domains for which email is accepted. For internationalized domains, use their
|
||||
# IDNA names in UTF-8.
|
||||
Domains:
|
||||
|
|
4
go.mod
4
go.mod
|
@ -4,7 +4,7 @@ go 1.18
|
|||
|
||||
require (
|
||||
github.com/mjl-/bstore v0.0.2
|
||||
github.com/mjl-/sconf v0.0.4
|
||||
github.com/mjl-/sconf v0.0.5
|
||||
github.com/mjl-/sherpa v0.6.6
|
||||
github.com/mjl-/sherpadoc v0.0.12
|
||||
github.com/mjl-/sherpaprom v0.0.2
|
||||
|
@ -22,7 +22,7 @@ require (
|
|||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mjl-/xfmt v0.0.0-20190521151243-39d9c00752ce // indirect
|
||||
github.com/mjl-/xfmt v0.0.2 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
|
|
8
go.sum
8
go.sum
|
@ -147,8 +147,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j
|
|||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mjl-/bstore v0.0.2 h1:4fdpIOY/+Dv1dBHyzdqa4PD90p8Mz86FeyRpI4qcehw=
|
||||
github.com/mjl-/bstore v0.0.2/go.mod h1:/cD25FNBaDfvL/plFRxI3Ba3E+wcB0XVOS8nJDqndg0=
|
||||
github.com/mjl-/sconf v0.0.4 h1:uyfn4vv5qOULSgiwQsPbbgkiONKnMFMsSOhsHfAiYwI=
|
||||
github.com/mjl-/sconf v0.0.4/go.mod h1:ezf7YOn7gtClo8y71SqgZKaEkyMQ5Te7vkv4PmTTfwM=
|
||||
github.com/mjl-/sconf v0.0.5 h1:4CMUTENpSnaeP2g6RKtrs8udTxnJgjX2MCCovxGId6s=
|
||||
github.com/mjl-/sconf v0.0.5/go.mod h1:uF8OdWtLT8La3i4ln176i1pB0ps9pXGCaABEU55ZkE0=
|
||||
github.com/mjl-/sherpa v0.6.6 h1:4Xc4/s12W2I/C1genIL8l4ZCLMsTo8498cPSjQcIHGc=
|
||||
github.com/mjl-/sherpa v0.6.6/go.mod h1:dSpAOdgpwdqQZ72O4n3EHo/tR68eKyan8tYYraUMPNc=
|
||||
github.com/mjl-/sherpadoc v0.0.0-20190505200843-c0a7f43f5f1d/go.mod h1:5khTKxoKKNXcB8bkVUO6GlzC7PFtMmkHq578lPbmnok=
|
||||
|
@ -158,8 +158,8 @@ github.com/mjl-/sherpaprom v0.0.2 h1:1dlbkScsNafM5jURI44uiWrZMSwfZtcOFEEq7vx2C1Y
|
|||
github.com/mjl-/sherpaprom v0.0.2/go.mod h1:cl5nMNOvqhzMiQJ2FzccQ9ReivjHXe53JhOVkPfSvw4=
|
||||
github.com/mjl-/sherpats v0.0.4 h1:rZkJO4YV4MfuCi3E4ifzbhpY6VgZgsQoOcL04ABEib4=
|
||||
github.com/mjl-/sherpats v0.0.4/go.mod h1:MoNZJtLmu8oCZ4Ocv5vZksENN4pp6/SJMlg9uTII4KA=
|
||||
github.com/mjl-/xfmt v0.0.0-20190521151243-39d9c00752ce h1:oyFmIHo3GLWZzb0odAzN9QUy0MTW6P8JaNRnNVGCBCk=
|
||||
github.com/mjl-/xfmt v0.0.0-20190521151243-39d9c00752ce/go.mod h1:DIEOLmETMQHHr4OgwPG7iC37rDiN9MaZIZxNm5hBtL8=
|
||||
github.com/mjl-/xfmt v0.0.2 h1:6dLgd6U3bmDJKtTxsaSYYyMaORoO4hKBAJo4XKkPRko=
|
||||
github.com/mjl-/xfmt v0.0.2/go.mod h1:DIEOLmETMQHHr4OgwPG7iC37rDiN9MaZIZxNm5hBtL8=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
|
|
38
vendor/github.com/mjl-/sconf/describe.go
generated
vendored
38
vendor/github.com/mjl-/sconf/describe.go
generated
vendored
|
@ -17,6 +17,7 @@ type writeError struct{ error }
|
|||
|
||||
type writer struct {
|
||||
out *bufio.Writer
|
||||
wrote int
|
||||
prefix string
|
||||
keepZero bool // If set, we also write zero values.
|
||||
docs bool // If set, we write comments.
|
||||
|
@ -33,8 +34,9 @@ func (w *writer) check(err error) {
|
|||
}
|
||||
|
||||
func (w *writer) write(s string) {
|
||||
_, err := w.out.WriteString(s)
|
||||
n, err := w.out.WriteString(s)
|
||||
w.check(err)
|
||||
w.wrote += n
|
||||
}
|
||||
|
||||
func (w *writer) flush() {
|
||||
|
@ -108,7 +110,7 @@ func isEmptyStruct(v reflect.Value) bool {
|
|||
for i := 0; i < n; i++ {
|
||||
ft := t.Field(i)
|
||||
tag := ft.Tag.Get("sconf")
|
||||
if isIgnore(tag) {
|
||||
if !ft.IsExported() || isIgnore(tag) {
|
||||
continue
|
||||
}
|
||||
if !isOptional(tag) {
|
||||
|
@ -134,7 +136,7 @@ func isZeroIgnored(v reflect.Value) bool {
|
|||
for i := 0; i < n; i++ {
|
||||
ft := t.Field(i)
|
||||
tag := ft.Tag.Get("sconf")
|
||||
if isIgnore(tag) {
|
||||
if !ft.IsExported() || isIgnore(tag) {
|
||||
continue
|
||||
}
|
||||
if !isZeroIgnored(v.Field(i)) {
|
||||
|
@ -153,7 +155,7 @@ func (w *writer) describeStruct(v reflect.Value) {
|
|||
for i := 0; i < n; i++ {
|
||||
f := t.Field(i)
|
||||
fv := v.Field(i)
|
||||
if isIgnore(f.Tag.Get("sconf")) {
|
||||
if !f.IsExported() || isIgnore(f.Tag.Get("sconf")) {
|
||||
continue
|
||||
}
|
||||
if !w.keepZero && isOptional(f.Tag.Get("sconf")) && isZeroIgnored(fv) {
|
||||
|
@ -163,11 +165,33 @@ func (w *writer) describeStruct(v reflect.Value) {
|
|||
doc := f.Tag.Get("sconf-doc")
|
||||
optional := isOptional(f.Tag.Get("sconf"))
|
||||
if doc != "" || optional {
|
||||
s := "\n" + w.prefix + "# " + doc
|
||||
s := "\n"
|
||||
if w.wrote == 0 {
|
||||
// No empty line at start of file.
|
||||
s = ""
|
||||
}
|
||||
// Treat two blank lines as section separator: the comments are not joined with
|
||||
// lines with just "#", but instead with empty lines. To allow a hack where the
|
||||
// first field of a config struct gives some context about the file.
|
||||
sections := strings.Split(doc, "\n\n\n")
|
||||
for si, section := range sections {
|
||||
if si > 0 {
|
||||
s += "\n\n\n"
|
||||
}
|
||||
for i, line := range strings.Split(section, "\n") {
|
||||
if i > 0 {
|
||||
s += "\n"
|
||||
}
|
||||
s += w.prefix + "#"
|
||||
if line != "" {
|
||||
s += " " + line
|
||||
}
|
||||
}
|
||||
}
|
||||
if optional {
|
||||
opt := "(optional)"
|
||||
if doc != "" {
|
||||
opt = " " + opt
|
||||
if !strings.HasSuffix(doc, " ") {
|
||||
s += " "
|
||||
}
|
||||
s += opt
|
||||
}
|
||||
|
|
6
vendor/github.com/mjl-/sconf/parse.go
generated
vendored
6
vendor/github.com/mjl-/sconf/parse.go
generated
vendored
|
@ -245,8 +245,8 @@ func (p *parser) parseStruct0(v reflect.Value) {
|
|||
if vv == zeroValue {
|
||||
p.stop(fmt.Sprintf("unknown key %q", k))
|
||||
}
|
||||
if ft, _ := t.FieldByName(k); isIgnore(ft.Tag.Get("sconf")) {
|
||||
p.stop(fmt.Sprintf("unknown key %q (has ignore tag)", k))
|
||||
if ft, _ := t.FieldByName(k); !ft.IsExported() || isIgnore(ft.Tag.Get("sconf")) {
|
||||
p.stop(fmt.Sprintf("unknown key %q (has ignore tag or not exported)", k))
|
||||
}
|
||||
vv.Set(p.parseValue(vv))
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ func (p *parser) parseStruct0(v reflect.Value) {
|
|||
n := t.NumField()
|
||||
for i := 0; i < n; i++ {
|
||||
f := t.Field(i)
|
||||
if isIgnore(f.Tag.Get("sconf")) || isOptional(f.Tag.Get("sconf")) {
|
||||
if !f.IsExported() || isIgnore(f.Tag.Get("sconf")) || isOptional(f.Tag.Get("sconf")) {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[f.Name]; !ok {
|
||||
|
|
16
vendor/github.com/mjl-/xfmt/xfmt.go
generated
vendored
16
vendor/github.com/mjl-/xfmt/xfmt.go
generated
vendored
|
@ -10,8 +10,12 @@ import (
|
|||
|
||||
// Config tells format how to reformat text.
|
||||
type Config struct {
|
||||
MaxWidth int // Max width of content (excluding indenting), after which lines are wrapped.
|
||||
BreakPrefixes []string // String prefixes that cause a line to break, instead of being merged into the previous line.
|
||||
// Max width of content (excluding indenting), after which lines are wrapped.
|
||||
MaxWidth int
|
||||
|
||||
// String prefixes that cause a line to break, instead of being merged into the
|
||||
// previous line.
|
||||
BreakPrefixes []string
|
||||
}
|
||||
|
||||
// Format reads text from r and writes reformatted text to w, according to
|
||||
|
@ -33,7 +37,7 @@ type formatter struct {
|
|||
curLineend string
|
||||
}
|
||||
|
||||
type parseError error
|
||||
type parseError struct{ error }
|
||||
|
||||
func (f *formatter) format() (rerr error) {
|
||||
defer func() {
|
||||
|
@ -65,7 +69,7 @@ func (f *formatter) format() (rerr error) {
|
|||
|
||||
func (f *formatter) check(err error, action string) {
|
||||
if err != nil {
|
||||
panic(parseError(fmt.Errorf("%s: %s", action, err)))
|
||||
panic(parseError{fmt.Errorf("%s: %s", action, err)})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,6 +112,7 @@ func (f *formatter) gatherLine() (string, string) {
|
|||
var curLine, curLineend string
|
||||
var curPrefix string
|
||||
|
||||
n := 0
|
||||
for {
|
||||
line, end := f.peekLine()
|
||||
if line == "" && end == "" {
|
||||
|
@ -123,7 +128,7 @@ func (f *formatter) gatherLine() (string, string) {
|
|||
}
|
||||
break
|
||||
}
|
||||
if curLine != "" && (curPrefix != prefix || rem == "" || f.causeBreak(rem)) {
|
||||
if n > 0 && (curPrefix != prefix || rem == "" || f.causeBreak(rem)) {
|
||||
break
|
||||
}
|
||||
curPrefix = prefix
|
||||
|
@ -136,6 +141,7 @@ func (f *formatter) gatherLine() (string, string) {
|
|||
if curLine != "" && curLine[len(curLine)-1] < 0x20 {
|
||||
break
|
||||
}
|
||||
n++
|
||||
}
|
||||
|
||||
return curPrefix + curLine, curLineend
|
||||
|
|
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
|
@ -14,7 +14,7 @@ github.com/matttproud/golang_protobuf_extensions/pbutil
|
|||
# github.com/mjl-/bstore v0.0.2
|
||||
## explicit; go 1.19
|
||||
github.com/mjl-/bstore
|
||||
# github.com/mjl-/sconf v0.0.4
|
||||
# github.com/mjl-/sconf v0.0.5
|
||||
## explicit; go 1.12
|
||||
github.com/mjl-/sconf
|
||||
# github.com/mjl-/sherpa v0.6.6
|
||||
|
@ -31,7 +31,7 @@ github.com/mjl-/sherpaprom
|
|||
## explicit; go 1.12
|
||||
github.com/mjl-/sherpats
|
||||
github.com/mjl-/sherpats/cmd/sherpats
|
||||
# github.com/mjl-/xfmt v0.0.0-20190521151243-39d9c00752ce
|
||||
# github.com/mjl-/xfmt v0.0.2
|
||||
## explicit; go 1.12
|
||||
github.com/mjl-/xfmt
|
||||
# github.com/prometheus/client_golang v1.14.0
|
||||
|
|
Loading…
Reference in a new issue