added support for config files, openbsd, pledge and unveil

This commit is contained in:
ston1th 2018-10-26 17:28:50 +02:00
commit 375933c7bc
14 changed files with 138 additions and 49 deletions

View file

@ -4,6 +4,7 @@ VERSION=$(shell cat VERSION)
GCFLAGS=-gcflags '-e' GCFLAGS=-gcflags '-e'
LDFLAGS=-ldflags '-X main.version=$(VERSION) -s -w' LDFLAGS=-ldflags '-X main.version=$(VERSION) -s -w'
PROGRAM=gowiki PROGRAM=gowiki
ENV=CGO_ENABLED=0
all: $(PROGRAM) all: $(PROGRAM)
@ -11,10 +12,10 @@ setup:
$(CC) get github.com/client9/misspell $(CC) get github.com/client9/misspell
vendor: clean codeqa vendor: clean codeqa
CGO_ENABLED=0 $(CC) $(BUILD) -mod=vendor $(LDFLAGS) $(ENV) $(CC) $(BUILD) -mod=vendor $(LDFLAGS)
$(PROGRAM): clean codeqa $(PROGRAM): clean codeqa
CGO_ENABLED=0 $(CC) $(BUILD) $(LDFLAGS) $(ENV) $(CC) $(BUILD) $(LDFLAGS)
clean: clean:
$(CC) clean -x $(CC) clean -x
@ -36,9 +37,13 @@ misspell:
test: test:
ifeq ($(shell go env GOARCH), $(shell go env GOHOSTARCH)) ifeq ($(shell go env GOARCH), $(shell go env GOHOSTARCH))
ifeq ($(shell go env GOOS), $(shell go env GOHOSTOS))
$(CC) test ./... $(CC) test ./...
else else
$(info skipping tests of other platforms) $(info skipping tests of other platforms)
endif endif
else
$(info skipping tests of other platforms)
endif
.PHONY: setup vendor build clean codeqa generate gofmt golint misspell test .PHONY: setup vendor build clean codeqa generate gofmt golint misspell test

View file

@ -1 +1,27 @@
# GoWiki - a simple wiki engine written in Go # GoWiki - a simple wiki engine written in Go
## Building
Linux:
```
make
or offline
make vendor
```
OpenBSD:
```
GOOS=openbsd make
or offline
GOOS=openbsd make vendor
```
## Install
See the `scripts/` directory on how to install gowiki on Linux or OpenBSD.

View file

