caddy/main.go

157 lines
3.5 KiB
Go
Raw Normal View History

2015-01-14 03:43:45 +08:00
package main
import (
"errors"
"flag"
2015-04-16 04:11:32 +08:00
"fmt"
"io/ioutil"
2015-01-14 03:43:45 +08:00
"log"
"os"
"runtime"
"strconv"
"strings"
2015-01-14 03:43:45 +08:00
"github.com/mholt/caddy/caddy"
"github.com/mholt/caddy/caddy/letsencrypt"
2015-01-14 03:43:45 +08:00
)
var (
2015-05-08 03:09:40 +08:00
conf string
cpu string
version bool
2015-10-21 14:09:45 +08:00
revoke string
)
const (
appName = "Caddy"
appVersion = "0.8 beta"
)
func init() {
flag.StringVar(&conf, "conf", "", "Configuration file to use (default="+caddy.DefaultConfigFile+")")
flag.BoolVar(&caddy.HTTP2, "http2", true, "Enable HTTP/2 support") // TODO: temporary flag until http2 merged into std lib
flag.BoolVar(&caddy.Quiet, "quiet", false, "Quiet mode (no initialization output)")
flag.StringVar(&cpu, "cpu", "100%", "CPU cap")
flag.StringVar(&caddy.Root, "root", caddy.DefaultRoot, "Root path to default site")
flag.StringVar(&caddy.Host, "host", caddy.DefaultHost, "Default host")
flag.StringVar(&caddy.Port, "port", caddy.DefaultPort, "Default port")
2015-05-08 03:09:40 +08:00
flag.BoolVar(&version, "version", false, "Show version")
flag.BoolVar(&letsencrypt.Agreed, "agree", false, "Agree to Let's Encrypt Subscriber Agreement")
flag.StringVar(&letsencrypt.DefaultEmail, "email", "", "Default email address to use for Let's Encrypt transactions")
flag.StringVar(&revoke, "revoke", "", "Hostname for which to revoke its certificate")
}
2015-01-14 03:43:45 +08:00
func main() {
flag.Parse()
caddy.AppName = appName
caddy.AppVersion = appVersion
2015-05-08 03:09:40 +08:00
if version {
fmt.Printf("%s %s\n", caddy.AppName, caddy.AppVersion)
2015-05-08 03:09:40 +08:00
os.Exit(0)
}
2015-10-21 14:09:45 +08:00
if revoke != "" {
err := letsencrypt.Revoke(revoke)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Revoked certificate for %s\n", revoke)
os.Exit(0)
}
2015-05-08 03:09:40 +08:00
// Set CPU cap
err := setCPU(cpu)
if err != nil {
log.Fatal(err)
}
// Get Caddyfile input
caddyfile, err := caddy.LoadCaddyfile(loadCaddyfile)
2015-04-16 04:11:32 +08:00
if err != nil {
log.Fatal(err)
}
// Start your engines
err = caddy.Start(caddyfile)
if err != nil {
log.Fatal(err)
2015-01-14 03:43:45 +08:00
}
// Twiddle your thumbs
caddy.Wait()
}
func loadCaddyfile() (caddy.Input, error) {
// -conf flag
if conf != "" {
contents, err := ioutil.ReadFile(conf)
if err != nil {
return nil, err
}
return caddy.CaddyfileInput{
Contents: contents,
Filepath: conf,
RealFile: true,
}, nil
}
// command line args
2015-09-09 02:14:23 +08:00
if flag.NArg() > 0 {
confBody := ":" + caddy.DefaultPort + "\n" + strings.Join(flag.Args(), "\n")
return caddy.CaddyfileInput{
Contents: []byte(confBody),
Filepath: "args",
}, nil
2015-09-09 02:14:23 +08:00
}
// Caddyfile in cwd
contents, err := ioutil.ReadFile(caddy.DefaultConfigFile)
if err != nil {
if os.IsNotExist(err) {
return caddy.DefaultInput, nil
}
return nil, err
}
return caddy.CaddyfileInput{
Contents: contents,
Filepath: caddy.DefaultConfigFile,
RealFile: true,
}, nil
}
// setCPU parses string cpu and sets GOMAXPROCS
// according to its value. It accepts either
// a number (e.g. 3) or a percent (e.g. 50%).
func setCPU(cpu string) error {
var numCPU int
availCPU := runtime.NumCPU()
if strings.HasSuffix(cpu, "%") {
// Percent
var percent float32
pctStr := cpu[:len(cpu)-1]
pctInt, err := strconv.Atoi(pctStr)
if err != nil || pctInt < 1 || pctInt > 100 {
return errors.New("invalid CPU value: percentage must be between 1-100")
}
percent = float32(pctInt) / 100
numCPU = int(float32(availCPU) * percent)
} else {
// Number
num, err := strconv.Atoi(cpu)
if err != nil || num < 1 {
return errors.New("invalid CPU value: provide a number or percent greater than 0")
}
numCPU = num
}
if numCPU > availCPU {
numCPU = availCPU
}
2015-05-06 23:16:10 +08:00
runtime.GOMAXPROCS(numCPU)
return nil
}