Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
et-nik committed Nov 20, 2021
2 parents f908d7f + c8f5bbe commit 7c71991
Show file tree
Hide file tree
Showing 23 changed files with 196 additions and 88 deletions.
3 changes: 3 additions & 0 deletions config/gameap-daemon.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@ drives_list=/ /home/servers

stats_update_period=60
stats_db_update_period=300

#output_log=/var/log/gameap-daemon/output.log
log_level=debug
3 changes: 2 additions & 1 deletion config/gameap-daemon.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ drives_list:
stats_update_period: 60
stats_db_update_period: 300

log_level: trace
#output_log: /var/log/gameap-daemon/output.log
log_level: debug
27 changes: 18 additions & 9 deletions internal/app/components/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ import (
var ErrEmptyCommand = errors.New("empty command")

type ExecutorOptions struct {
WorkDir string
UID string
GID string
Env map[string]string
WorkDir string
FallbackWorkDir string
UID string
GID string
Env map[string]string
}

type Executor struct {
Expand Down Expand Up @@ -83,12 +84,20 @@ func ExecWithWriter(ctx context.Context, command string, out io.Writer, options
return -1, err
}

_, err = os.Stat(options.WorkDir)
if err != nil {
return -1, errors.Wrap(err, "invalid work directory")
workDir := options.WorkDir
_, err = os.Stat(workDir)
if err != nil && options.FallbackWorkDir == "" {
return -1, errors.Wrapf(err, "invalid work directory %s", workDir)
} else if err != nil && options.FallbackWorkDir != "" {
_, err = os.Stat(options.FallbackWorkDir)
if err != nil {
return -1, errors.Wrapf(err, "invalid fallback work directory %s", options.FallbackWorkDir)
}

workDir = options.FallbackWorkDir
}

_, err = os.Stat(path.Clean(options.WorkDir + "/" + args[0]))
_, err = os.Stat(path.Clean(workDir + "/" + args[0]))
if err != nil && errors.Is(err, os.ErrNotExist) {
_, err = exec.LookPath(args[0])
if err != nil {
Expand All @@ -99,7 +108,7 @@ func ExecWithWriter(ctx context.Context, command string, out io.Writer, options
}

cmd := exec.CommandContext(ctx, args[0], args[1:]...) //nolint:gosec
cmd.Dir = options.WorkDir
cmd.Dir = workDir
cmd.Stdout = out
cmd.Stderr = out

Expand Down
13 changes: 11 additions & 2 deletions internal/app/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ type Config struct {
Path7zip string `yaml:"path_7zip"`
PathStarter string `yaml:"path_starter"`

WorkPath string `yaml:"work_path"`
SteamCMDPath string `yaml:"steamcmd_path"`
WorkPath string `yaml:"work_path"`
ScriptsWorkPath string `yaml:"scripts_work_path"`
SteamCMDPath string `yaml:"steamcmd_path"`

SteamConfig SteamConfig `yaml:"steam_config"`

Expand Down Expand Up @@ -107,3 +108,11 @@ func (cfg *Config) Validate() error {

return nil
}

func (cfg *Config) ScriptsWorkDir() string {
return cfg.ScriptsWorkPath
}

func (cfg *Config) WorkDir() string {
return cfg.WorkPath
}
5 changes: 5 additions & 0 deletions internal/app/config/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ func loadIni(path string) (*Config, error) {
cfg.DHFile = c.Section("").Key("dh_file").String()

cfg.LogLevel = c.Section("").Key("log_level").MustString("debug")
cfg.OutputLog = c.Section("").Key("output_log").MustString("")

cfg.ScriptsWorkPath = c.Section("").
Key("scripts_work_path").
MustString("")

cfg.Path7zip = c.Section("").
Key("7zip_path").
Expand Down
35 changes: 26 additions & 9 deletions internal/app/config/nodeConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ type nodeInitial struct {

//nolint:funlen
func (ncu *NodeConfigInitializer) Initialize(ctx context.Context, cfg *Config) error {
ncu.initDefault(cfg)

resp, err := ncu.client.Request(ctx, domain.APIRequest{
Method: http.MethodGet,
URL: "gdaemon_api/dedicated_servers/get_init_data/{id}",
Expand Down Expand Up @@ -104,7 +102,7 @@ func (ncu *NodeConfigInitializer) Initialize(ctx context.Context, cfg *Config) e
cfg.Scripts.Restart = initial.ScriptRestart
}

if cfg.Scripts.Start == "" {
if cfg.Scripts.Status == "" {
cfg.Scripts.Status = initial.ScriptStatus
}

Expand All @@ -120,14 +118,33 @@ func (ncu *NodeConfigInitializer) Initialize(ctx context.Context, cfg *Config) e
cfg.Scripts.Delete = initial.ScriptDelete
}

ncu.initDefault(cfg)

return nil
}

func (ncu *NodeConfigInitializer) initDefault(cfg *Config) {
cfg.Scripts.Start = DefaultGameServerScriptStart
cfg.Scripts.Stop = DefaultGameServerScriptStop
cfg.Scripts.Restart = DefaultGameServerScriptRestart
cfg.Scripts.Status = DefaultGameServerScriptStatus
cfg.Scripts.GetConsole = DefaultGameServerScriptGetOutput
cfg.Scripts.SendCommand = DefaultGameServerScriptSendInput
if cfg.Scripts.Start == "" {
cfg.Scripts.Start = DefaultGameServerScriptStart
}

if cfg.Scripts.Stop == "" {
cfg.Scripts.Stop = DefaultGameServerScriptStop
}

if cfg.Scripts.Restart == "" {
cfg.Scripts.Restart = DefaultGameServerScriptRestart
}

if cfg.Scripts.Status == "" {
cfg.Scripts.Status = DefaultGameServerScriptStatus
}

if cfg.Scripts.GetConsole == "" {
cfg.Scripts.GetConsole = DefaultGameServerScriptGetOutput
}

if cfg.Scripts.SendCommand == "" {
cfg.Scripts.SendCommand = DefaultGameServerScriptSendInput
}
}
30 changes: 30 additions & 0 deletions internal/app/domain/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package domain

import (
"strconv"
"strings"
)

type ErrInvalidResponseFromAPI struct {
code int
body []byte
}

func NewErrInvalidResponseFromAPI(code int, response []byte) ErrInvalidResponseFromAPI {
return ErrInvalidResponseFromAPI{
code: code,
body: response,
}
}

func (err ErrInvalidResponseFromAPI) Error() string {
builder := strings.Builder{}

builder.WriteString("invalid response from api server: ")
builder.WriteString("(")
builder.WriteString(strconv.Itoa(err.code))
builder.WriteString(") ")
builder.Write(err.body)

return builder.String()
}
9 changes: 9 additions & 0 deletions internal/app/domain/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package domain

import (
"context"
"path"
"strings"
"time"
)
Expand All @@ -18,6 +19,10 @@ const autostartSettingKey = "autostart"
const autostartCurrentSettingKey = "autostart_current"
const updateBeforeStartSettingKey = "update_before_start"

type workDirReader interface {
WorkDir() string
}

type ServerRepository interface {
IDs(ctx context.Context) ([]int, error)
FindByID(ctx context.Context, id int) (*Server, error)
Expand Down Expand Up @@ -184,6 +189,10 @@ func (s *Server) Dir() string {
return s.dir
}

func (s *Server) WorkDir(cfg workDirReader) string {
return path.Clean(cfg.WorkDir() + "/" + s.dir)
}

func (s *Server) StartCommand() string {
return s.startCommand
}
Expand Down
7 changes: 1 addition & 6 deletions internal/app/game_server_commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package gameservercommands
import (
"context"
"io"
"path"
"strconv"
"strings"

Expand Down Expand Up @@ -98,10 +97,6 @@ func (factory *ServerCommandFactory) LoadServerCommandFunc(cmd ServerCommand) in
return nil
}

func makeFullServerPath(cfg *config.Config, serverDir string) string {
return path.Clean(cfg.WorkPath + "/" + serverDir)
}

func makeFullCommand(
cfg *config.Config,
server *domain.Server,
Expand All @@ -116,7 +111,7 @@ func makeFullCommand(
func replaceShortCodes(commandTemplate string, cfg *config.Config, server *domain.Server) string {
command := commandTemplate

command = strings.ReplaceAll(command, "{dir}", makeFullServerPath(cfg, server.Dir()))
command = strings.ReplaceAll(command, "{dir}", server.WorkDir(cfg))
command = strings.ReplaceAll(command, "{uuid}", server.UUID())
command = strings.ReplaceAll(command, "{uuid_short}", server.UUIDShort())
command = strings.ReplaceAll(command, "{id}", strconv.Itoa(server.ID()))
Expand Down
22 changes: 18 additions & 4 deletions internal/app/game_server_commands/delete_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import (
"github.com/gameap/daemon/internal/app/config"
"github.com/gameap/daemon/internal/app/domain"
"github.com/gameap/daemon/internal/app/interfaces"
"github.com/pkg/errors"
)

var errForbiddenWorkDirectoryPath = errors.New("forbidden game server work directory path")

type deleteServer struct {
baseCommand
bufCommand
Expand Down Expand Up @@ -40,13 +43,12 @@ func (cmd *deleteServer) Execute(ctx context.Context, server *domain.Server) err
}

func (cmd *deleteServer) removeByScript(ctx context.Context, server *domain.Server) error {
path := makeFullServerPath(cmd.cfg, server.Dir())

command := makeFullCommand(cmd.cfg, server, cmd.cfg.Scripts.Status, "")

var err error
cmd.result, err = cmd.executor.ExecWithWriter(ctx, command, cmd.output, components.ExecutorOptions{
WorkDir: path,
WorkDir: server.WorkDir(cmd.cfg),
FallbackWorkDir: cmd.cfg.WorkDir(),
})

if err != nil {
Expand All @@ -59,7 +61,11 @@ func (cmd *deleteServer) removeByScript(ctx context.Context, server *domain.Serv
}

func (cmd *deleteServer) removeByFilesystem(_ context.Context, server *domain.Server) error {
path := makeFullServerPath(cmd.cfg, server.Dir())
path := server.WorkDir(cmd.cfg)

if cmd.isWorkDirForbiddenToRemove(path) {
return errForbiddenWorkDirectoryPath
}

err := os.RemoveAll(path)
if err != nil {
Expand All @@ -70,3 +76,11 @@ func (cmd *deleteServer) removeByFilesystem(_ context.Context, server *domain.Se

return nil
}

func (cmd *deleteServer) isWorkDirForbiddenToRemove(path string) bool {
if path == cmd.cfg.WorkPath || path == cmd.cfg.SteamCMDPath || path == "/" {
return true
}

return false
}
4 changes: 2 additions & 2 deletions internal/app/game_server_commands/install_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ func (in *installator) Install(ctx context.Context, server *domain.Server, rules
}

func (in *installator) install(ctx context.Context, server *domain.Server, rule installationRule) error {
dst := makeFullServerPath(in.cfg, server.Dir())
dst := server.WorkDir(in.cfg)

var err error
switch rule.Action {
Expand Down Expand Up @@ -485,7 +485,7 @@ func (in *installator) makeSteamCMDCommand(appID string, server *domain.Server)
}

execCmd.WriteString(" +force_install_dir \"")
execCmd.WriteString(makeFullServerPath(in.cfg, server.Dir()))
execCmd.WriteString(server.WorkDir(in.cfg))
execCmd.WriteString("\"")

execCmd.WriteString(" +app_update ")
Expand Down
4 changes: 2 additions & 2 deletions internal/app/game_server_commands/restart_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ func (s *restartServer) Execute(ctx context.Context, server *domain.Server) erro
}

command := makeFullCommand(s.cfg, server, s.cfg.Scripts.Restart, server.StartCommand())
path := makeFullServerPath(s.cfg, server.Dir())

var err error
s.result, err = s.executor.ExecWithWriter(ctx, command, s.output, components.ExecutorOptions{
WorkDir: path,
WorkDir: server.WorkDir(s.cfg),
FallbackWorkDir: s.cfg.WorkDir(),
})
s.complete = true
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/app/game_server_commands/start_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ func newStartServer(cfg *config.Config, executor interfaces.Executor, update *in

func (s *startServer) Execute(ctx context.Context, server *domain.Server) error {
command := makeFullCommand(s.cfg, server, s.cfg.Scripts.Start, server.StartCommand())
path := makeFullServerPath(s.cfg, server.Dir())

var err error

Expand All @@ -47,7 +46,8 @@ func (s *startServer) Execute(ctx context.Context, server *domain.Server) error
}

s.result, err = s.executor.ExecWithWriter(ctx, command, s.startOutput, components.ExecutorOptions{
WorkDir: path,
WorkDir: server.WorkDir(s.cfg),
FallbackWorkDir: s.cfg.WorkPath,
})
s.complete = true
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/app/game_server_commands/status_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ func newStatusServer(cfg *config.Config, executor interfaces.Executor) *statusSe

func (s *statusServer) Execute(ctx context.Context, server *domain.Server) error {
command := makeFullCommand(s.cfg, server, s.cfg.Scripts.Status, "")
path := makeFullServerPath(s.cfg, server.Dir())

var err error
s.result, err = s.executor.ExecWithWriter(ctx, command, s.output, components.ExecutorOptions{
WorkDir: path,
WorkDir: server.WorkDir(s.cfg),
FallbackWorkDir: s.cfg.WorkPath,
})
s.complete = true
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/app/game_server_commands/stop_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ func newStopServer(cfg *config.Config, executor interfaces.Executor) *stopServer

func (s *stopServer) Execute(ctx context.Context, server *domain.Server) error {
command := makeFullCommand(s.cfg, server, s.cfg.Scripts.Stop, server.StopCommand())
path := makeFullServerPath(s.cfg, server.Dir())

server.AffectStop()

var err error
s.result, err = s.executor.ExecWithWriter(ctx, command, s.output, components.ExecutorOptions{
WorkDir: path,
WorkDir: server.WorkDir(s.cfg),
FallbackWorkDir: s.cfg.WorkDir(),
})
s.complete = true
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions internal/app/interfaces/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@ type GameProcessController interface {
GetOutput(ctx context.Context, server *domain.Server) (int, error)
SendInput(ctx context.Context, server *domain.Server) (int, error)
}

type DomainPrimitiveValidator interface {
Validate() error
}
Loading

0 comments on commit 7c71991

Please sign in to comment.