working commit
This commit is contained in:
+72
-8
@@ -1,10 +1,14 @@
|
||||
package config
|
||||
|
||||
type Config struct {
|
||||
Service Service `json:"service" yaml:"service"`
|
||||
Database Database `json:"database" yaml:"database"`
|
||||
Storage Storage `json:"storage" yaml:"storage"`
|
||||
}
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
Address string `json:"address" yaml:"address"`
|
||||
@@ -19,8 +23,23 @@ type Storage struct {
|
||||
Basepath string `json:"basepath" yaml:"basepath"`
|
||||
}
|
||||
|
||||
func NewConfig() (*Config, error) {
|
||||
var err error
|
||||
type Config struct {
|
||||
Service Service `json:"service" yaml:"service"`
|
||||
Database Database `json:"database" yaml:"database"`
|
||||
Storage Storage `json:"storage" yaml:"storage"`
|
||||
AsDaemon bool `json:"asDaemon" yaml:"asDaemon"`
|
||||
Logpath string `json:"logpath" yaml:"logpath"`
|
||||
Runpath string `json:"runpath" yaml:"runpath"`
|
||||
Version string `json:"version" yaml:"version"`
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
logfile := fmt.Sprintf("%s.log", srvname)
|
||||
logpath := filepath.Join(logdir, logfile)
|
||||
|
||||
runfile := fmt.Sprintf("%s.run", srvname)
|
||||
runpath := filepath.Join(rundir, runfile)
|
||||
|
||||
return &Config{
|
||||
Service: Service{
|
||||
Address: "0.0.0.0",
|
||||
@@ -32,5 +51,50 @@ func NewConfig() (*Config, error) {
|
||||
Storage: Storage{
|
||||
Basepath: datadir,
|
||||
},
|
||||
}, err
|
||||
AsDaemon: false,
|
||||
Logpath: logpath,
|
||||
Runpath: runpath,
|
||||
Version: version,
|
||||
}
|
||||
}
|
||||
|
||||
func (conf *Config) String() string {
|
||||
confbytes, _ := yaml.Marshal(conf)
|
||||
return string(confbytes)
|
||||
}
|
||||
|
||||
func (conf *Config) ReadConfigfile() error {
|
||||
conffile := fmt.Sprintf("%sd.yaml", srvname)
|
||||
confpath := filepath.Join(confdir, conffile)
|
||||
|
||||
confdata, err := ioutil.ReadFile(confpath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = yaml.Unmarshal(confdata, conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (conf *Config) ReadOptions() error {
|
||||
var err error
|
||||
exename := filepath.Base(os.Args[0])
|
||||
|
||||
flag.Int64Var(&conf.Service.Port, "port", conf.Service.Port, "listen port")
|
||||
flag.BoolVar(&conf.AsDaemon, "daemon", conf.AsDaemon, "run as daemon")
|
||||
|
||||
help := func() {
|
||||
fmt.Println("")
|
||||
fmt.Printf("Usage: %s [option]\n", exename)
|
||||
fmt.Println("")
|
||||
fmt.Println("Options:")
|
||||
flag.PrintDefaults()
|
||||
fmt.Println("")
|
||||
}
|
||||
flag.Usage = help
|
||||
flag.Parse()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@ const (
|
||||
logdir = "/home/ziggi/Projects/mstore/tmp/log"
|
||||
datadir = "/home/ziggi/Projects/mstore/tmp/data"
|
||||
version = "0.1.0"
|
||||
srvname = "mstored"
|
||||
)
|
||||
|
||||
@@ -6,4 +6,5 @@ const (
|
||||
logdir = "@srv_logdir@"
|
||||
datadir = "@srv_datadir@"
|
||||
version = "@PACKAGE_VERSION@"
|
||||
srvname = "@PACKAGE_NAME@d"
|
||||
)
|
||||
|
||||
+128
-7
@@ -6,8 +6,8 @@ import (
|
||||
"os/signal"
|
||||
"os/user"
|
||||
//"os/user"
|
||||
//"path/filepath"
|
||||
//"strconv"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
//"sync"
|
||||
"syscall"
|
||||
//"time"
|
||||
@@ -45,11 +45,19 @@ func (srv *Server) Handler() *handler.Handler {
|
||||
func (srv *Server) Configure() error {
|
||||
var err error
|
||||
srv.logg.Infof("Server configure")
|
||||
srv.conf, err = config.NewConfig()
|
||||
srv.conf = config.NewConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = srv.conf.ReadConfigfile()
|
||||
if err != nil {
|
||||
//srv.logg.Warningf("Error loading config file: %v", err)
|
||||
//return err
|
||||
}
|
||||
err = srv.conf.ReadOptions()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -57,21 +65,39 @@ func (srv *Server) Build() error {
|
||||
var err error
|
||||
srv.logg.Infof("Server build")
|
||||
|
||||
confDump := srv.conf.String()
|
||||
srv.logg.Infof("Current server configuration is:\n%s\n", confDump)
|
||||
|
||||
if srv.conf.AsDaemon {
|
||||
logdir := filepath.Dir(srv.conf.Logpath)
|
||||
srv.logg.Infof("Create log directory %s", logdir)
|
||||
err = os.MkdirAll(logdir, 0750)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rundir := filepath.Dir(srv.conf.Runpath)
|
||||
srv.logg.Infof("Create run directory %s", rundir)
|
||||
err = os.MkdirAll(rundir, 0750)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Database create
|
||||
srv.logg.Infof("Create database directory")
|
||||
dbdir := srv.conf.Database.Basepath
|
||||
srv.logg.Infof("Create database directory %s ", dbdir)
|
||||
err = os.MkdirAll(dbdir, 0750)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mdb := maindb.NewDatabase(dbdir)
|
||||
srv.logg.Infof("Open database")
|
||||
srv.logg.Infof("Open main database")
|
||||
err = mdb.OpenDatabase()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srv.logg.Infof("Initialize database")
|
||||
srv.logg.Infof("Initialize main database")
|
||||
err = mdb.InitDatabase()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -162,3 +188,98 @@ func (srv *Server) Run() error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (srv *Server) PseudoFork() error {
|
||||
const successExit int = 0
|
||||
var keyEnv string = "IMX0LTSELMRF8K"
|
||||
var err error
|
||||
|
||||
_, isChild := os.LookupEnv(keyEnv)
|
||||
switch {
|
||||
case !isChild:
|
||||
os.Setenv(keyEnv, "TRUE")
|
||||
|
||||
procAttr := syscall.ProcAttr{}
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var sysFiles = make([]uintptr, 3)
|
||||
sysFiles[0] = uintptr(syscall.Stdin)
|
||||
sysFiles[1] = uintptr(syscall.Stdout)
|
||||
sysFiles[2] = uintptr(syscall.Stderr)
|
||||
|
||||
procAttr.Files = sysFiles
|
||||
procAttr.Env = os.Environ()
|
||||
procAttr.Dir = cwd
|
||||
|
||||
_, err = syscall.ForkExec(os.Args[0], os.Args, &procAttr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
os.Exit(successExit)
|
||||
case isChild:
|
||||
_, err = syscall.Setsid()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
os.Unsetenv(keyEnv)
|
||||
return err
|
||||
}
|
||||
|
||||
func (srv *Server) Daemonize() error {
|
||||
var err error
|
||||
if srv.conf.AsDaemon {
|
||||
// Restart process process
|
||||
err = srv.PseudoFork()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Redirect stdin
|
||||
nullFile, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = syscall.Dup2(int(nullFile.Fd()), int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Redirect stderr and stout
|
||||
logdir := filepath.Dir(srv.conf.Logpath)
|
||||
err = os.MkdirAll(logdir, 0750)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logFile, err := os.OpenFile(srv.conf.Logpath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0640)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = syscall.Dup2(int(logFile.Fd()), int(os.Stdout.Fd()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = syscall.Dup2(int(logFile.Fd()), int(os.Stderr.Fd()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Write process ID
|
||||
rundir := filepath.Dir(srv.conf.Runpath)
|
||||
err = os.MkdirAll(rundir, 0750)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pidFile, err := os.OpenFile(srv.conf.Runpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0640)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer pidFile.Close()
|
||||
currPid := os.Getpid()
|
||||
_, err = pidFile.WriteString(strconv.Itoa(currPid))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user