2015-01-14 03:43:45 +08:00
|
|
|
package config
|
|
|
|
|
2015-01-22 05:10:52 +08:00
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"runtime"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
2015-01-19 14:11:21 +08:00
|
|
|
|
2015-01-14 03:43:45 +08:00
|
|
|
// dirFunc is a type of parsing function which processes
|
|
|
|
// a particular directive and populates the config.
|
|
|
|
type dirFunc func(*parser) error
|
|
|
|
|
2015-02-01 01:15:17 +08:00
|
|
|
// validDirectives is a map of valid, built-in directive names
|
|
|
|
// to their parsing function.
|
2015-01-14 03:43:45 +08:00
|
|
|
var validDirectives map[string]dirFunc
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
// This has to be in the init function
|
|
|
|
// to avoid an initialization loop error because
|
|
|
|
// the 'import' directive (key) in this map
|
|
|
|
// invokes a method that uses this map.
|
|
|
|
validDirectives = map[string]dirFunc{
|
|
|
|
"root": func(p *parser) error {
|
2015-01-19 14:11:21 +08:00
|
|
|
if !p.nextArg() {
|
2015-01-14 03:43:45 +08:00
|
|
|
return p.argErr()
|
|
|
|
}
|
|
|
|
p.cfg.Root = p.tkn()
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
"import": func(p *parser) error {
|
2015-01-19 14:11:21 +08:00
|
|
|
if !p.nextArg() {
|
2015-01-14 03:43:45 +08:00
|
|
|
return p.argErr()
|
|
|
|
}
|
|
|
|
|
2015-01-22 04:19:25 +08:00
|
|
|
filename := p.tkn()
|
|
|
|
file, err := os.Open(filename)
|
2015-01-14 03:43:45 +08:00
|
|
|
if err != nil {
|
|
|
|
return p.err("Parse", err.Error())
|
|
|
|
}
|
2015-01-19 14:11:21 +08:00
|
|
|
defer file.Close()
|
2015-01-22 04:19:25 +08:00
|
|
|
p2, err := newParser(file)
|
|
|
|
if err != nil {
|
|
|
|
return p.err("Parse", "Could not import "+filename+"; "+err.Error())
|
|
|
|
}
|
2015-01-14 03:43:45 +08:00
|
|
|
|
|
|
|
p2.cfg = p.cfg
|
|
|
|
err = p2.directives()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
p.cfg = p2.cfg
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
"tls": func(p *parser) error {
|
|
|
|
tls := TLSConfig{Enabled: true}
|
|
|
|
|
2015-01-19 14:11:21 +08:00
|
|
|
if !p.nextArg() {
|
2015-01-14 03:43:45 +08:00
|
|
|
return p.argErr()
|
|
|
|
}
|
|
|
|
tls.Certificate = p.tkn()
|
|
|
|
|
2015-01-19 14:11:21 +08:00
|
|
|
if !p.nextArg() {
|
2015-01-14 03:43:45 +08:00
|
|
|
return p.argErr()
|
|
|
|
}
|
|
|
|
tls.Key = p.tkn()
|
|
|
|
|
|
|
|
p.cfg.TLS = tls
|
|
|
|
return nil
|
|
|
|
},
|
2015-01-22 05:10:52 +08:00
|
|
|
"cpu": func(p *parser) error {
|
|
|
|
sysCores := runtime.NumCPU()
|
|
|
|
|
|
|
|
if !p.nextArg() {
|
|
|
|
return p.argErr()
|
|
|
|
}
|
|
|
|
strNum := p.tkn()
|
|
|
|
|
|
|
|
setCPU := func(val int) {
|
|
|
|
if val < 1 {
|
|
|
|
val = 1
|
|
|
|
}
|
|
|
|
if val > sysCores {
|
|
|
|
val = sysCores
|
|
|
|
}
|
|
|
|
if val > p.cfg.MaxCPU {
|
|
|
|
p.cfg.MaxCPU = val
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if strings.HasSuffix(strNum, "%") {
|
|
|
|
// Percent
|
|
|
|
var percent float32
|
|
|
|
pctStr := strNum[:len(strNum)-1]
|
|
|
|
pctInt, err := strconv.Atoi(pctStr)
|
|
|
|
if err != nil || pctInt < 1 || pctInt > 100 {
|
|
|
|
return p.err("Parse", "Invalid number '"+strNum+"' (must be a positive percentage between 1 and 100)")
|
|
|
|
}
|
|
|
|
percent = float32(pctInt) / 100
|
|
|
|
setCPU(int(float32(sysCores) * percent))
|
|
|
|
} else {
|
|
|
|
// Number
|
|
|
|
num, err := strconv.Atoi(strNum)
|
|
|
|
if err != nil || num < 0 {
|
|
|
|
return p.err("Parse", "Invalid number '"+strNum+"' (requires positive integer or percent)")
|
|
|
|
}
|
|
|
|
setCPU(num)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
},
|
2015-01-14 03:43:45 +08:00
|
|
|
}
|
|
|
|
}
|