working commit

This commit is contained in:
2026-01-28 18:17:56 +02:00
parent d6496a427b
commit a9075902a3
8 changed files with 308 additions and 47 deletions
+13 -5
View File
@@ -2,21 +2,29 @@ AUTOMAKE_OPTIONS = foreign no-dependencies no-installinfo
GOFLAGS= -v
bin_PROGRAMS = mstorectl
sbin_PROGRAMS = mstored
mstored_SOURCES = cmd/mstored/main.go
mstorectl_SOURCES = \
cmd/mstorectl/main.go
cmd/mstorectl/file.go
mstored_SOURCES = \
cmd/mstored/main.go
mstorectl$(EXEEXT): $(mstorectl_SOURCES)
env CGO_ENABLED=0 $(GO) build $(GOFLAGS) -o mstorectl$(EXEEXT) $(mstorectl_SOURCES)
mstored$(EXEEXT): $(mstored_SOURCES)
env CGO_ENABLED=1 $(GO) build $(GOFLAGS) -o mstored$(EXEEXT) $(mstored_SOURCES)
run: mstored$(EXEEXT)
$(CWD)/mstored$(EXEEXT)
run: $(mstored_SOURCES)
cd cmd/mstored && env CGO_ENABLED=1 $(GO) run .
CWD=$(shell pwd)
format:
dirs=$$($(FIND) $(CWD) -name '*.go' | $(XARGS) -n1 dirname | $(SORT) | $(UNIQ)); \
@dirs=$$($(FIND) $(CWD) -name '*.go' | $(XARGS) -n1 dirname | $(SORT) | $(UNIQ)); \
for dir in $$dirs;do \
(echo "====$$dir===="; cd $$dir && $(GO) fmt .); \
done
+84 -27
View File
@@ -88,6 +88,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = mstorectl$(EXEEXT)
sbin_PROGRAMS = mstored$(EXEEXT)
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -101,8 +102,11 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES = app/config/variant.go
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)"
PROGRAMS = $(sbin_PROGRAMS)
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"
PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS)
am_mstorectl_OBJECTS =
mstorectl_OBJECTS = $(am_mstorectl_OBJECTS)
mstorectl_LDADD = $(LDADD)
am_mstored_OBJECTS =
mstored_OBJECTS = $(am_mstored_OBJECTS)
mstored_LDADD = $(LDADD)
@@ -133,8 +137,8 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(mstored_SOURCES)
DIST_SOURCES = $(mstored_SOURCES)
SOURCES = $(mstorectl_SOURCES) $(mstored_SOURCES)
DIST_SOURCES = $(mstorectl_SOURCES) $(mstored_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -282,7 +286,12 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign no-dependencies no-installinfo
GOFLAGS = -v
mstored_SOURCES = cmd/mstored/main.go
mstorectl_SOURCES = \
cmd/mstorectl/main.go
mstored_SOURCES = \
cmd/mstored/main.go
CWD = $(shell pwd)
all: all-am
@@ -322,6 +331,48 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
app/config/variant.go: $(top_builddir)/config.status $(top_srcdir)/app/config/variant.go.in
cd $(top_builddir) && $(SHELL) ./config.status $@
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
$(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p \
; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' \
-e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' \
`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
@@ -605,7 +656,7 @@ check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(sbindir)"; do \
for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -640,7 +691,8 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-local clean-sbinPROGRAMS mostlyclean-am
clean-am: clean-binPROGRAMS clean-generic clean-local \
clean-sbinPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
@@ -666,7 +718,7 @@ install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-sbinPROGRAMS
install-exec-am: install-binPROGRAMS install-sbinPROGRAMS
install-html: install-html-am
@@ -706,38 +758,43 @@ ps: ps-am
ps-am:
uninstall-am: uninstall-sbinPROGRAMS
uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \
clean-cscope clean-generic clean-local clean-sbinPROGRAMS \
cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
dist-zstd distcheck distclean distclean-compile \
distclean-generic distclean-tags distcleancheck distdir \
distuninstallcheck dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-sbinPROGRAMS install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am uninstall-sbinPROGRAMS
clean-binPROGRAMS clean-cscope clean-generic clean-local \
clean-sbinPROGRAMS cscope cscopelist-am ctags ctags-am dist \
dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
dist-xz dist-zip dist-zstd distcheck distclean \
distclean-compile distclean-generic distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-binPROGRAMS \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \
uninstall-sbinPROGRAMS
.PRECIOUS: Makefile
cmd/mstorectl/file.go
mstorectl$(EXEEXT): $(mstorectl_SOURCES)
env CGO_ENABLED=0 $(GO) build $(GOFLAGS) -o mstorectl$(EXEEXT) $(mstorectl_SOURCES)
mstored$(EXEEXT): $(mstored_SOURCES)
env CGO_ENABLED=1 $(GO) build $(GOFLAGS) -o mstored$(EXEEXT) $(mstored_SOURCES)
run: mstored$(EXEEXT)
$(CWD)/mstored$(EXEEXT)
run: $(mstored_SOURCES)
cd cmd/mstored && env CGO_ENABLED=1 $(GO) run .
format:
dirs=$$($(FIND) $(CWD) -name '*.go' | $(XARGS) -n1 dirname | $(SORT) | $(UNIQ)); \
@dirs=$$($(FIND) $(CWD) -name '*.go' | $(XARGS) -n1 dirname | $(SORT) | $(UNIQ)); \
for dir in $$dirs;do \
(echo "====$$dir===="; cd $$dir && $(GO) fmt .); \
done
+72 -8
View File
@@ -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
}
+1
View File
@@ -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"
)
+1
View File
@@ -6,4 +6,5 @@ const (
logdir = "@srv_logdir@"
datadir = "@srv_datadir@"
version = "@PACKAGE_VERSION@"
srvname = "@PACKAGE_NAME@d"
)
+128 -7
View File
@@ -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
}
+2
View File
@@ -8,6 +8,7 @@ require (
github.com/mattn/go-sqlite3 v1.14.33
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.11.1
sigs.k8s.io/yaml v1.6.0
)
require (
@@ -15,5 +16,6 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.9 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+7
View File
@@ -5,6 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@@ -25,8 +27,13 @@ github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=