@ -3,6 +3,7 @@
package cmd package cmd
import ( import (
"encoding/json"
"git.giftfish.de/ston1th/godrop/v2" "git.giftfish.de/ston1th/godrop/v2"
"git.giftfish.de/ston1th/gowiki/pkg/core" "git.giftfish.de/ston1th/gowiki/pkg/core"
"git.giftfish.de/ston1th/gowiki/pkg/db" "git.giftfish.de/ston1th/gowiki/pkg/db"
@ -29,10 +30,11 @@ const (
var ( var (
conf core.Config conf core.Config
dumpFile string dumpFile string
config string
) )
func initServer(conf core.Config) (err error) { func initServer(conf core.Config) (err error) {
if err = core.Pledge("stdio rpath wpath cpath inet fattr flock proc exec id", ""); err != nil { if err = godrop.PledgePromises("stdio rpath wpath cpath inet fattr flock proc exec id unveil"); err != nil {
return return
} }
dropCfg := godrop.Config{ dropCfg := godrop.Config{
@ -50,17 +52,17 @@ func initServer(conf core.Config) (err error) {
return return
} }
if err = core.Pledge("stdio rpath wpath cpath inet fattr flock", ""); err != nil { if err = godrop.PledgePromises("stdio rpath wpath cpath inet fattr flock unveil"); err != nil {
return return
} }
log.InitLogger(conf.DataDir, conf.LogFile, conf.Debug)
l, err := godrop.GetListener() l, err := godrop.GetListener()
if err != nil { if err != nil {
return return
} }
log.InitLogger(conf.DataDir, conf.LogFile, conf.Debug)
srv := server.NewHTTPServer(l, conf) srv := server.NewHTTPServer(l, conf)
err = srv.Start() err = srv.Start()
if err != nil { if err != nil {
@ -70,7 +72,7 @@ func initServer(conf core.Config) (err error) {
sigs := make(chan os.Signal) sigs := make(chan os.Signal)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
sig := <-sigs sig := <-sigs
log.Println("caught " + sig.String()) log.Println("signal: " + sig.String())
go func() { go func() {
time.Sleep(time.Second * 20) time.Sleep(time.Second * 20)
log.Fatal("stop timed out: killing") log.Fatal("stop timed out: killing")
@ -83,6 +85,21 @@ func initServer(conf core.Config) (err error) {
return return
} }
func loadConfig() error {
if config == "" {
return nil
}
file, err := os.Open(config)
if err != nil {
return err
}
err = json.NewDecoder(file).Decode(&conf)
if err != nil {
return err
}
return file.Close()
}
func Run(version string) { func Run(version string) {
app := cli.NewApp() app := cli.NewApp()
app.Name = "gowiki" app.Name = "gowiki"
@ -94,9 +111,12 @@ func Run(version string) {
Usage: "start gowiki server", Usage: "start gowiki server",
Flags: defaultFlags(serverFlags()), Flags: defaultFlags(serverFlags()),
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
if err := loadConfig(); err != nil {
stdlog.Fatal("server: ", err)
}
conf.Version = app.Version conf.Version = app.Version
if err := initServer(conf); err != nil { if err := initServer(conf); err != nil {
stdlog.Fatal(err) stdlog.Fatal("server: ", err)
} }
return nil return nil
}, },
@ -110,15 +130,15 @@ func Run(version string) {
file = os.Stdout file = os.Stdout
err error err error
) )
if err = loadConfig(); err != nil {
stdlog.Fatal("dump: ", err)
}
if dumpFile != "-" { if dumpFile != "-" {
file, err = os.OpenFile(dumpFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0640) file, err = os.OpenFile(dumpFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0640)
if err != nil { if err != nil {
stdlog.Fatal("dump: ", err) stdlog.Fatal("dump: ", err)
} }
} }
if err = os.Chdir(conf.DataDir); err != nil {
stdlog.Fatal("dump: ", err)
}
DB, err := db.New(conf.DataDir) DB, err := db.New(conf.DataDir)
if err != nil { if err != nil {
stdlog.Fatal("dump: ", err) stdlog.Fatal("dump: ", err)
@ -143,15 +163,15 @@ func Run(version string) {
file = os.Stdin file = os.Stdin
err error err error
) )
if err = loadConfig(); err != nil {
stdlog.Fatal("restore: ", err)
}
if dumpFile != "-" { if dumpFile != "-" {
file, err = os.Open(dumpFile) file, err = os.Open(dumpFile)
if err != nil { if err != nil {
stdlog.Fatal("dump: ", err)
}
}
if err = os.Chdir(conf.DataDir); err != nil {
stdlog.Fatal("restore: ", err) stdlog.Fatal("restore: ", err)
} }
}
DB, err := db.New(conf.DataDir) DB, err := db.New(conf.DataDir)
if err != nil { if err != nil {
stdlog.Fatal("restore: ", err) stdlog.Fatal("restore: ", err)
@ -233,6 +253,11 @@ func dumpRestoreFlags() []cli.Flag {
func defaultFlags(f []cli.Flag) []cli.Flag { func defaultFlags(f []cli.Flag) []cli.Flag {
return append([]cli.Flag{ return append([]cli.Flag{
cli.StringFlag{
Name: "config, c",
Usage: "config file",
Destination: &config,
},
cli.StringFlag{ cli.StringFlag{
Name: "data, d", Name: "data, d",
Value: defDataDir, Value: defDataDir,

View file

@ -1,7 +0,0 @@
// Copyright (C) 2018 Marius Schellenberger
// +build !openbsd
package core
func Pledge(promises, execpromises string) error { return nil }

View file

@ -1,11 +0,0 @@
// Copyright (C) 2018 Marius Schellenberger
// +build openbsd
package core
import "golang.org/x/sys/unix"
func Pledge(promises, execpromises string) error {
return unix.Pledge(promises, execpromises)
}

View file

@ -43,14 +43,14 @@ type Result struct {
} }
type Config struct { type Config struct {
DataDir string DataDir string `json:"data_dir,omitempty"`
User string User string `json:"user,omitempty"`
Group string Group string `json:"group,omitempty"`
ListenAddr string ListenAddr string `json:"listen_addr,omitempty"`
LogFile string LogFile string `json:"log_file,omitempty"`
Version string Version string `json:"-"`
Secret string Secret string `json:"secret,omitempty"`
Foreground bool Foreground bool `json:"foreground,omitempty"`
SecureCookie bool SecureCookie bool `json:"secure_cookie,omitempty"`
Debug bool Debug bool `json:"debug,omitempty"`
} }

View file

@ -3,6 +3,7 @@
package db package db
import ( import (
"git.giftfish.de/ston1th/godrop/v2"
"git.giftfish.de/ston1th/gowiki/pkg/cache" "git.giftfish.de/ston1th/gowiki/pkg/cache"
"git.giftfish.de/ston1th/gowiki/pkg/core" "git.giftfish.de/ston1th/gowiki/pkg/core"
"git.giftfish.de/ston1th/gowiki/pkg/index" "git.giftfish.de/ston1th/gowiki/pkg/index"
@ -32,7 +33,12 @@ type DB struct {
func New(dir string) (db *DB, err error) { func New(dir string) (db *DB, err error) {
db = &DB{cache: cache.NewCache()} db = &DB{cache: cache.NewCache()}
db.store, err = store.NewBoltStore(filepath.Join(dir, storeFile), nil) dbFile := filepath.Join(dir, storeFile)
err = godrop.Unveil(dbFile, "rwc")
if err != nil {
return
}
db.store, err = store.NewBoltStore(dbFile, nil)
if err != nil { if err != nil {
return return
} }

View file

@ -79,7 +79,6 @@ func (db *DB) CreatePage(title, section, markdown, username string, p core.Permi
} }
st := render.StoreTitle(section, render.Title(title)) st := render.StoreTitle(section, render.Title(title))
_, err = db.getPage(st, username) _, err = db.getPage(st, username)
//if err == nil || (err != nil && err != store.ErrKeyNotFound) {
if err != store.ErrKeyNotFound { if err != store.ErrKeyNotFound {
return return
} }

View file

@ -4,6 +4,7 @@ package index
import ( import (
"errors" "errors"
"git.giftfish.de/ston1th/godrop/v2"
"git.giftfish.de/ston1th/gowiki/pkg/core" "git.giftfish.de/ston1th/gowiki/pkg/core"
"github.com/blevesearch/bleve" "github.com/blevesearch/bleve"
"html/template" "html/template"
@ -24,6 +25,10 @@ type Index struct {
func NewIndex(path string) (i *Index, err error) { func NewIndex(path string) (i *Index, err error) {
var bi bleve.Index var bi bleve.Index
err = godrop.Unveil(path, "rwc")
if err != nil {
return
}
if _, err = os.Stat(path); os.IsNotExist(err) { if _, err = os.Stat(path); os.IsNotExist(err) {
mapping := bleve.NewIndexMapping() mapping := bleve.NewIndexMapping()
bi, err = bleve.New(path, mapping) bi, err = bleve.New(path, mapping)

View file

@ -3,6 +3,7 @@
package log package log
import ( import (
"git.giftfish.de/ston1th/godrop/v2"
stdlog "log" stdlog "log"
"os" "os"
"path/filepath" "path/filepath"
@ -18,7 +19,13 @@ func InitLogger(dir, file string, d bool) {
if file == "-" { if file == "-" {
return return
} }
f, err := os.OpenFile(filepath.Join(dir, file), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0640) logfile := filepath.Join(dir, file)
err := godrop.Unveil(logfile, "rwc")
if err != nil {
stdlog.Fatal(err)
return
}
f, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0640)
if err != nil { if err != nil {
stdlog.Fatal(err) stdlog.Fatal(err)
} }

View file

@ -109,9 +109,6 @@ func openTag(j int) (ret string) {
for i := 0; i < j; i++ { for i := 0; i < j; i++ {
ret += `<ul class="toc"><li>` ret += `<ul class="toc"><li>`
} }
//if j > 1 {
// ret = strings.Replace(ret, "circle", "none", j-1)
//}
ret = ret[0 : len(ret)-4] ret = ret[0 : len(ret)-4]
return return
} }

View file

@ -6,6 +6,7 @@ import (
"bytes" "bytes"
"context" "context"
"errors" "errors"
"git.giftfish.de/ston1th/godrop/v2"
"git.giftfish.de/ston1th/gowiki/pkg/core" "git.giftfish.de/ston1th/gowiki/pkg/core"
"git.giftfish.de/ston1th/gowiki/pkg/db" "git.giftfish.de/ston1th/gowiki/pkg/db"
"git.giftfish.de/ston1th/gowiki/pkg/log" "git.giftfish.de/ston1th/gowiki/pkg/log"
@ -57,6 +58,10 @@ func (s *HTTPServer) Start() (err error) {
if err != nil { if err != nil {
return errors.New("db: " + err.Error()) return errors.New("db: " + err.Error())
} }
err = godrop.UnveilBlock()
if err != nil {
return
}
if s.Secret != "" { if s.Secret != "" {
s.JWT, err = jwt.New(jwt.DefaultExpiry, s.DB, bytes.NewBufferString(s.Secret)) s.JWT, err = jwt.New(jwt.DefaultExpiry, s.DB, bytes.NewBufferString(s.Secret))
} else { } else {

32
scripts/install_openbsd.sh Executable file
View file

@ -0,0 +1,32 @@
#!/bin/sh
# rc script
cat <<'EOF'> /etc/rc.d/gowiki
#!/bin/sh
daemon="/usr/local/sbin/gowiki"
. /etc/rc.d/rc.subr
rc_cmd $1
EOF
chmod 555 /etc/rc.d/gowiki
rcctl enable gowiki
rcctl set gowiki flags server -c /var/wiki/gowiki.conf
# user
useradd -m -b /var -s /sbin/nologin wiki
# config
cat <<EOF> /var/wiki/gowiki.conf
{
"data_dir": "/var/wiki",
"secret": "$(openssl rand -hex 32)",
"secure_cookie": true
}
EOF
chmod 640 /var/wiki/gowiki.conf
chgrp wiki /var/wiki/gowiki.conf
# start
rcctl start gowiki