mstore server: moving creating listener from service to service

This commit is contained in:
2026-03-25 12:21:58 +02:00
parent 8e7a0fffa7
commit 229a3a97fc
6 changed files with 97 additions and 81 deletions
+3 -1
View File
@@ -22,7 +22,7 @@ import (
type Service struct { type Service struct {
Address string `json:"address" yaml:"address"` Address string `json:"address" yaml:"address"`
Port int64 `json:"port" yaml:"port"` Port uint32 `json:"port" yaml:"port"`
} }
type Database struct { type Database struct {
@@ -49,6 +49,7 @@ type Config struct {
Hostname string `json:"hostname" yaml:hostname` Hostname string `json:"hostname" yaml:hostname`
Hostnames []string `json:"hostnames" yaml:hostnames` Hostnames []string `json:"hostnames" yaml:hostnames`
LogLimit int64 `json:"logLimit" yaml:logLimit` LogLimit int64 `json:"logLimit" yaml:logLimit`
RunUser string `json:"runUser" yaml:runUser`
} }
func NewConfig() *Config { func NewConfig() *Config {
@@ -84,6 +85,7 @@ func NewConfig() *Config {
//Keypath: keypath, //Keypath: keypath,
Hostnames: make([]string, 0), Hostnames: make([]string, 0),
LogLimit: 1024 * 1024 * 10, // 10 Mb LogLimit: 1024 * 1024 * 10, // 10 Mb
RunUser: "daemon",
} }
} }
+1 -1
View File
@@ -5,6 +5,6 @@ const (
rundir = "/var/run/mstore" rundir = "/var/run/mstore"
logdir = "/var/log/mstore" logdir = "/var/log/mstore"
datadir = "/var/lib/mstore" datadir = "/var/lib/mstore"
version = "0.2.3" version = "0.2.4"
srvname = "mstored" srvname = "mstored"
) )
+75 -18
View File
@@ -14,6 +14,7 @@ import (
"context" "context"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net"
"os" "os"
"os/signal" "os/signal"
"os/user" "os/user"
@@ -54,6 +55,9 @@ type Server struct {
cancel context.CancelFunc cancel context.CancelFunc
wg sync.WaitGroup wg sync.WaitGroup
logf *os.File logf *os.File
//x509cert []byte
//x509key []byte
listen net.Listener
} }
func NewServer() (*Server, error) { func NewServer() (*Server, error) {
@@ -85,7 +89,7 @@ func (srv *Server) SetDatadir(dir string) {
srv.conf.Datadir = dir srv.conf.Datadir = dir
} }
func (srv *Server) SetPort(port int64) { func (srv *Server) SetPort(port uint32) {
srv.conf.Service.Port = port srv.conf.Service.Port = port
} }
@@ -152,6 +156,21 @@ func (srv *Server) Build() error {
confDump := srv.conf.String() confDump := srv.conf.String()
srv.logg.Infof("Current server configuration is:\n%s\n", confDump) srv.logg.Infof("Current server configuration is:\n%s\n", confDump)
usr, err := user.Lookup(srv.conf.RunUser)
if err != nil {
return err
}
uid64, err := strconv.ParseInt(usr.Uid, 10, 64)
if err != nil {
return err
}
gid64, err := strconv.ParseInt(usr.Gid, 10, 64)
if err != nil {
return err
}
uid := int(uid64)
gid := int(gid64)
if srv.conf.AsDaemon { if srv.conf.AsDaemon {
logdir := filepath.Dir(srv.conf.Logpath) logdir := filepath.Dir(srv.conf.Logpath)
srv.logg.Infof("Creating log directory %s", logdir) srv.logg.Infof("Creating log directory %s", logdir)
@@ -159,12 +178,20 @@ func (srv *Server) Build() error {
if err != nil { if err != nil {
return err return err
} }
err = os.Chown(logdir, uid, gid)
if err != nil {
return err
}
rundir := filepath.Dir(srv.conf.Runpath) rundir := filepath.Dir(srv.conf.Runpath)
srv.logg.Infof("Creating run directory %s", rundir) srv.logg.Infof("Creating run directory %s", rundir)
err = os.MkdirAll(rundir, 0750) err = os.MkdirAll(rundir, 0750)
if err != nil { if err != nil {
return err return err
} }
err = os.Chown(rundir, uid, gid)
if err != nil {
return err
}
} }
// Creating datadir // Creating datadir
@@ -176,6 +203,11 @@ func (srv *Server) Build() error {
return err return err
} }
} }
err = os.Chown(datadir, uid, gid)
if err != nil {
return err
}
// Read state file // Read state file
srv.logg.Infof("Reading server status") srv.logg.Infof("Reading server status")
err = srv.ReadStat() err = srv.ReadStat()
@@ -184,13 +216,45 @@ func (srv *Server) Build() error {
} }
// Creating database dir // Creating database dir
dbdir := srv.conf.Database.Basepath dbdir := srv.conf.Database.Basepath
//if !auxtool.DirExists(dbdir) {
srv.logg.Infof("Creating database directory %s ", dbdir) srv.logg.Infof("Creating database directory %s ", dbdir)
err = os.MkdirAll(dbdir, 0750) err = os.MkdirAll(dbdir, 0750)
if err != nil { if err != nil {
return err return err
} }
//}
// Creating storage dir
srv.logg.Infof("Creating storage directory")
datadir = srv.conf.Database.Basepath
err = os.MkdirAll(datadir, 0750)
if err != nil {
return err
}
err = os.Chown(datadir, uid, gid)
if err != nil {
return err
}
cert, key := []byte(srv.conf.X509Cert), []byte(srv.conf.X509Key)
addrinfo := fmt.Sprintf("%s:%d", srv.conf.Service.Address, srv.conf.Service.Port)
listener, err := CreateTLSListener(addrinfo, cert, key)
if err != nil {
return err
}
srv.listen = listener
// Change effective user
err = syscall.Setuid(uid)
if err != nil {
return err
}
uidstr := strconv.FormatInt(int64(syscall.Geteuid()), 10)
usr, err = user.LookupId(uidstr)
if err != nil {
return err
}
srv.logg.Warningf("Now run as user: %s", usr.Username)
// Creating database // Creating database
mdb := maindb.NewDatabase(dbdir) mdb := maindb.NewDatabase(dbdir)
srv.logg.Infof("Opening main database") srv.logg.Infof("Opening main database")
@@ -246,15 +310,7 @@ func (srv *Server) Build() error {
return err return err
} }
} }
// Creating storage // Creating storage
srv.logg.Infof("Creating storage directory")
datadir = srv.conf.Database.Basepath
err = os.MkdirAll(datadir, 0750)
if err != nil {
return err
}
srv.logg.Infof("Creating storage") srv.logg.Infof("Creating storage")
store := storage.NewStorage(datadir) store := storage.NewStorage(datadir)
srv.stor = store srv.stor = store
@@ -289,7 +345,6 @@ func (srv *Server) Build() error {
if err != nil { if err != nil {
return err return err
} }
// Creating handler // Creating handler
srv.logg.Infof("Creating handler") srv.logg.Infof("Creating handler")
handlerParams := &handler.HandlerParams{ handlerParams := &handler.HandlerParams{
@@ -305,10 +360,7 @@ func (srv *Server) Build() error {
// Creating service // Creating service
serviceParams := &service.ServiceParams{ serviceParams := &service.ServiceParams{
Handler: srv.hand, Handler: srv.hand,
X509Cert: srv.conf.X509Cert, Listener: srv.listen,
X509Key: srv.conf.X509Key,
Address: srv.conf.Service.Address,
Portnum: srv.conf.Service.Port,
} }
srv.logg.Infof("Creating service") srv.logg.Infof("Creating service")
srv.svc, err = service.NewService(serviceParams) srv.svc, err = service.NewService(serviceParams)
@@ -320,7 +372,6 @@ func (srv *Server) Build() error {
if err != nil { if err != nil {
return err return err
} }
return err return err
} }
@@ -331,7 +382,13 @@ func (srv *Server) Run() error {
if err != nil { if err != nil {
return err return err
} }
srv.logg.Infof("Server run as user %s", currUser.Username) srv.logg.Infof("Server started with user: %s", currUser.Username)
uidstr := strconv.FormatInt(int64(syscall.Geteuid()), 10)
usr, err := user.LookupId(uidstr)
if err != nil {
return err
}
srv.logg.Infof("Server run with user: %s", usr.Username)
srv.ctx, srv.cancel = context.WithCancel(context.Background()) srv.ctx, srv.cancel = context.WithCancel(context.Background())
svcDone := make(chan error, 1) svcDone := make(chan error, 1)
+6 -49
View File
@@ -11,8 +11,6 @@ package service
import ( import (
"context" "context"
"crypto/tls"
"fmt"
"net" "net"
"net/http" "net/http"
"time" "time"
@@ -22,26 +20,15 @@ import (
"mstore/app/router" "mstore/app/router"
) )
const protocol = "tcp"
type ServiceParams struct { type ServiceParams struct {
Handler *handler.Handler Handler *handler.Handler
X509Cert string Listener net.Listener
X509Key string
Portnum int64
Address string
} }
type Service struct { type Service struct {
hand *handler.Handler hand *handler.Handler
rout *router.Router rout *router.Router
logg *logger.Logger logg *logger.Logger
address string
portnum int64
x509cert []byte
x509key []byte
listen net.Listener listen net.Listener
hsrv *http.Server hsrv *http.Server
} }
@@ -49,11 +36,8 @@ type Service struct {
func NewService(params *ServiceParams) (*Service, error) { func NewService(params *ServiceParams) (*Service, error) {
var err error var err error
svc := &Service{ svc := &Service{
hand: params.Handler, hand: params.Handler,
x509cert: []byte(params.X509Cert), listen: params.Listener,
x509key: []byte(params.X509Key),
portnum: params.Portnum,
address: params.Address,
} }
svc.logg = logger.NewLoggerWithSubject("service") svc.logg = logger.NewLoggerWithSubject("service")
return svc, err return svc, err
@@ -126,33 +110,6 @@ func (svc *Service) Build() error {
svc.logg.Infof("%s\t%s", item.Method, item.RawPath) svc.logg.Infof("%s\t%s", item.Method, item.RawPath)
} }
const useTLS = true
if useTLS {
tlsCert, err := tls.X509KeyPair(svc.x509cert, svc.x509key)
if err != nil {
return err
}
tlsConfig := tls.Config{
Certificates: []tls.Certificate{tlsCert},
ClientAuth: tls.NoClientCert,
InsecureSkipVerify: true,
}
listenAddress := fmt.Sprintf("%s:%d", svc.address, svc.portnum)
svc.listen, err = tls.Listen(protocol, listenAddress, &tlsConfig)
if err != nil {
return err
}
} else {
listenAddress := fmt.Sprintf("%s:%d", svc.address, svc.portnum)
svc.listen, err = net.Listen(protocol, listenAddress)
if err != nil {
return err
}
}
svc.logg.Infof("Service listening at %v", svc.listen.Addr()) svc.logg.Infof("Service listening at %v", svc.listen.Addr())
svc.hsrv = &http.Server{ svc.hsrv = &http.Server{
Handler: svc.rout, Handler: svc.rout,
+2 -2
View File
@@ -20,7 +20,7 @@ import (
type Starter struct { type Starter struct {
runAsDaemon bool runAsDaemon bool
port int64 port uint32
cmd *cobra.Command cmd *cobra.Command
srv *server.Server srv *server.Server
} }
@@ -36,7 +36,7 @@ func NewStarter() *Starter {
} }
cmd.CompletionOptions.DisableDefaultCmd = true cmd.CompletionOptions.DisableDefaultCmd = true
cmd.Flags().BoolVarP(&sta.runAsDaemon, "asDaemon", "D", true, "Run service as daemon") cmd.Flags().BoolVarP(&sta.runAsDaemon, "asDaemon", "D", true, "Run service as daemon")
cmd.Flags().Int64VarP(&sta.port, "port", "P", 1025, "Service port") cmd.Flags().Uint32VarP(&sta.port, "port", "P", 1025, "Service port")
sta.cmd = cmd sta.cmd = cmd
return sta return sta
Vendored
+10 -10
View File
@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.72 for mstore 0.2.3. # Generated by GNU Autoconf 2.72 for mstore 0.2.4.
# #
# #
# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation, # Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation,
@@ -600,8 +600,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='mstore' PACKAGE_NAME='mstore'
PACKAGE_TARNAME='mstore' PACKAGE_TARNAME='mstore'
PACKAGE_VERSION='0.2.3' PACKAGE_VERSION='0.2.4'
PACKAGE_STRING='mstore 0.2.3' PACKAGE_STRING='mstore 0.2.4'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
PACKAGE_URL='' PACKAGE_URL=''
@@ -1278,7 +1278,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
'configure' configures mstore 0.2.3 to adapt to many kinds of systems. 'configure' configures mstore 0.2.4 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1349,7 +1349,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of mstore 0.2.3:";; short | recursive ) echo "Configuration of mstore 0.2.4:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1436,7 +1436,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
mstore configure 0.2.3 mstore configure 0.2.4
generated by GNU Autoconf 2.72 generated by GNU Autoconf 2.72
Copyright (C) 2023 Free Software Foundation, Inc. Copyright (C) 2023 Free Software Foundation, Inc.
@@ -1473,7 +1473,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by mstore $as_me 0.2.3, which was It was created by mstore $as_me 0.2.4, which was
generated by GNU Autoconf 2.72. Invocation command line was generated by GNU Autoconf 2.72. Invocation command line was
$ $0$ac_configure_args_raw $ $0$ac_configure_args_raw
@@ -2612,7 +2612,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='mstore' PACKAGE='mstore'
VERSION='0.2.3' VERSION='0.2.4'
printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -4448,7 +4448,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by mstore $as_me 0.2.3, which was This file was extended by mstore $as_me 0.2.4, which was
generated by GNU Autoconf 2.72. Invocation command line was generated by GNU Autoconf 2.72. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -4503,7 +4503,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped' ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\ ac_cs_version="\\
mstore config.status 0.2.3 mstore config.status 0.2.4
configured by $0, generated by GNU Autoconf 2.72, configured by $0, generated by GNU Autoconf 2.72,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"