gowiki/main.go

152 lines
3 KiB
Go

//go:generate ./templates.sh
package main
import (
"errors"
"flag"
logger "log"
"net"
"os"
"os/signal"
"syscall"
"time"
"git.giftfish.de/ston1th/godrop"
"github.com/blevesearch/bleve"
)
const (
bleveStore = "."
defDataDir = "/var/lib/gowiki"
defListen = "127.0.0.1:8090"
defLog = "gowiki.log"
defUser = "admin"
defPassword = "gowiki"
defRunUser = "wiki"
defRunGroup = "wiki"
welcome = `# Welcome to GoWiki
This is the [Index](/wiki/Index) page.
You can customize it how you like.`
indexName = "Index"
)
var (
datadir string
listen string
secureCookie bool
user string
group string
logfile string
engine *Engine
db *BoltStore
dump bool
restore bool
)
func main() {
flag.StringVar(&datadir, "d", defDataDir, "data directory")
flag.StringVar(&user, "u", defRunUser, "drop privileges to user")
flag.StringVar(&group, "g", defRunGroup, "drop privileges to group")
flag.StringVar(&listen, "l", defListen, "listening <address>:<port>")
flag.StringVar(&logfile, "log", defLog, "log file")
flag.BoolVar(&secureCookie, "s", false, "enable secure cookie")
flag.BoolVar(&dump, "dump", false, "create a json dump of all articles in the data directory (dump is written to stdout)")
flag.BoolVar(&restore, "restore", false, "restore a json dump to the data directory (dump is read from stdin)")
flag.Parse()
if dump {
err := dumpWiki()
if err != nil {
logger.Fatal("dump: ", err)
}
return
}
if restore {
err := restoreWiki()
if err != nil {
logger.Fatal("restore: ", err)
}
return
}
cfg := godrop.Config{
User: user,
Group: group,
}
err := godrop.Drop(cfg, func() (net.Listener, error) {
return net.Listen("tcp", listen)
})
if err != nil {
logger.Fatal("main: ", err)
}
err = os.Chdir(datadir)
if err != nil {
logger.Fatal("main: ", err)
}
newLogger(logfile)
l, err := godrop.GetListener()
if err != nil {
log.Fatal("main: ", err)
}
db, err = NewBoltStore("users")
if err != nil {
log.Fatal("main: ", err)
}
if !db.UserExists(defUser) {
err = db.CreateUser(defUser, defPassword, true)
if err != nil {
log.Fatal("main: ", err)
}
}
if _, err := os.Stat(bleveStore); os.IsNotExist(err) {
mapping := bleve.NewIndexMapping()
index, err := bleve.New(bleveStore, mapping)
if err != nil {
log.Fatal("main: ", err)
}
engine = NewEngine(index)
_, err = engine.Index(indexName, welcome, defUser, true)
if err != nil {
log.Fatal("main: ", err)
}
} else {
index, err := bleve.Open(bleveStore)
if err != nil {
log.Fatal("main: ", err)
}
engine = NewEngine(index)
}
go webserver(l)
log.Println("gowiki started")
sigs := make(chan os.Signal)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
sig := <-sigs
log.Println("caught " + sig.String())
go func() {
time.Sleep(time.Second * 20)
log.Fatal(errors.New("stop timed out: killing"))
}()
err = l.Close()
if err != nil {
log.Println(err)
}
err = db.Close()
if err != nil {
log.Println(err)
}
err = engine.Close()
if err != nil {
log.Println(err)
}
}