wip: using pflag and viper; remove go routine for exec file search

This commit is contained in:
2024-03-21 11:26:11 +11:00
parent a1d0360d46
commit 6032b6c0c1
9 changed files with 100 additions and 606 deletions

View File

@@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"strings"
"sync"
"gitea.suyono.dev/suyono/wingmate"
"github.com/spf13/viper"
@@ -13,7 +14,7 @@ import (
const (
EnvPrefix = "WINGMATE"
EnvConfigPath = "CONFIG_PATH"
ConfigPath = "config_path"
DefaultConfigPath = "/etc/wingmate"
ServiceDirName = "service"
CrontabFileName = "crontab"
@@ -21,8 +22,15 @@ const (
WingmateConfigFileFormat = "yaml"
WingmateVersion = "APP_VERSION"
PidProxyPathConfig = "pidproxy_path"
PidProxyPathDefault = "wmpidproxy"
ExecPathConfig = "exec_path"
ExecPathDefault = "wmexec"
versionTrimRightCutSet = "\r\n "
VersionFlag = "version"
WMPidProxyPathFlag = "pid-proxy"
WMExecPathFlag = "exec"
ConfigPathFlag = "config"
VersionCheckKey = "check-version"
)
type Config struct {
@@ -30,7 +38,7 @@ type Config struct {
CronV0 []*Cron
Service []ServiceTask
Cron []CronTask
FindUtils *FindUtils
viperMtx *sync.Mutex
}
type Task struct {
@@ -75,10 +83,14 @@ func SetVersion(version string) {
func Read() (*Config, error) {
viper.SetEnvPrefix(EnvPrefix)
viper.BindEnv(EnvConfigPath)
viper.BindEnv(PidProxyPathConfig)
viper.BindEnv(ExecPathConfig)
viper.SetDefault(EnvConfigPath, DefaultConfigPath)
_ = viper.BindEnv(ConfigPath)
_ = viper.BindEnv(PidProxyPathConfig)
_ = viper.BindEnv(ExecPathConfig)
viper.SetDefault(ConfigPath, DefaultConfigPath)
viper.SetDefault(PidProxyPathConfig, PidProxyPathDefault)
viper.SetDefault(ExecPathConfig, ExecPathDefault)
ParseFlags()
var (
dirent []os.DirEntry
@@ -91,17 +103,20 @@ func Read() (*Config, error) {
crontabfile string
services []ServiceTask
crones []CronTask
findUtils *FindUtils
)
serviceAvailable = false
cronAvailable = false
outConfig := &Config{
viperMtx: &sync.Mutex{},
ServiceV0: make([]string, 0),
}
configPath := viper.GetString(EnvConfigPath)
configPath := viper.GetString(ConfigPath)
svcdir = filepath.Join(configPath, ServiceDirName)
dirent, err = os.ReadDir(svcdir)
if err != nil {
wingmate.Log().Error().Msgf("encounter error when reading service directory %s: %+v", svcdir, err)
}
if len(dirent) > 0 {
for _, d := range dirent {
if d.Type().IsRegular() {
@@ -109,13 +124,12 @@ func Read() (*Config, error) {
if err = unix.Access(svcPath, unix.X_OK); err == nil {
serviceAvailable = true
outConfig.ServiceV0 = append(outConfig.ServiceV0, svcPath)
} else {
wingmate.Log().Error().Msgf("checking executable access for %s: %+v", svcPath, err)
}
}
}
}
if err != nil {
wingmate.Log().Error().Msgf("encounter error when reading service directory %s: %+v", svcdir, err)
}
crontabfile = filepath.Join(configPath, CrontabFileName)
cron, err = readCrontab(crontabfile)
@@ -128,12 +142,9 @@ func Read() (*Config, error) {
}
wingmateConfigAvailable = false
if services, crones, findUtils, err = readConfigYaml(configPath, WingmateConfigFileName, WingmateConfigFileFormat); err != nil {
if services, crones, err = readConfigYaml(configPath, WingmateConfigFileName, WingmateConfigFileFormat); err != nil {
wingmate.Log().Error().Msgf("encounter error when reading wingmate config file in %s/%s: %+v", configPath, WingmateConfigFileName, err)
}
if err == nil {
outConfig.FindUtils = findUtils
}
if len(services) > 0 {
outConfig.Service = services
wingmateConfigAvailable = true

View File

@@ -23,7 +23,7 @@ func setup(t *testing.T) {
if configDir, err = os.MkdirTemp("", "wingmate-*-test"); err != nil {
t.Fatal("setup", err)
}
viper.Set(EnvConfigPath, configDir)
viper.Set(ConfigPath, configDir)
}
func tear(t *testing.T) {

20
config/flags.go Normal file
View File

@@ -0,0 +1,20 @@
package config
import (
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
func ParseFlags() {
pflag.BoolP(VersionFlag, "v", false, "check version")
pflag.String(WMPidProxyPathFlag, "", "wmpidproxy path")
pflag.String(WMExecPathFlag, "", "wmexec path")
pflag.StringP(ConfigPathFlag, "c", "", "config path")
pflag.Parse()
_ = viper.BindPFlag(VersionCheckKey, pflag.CommandLine.Lookup(VersionFlag))
_ = viper.BindPFlag(ConfigPath, pflag.CommandLine.Lookup(ConfigPathFlag))
_ = viper.BindPFlag(PidProxyPathConfig, pflag.CommandLine.Lookup(WMPidProxyPathFlag))
_ = viper.BindPFlag(ExecPathConfig, pflag.CommandLine.Lookup(WMExecPathFlag))
}

View File

@@ -1,83 +1,10 @@
package config
import (
"fmt"
"github.com/spf13/viper"
"os/exec"
"strings"
)
type pathResult struct {
path string
err error
}
type FindUtils struct {
exec chan pathResult
pidProxy chan pathResult
}
const (
PidProxyBinaryName = "wmpidproxy"
ExecBinaryName = "wmexec"
)
func findExec(currentVersion string, path string, resultChan chan<- pathResult) {
var (
result pathResult
execVersion string
)
defer close(resultChan)
if len(path) > 0 {
result.path = path
execVersion, result.err = getVersion(result.path)
} else {
result.path, result.err = exec.LookPath(ExecBinaryName)
if result.err != nil {
resultChan <- result
return
}
execVersion, result.err = getVersion(result.path)
}
if result.err == nil {
if execVersion != currentVersion {
result.err = fmt.Errorf("incompatible version: wingmate %s and wmexec %s", currentVersion, execVersion)
}
}
resultChan <- result
}
func findPidProxy(currentVersion string, path string, resultChan chan<- pathResult) {
var (
result pathResult
pidProxyVersion string
)
defer close(resultChan)
if len(path) > 0 {
result.path = path
pidProxyVersion, result.err = getVersion(result.path)
} else {
result.path, result.err = exec.LookPath(PidProxyBinaryName)
if result.err != nil {
resultChan <- result
return
}
pidProxyVersion, result.err = getVersion(result.path)
}
if result.err == nil {
if pidProxyVersion != currentVersion {
result.err = fmt.Errorf("incompatible version: wingmate %s and wmpidproxy %s", currentVersion, pidProxyVersion)
}
}
resultChan <- result
}
func getVersion(binPath string) (string, error) {
var (
outBytes []byte
@@ -94,31 +21,3 @@ func getVersion(binPath string) (string, error) {
output = strings.TrimRight(output, versionTrimRightCutSet)
return output, nil
}
func startFindUtils() *FindUtils {
result := &FindUtils{
exec: make(chan pathResult),
pidProxy: make(chan pathResult),
}
var (
pidProxyPath string
execPath string
)
currentVersion := viper.GetString(WingmateVersion)
if viper.IsSet(PidProxyPathConfig) {
pidProxyPath = viper.GetString(PidProxyPathConfig)
}
if viper.IsSet(ExecPathConfig) {
execPath = viper.GetString(ExecPathConfig)
}
go findPidProxy(currentVersion, pidProxyPath, result.pidProxy)
go findExec(currentVersion, execPath, result.exec)
return result
}
//func (f *FindUtils) Get

View File

@@ -24,7 +24,7 @@ var (
crontabScheduleRegex = regexp.MustCompile(CrontabScheduleRegexPattern)
)
func readConfigYaml(path, name, format string) ([]ServiceTask, []CronTask, *FindUtils, error) {
func readConfigYaml(path, name, format string) ([]ServiceTask, []CronTask, error) {
var (
err error
nameMap map[string]any
@@ -34,7 +34,7 @@ func readConfigYaml(path, name, format string) ([]ServiceTask, []CronTask, *Find
item any
services []ServiceTask
crones []CronTask
findUtils *FindUtils
//findUtils *FindUtils
)
viper.AddConfigPath(path)
@@ -42,10 +42,9 @@ func readConfigYaml(path, name, format string) ([]ServiceTask, []CronTask, *Find
viper.SetConfigName(name)
if err = viper.ReadInConfig(); err != nil {
return nil, nil, nil, fmt.Errorf("reading config in dir %s, file %s, format %s: %w", path, name, format, err)
return nil, nil, fmt.Errorf("reading config in dir %s, file %s, format %s: %w", path, name, format, err)
}
findUtils = startFindUtils()
services = make([]ServiceTask, 0)
nameMap = viper.GetStringMap(ServiceConfigGroup)
for itemName, item = range nameMap {
@@ -74,7 +73,7 @@ func readConfigYaml(path, name, format string) ([]ServiceTask, []CronTask, *Find
crones = append(crones, cronTask)
}
return services, crones, findUtils, nil
return services, crones, nil
}
func parseYamlSchedule(input string) (schedule CronSchedule, err error) {