wip: feat(FindUtils): find wmexec and wmpidproxy + get version

This commit is contained in:
Suyono 2024-01-25 19:40:50 +11:00
parent 2c9bc8b56d
commit a1d0360d46
5 changed files with 149 additions and 5 deletions

View File

@ -21,6 +21,7 @@ func main() {
)
_ = wingmate.NewLog(os.Stderr)
config.SetVersion(version)
if cfg, err = config.Read(); err != nil {
wingmate.Log().Error().Msgf("failed to read config %#v", err)
}

View File

@ -4,6 +4,7 @@ import (
"errors"
"os"
"path/filepath"
"strings"
"gitea.suyono.dev/suyono/wingmate"
"github.com/spf13/viper"
@ -18,6 +19,10 @@ const (
CrontabFileName = "crontab"
WingmateConfigFileName = "wingmate"
WingmateConfigFileFormat = "yaml"
WingmateVersion = "APP_VERSION"
PidProxyPathConfig = "pidproxy_path"
ExecPathConfig = "exec_path"
versionTrimRightCutSet = "\r\n "
)
type Config struct {
@ -25,6 +30,7 @@ type Config struct {
CronV0 []*Cron
Service []ServiceTask
Cron []CronTask
FindUtils *FindUtils
}
type Task struct {
@ -61,9 +67,17 @@ type CronSchedule struct {
DoW CronTimeSpec
}
func SetVersion(version string) {
version = strings.TrimRight(version, versionTrimRightCutSet)
viper.Set(WingmateVersion, version)
wingmate.Log().Info().Msgf("starting wingmate version %s", version)
}
func Read() (*Config, error) {
viper.SetEnvPrefix(EnvPrefix)
viper.BindEnv(EnvConfigPath)
viper.BindEnv(PidProxyPathConfig)
viper.BindEnv(ExecPathConfig)
viper.SetDefault(EnvConfigPath, DefaultConfigPath)
var (
@ -77,6 +91,7 @@ func Read() (*Config, error) {
crontabfile string
services []ServiceTask
crones []CronTask
findUtils *FindUtils
)
serviceAvailable = false
@ -113,9 +128,12 @@ func Read() (*Config, error) {
}
wingmateConfigAvailable = false
if services, crones, err = readConfigYaml(configPath, WingmateConfigFileName, WingmateConfigFileFormat); err != nil {
if services, crones, findUtils, 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

@ -1 +1,124 @@
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
err error
output string
)
cmd := exec.Command(binPath, "version")
outBytes, err = cmd.Output()
if err != nil {
return "", err
}
output = string(outBytes)
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, error) {
func readConfigYaml(path, name, format string) ([]ServiceTask, []CronTask, *FindUtils, error) {
var (
err error
nameMap map[string]any
@ -34,6 +34,7 @@ func readConfigYaml(path, name, format string) ([]ServiceTask, []CronTask, error
item any
services []ServiceTask
crones []CronTask
findUtils *FindUtils
)
viper.AddConfigPath(path)
@ -41,9 +42,10 @@ func readConfigYaml(path, name, format string) ([]ServiceTask, []CronTask, error
viper.SetConfigName(name)
if err = viper.ReadInConfig(); err != nil {
return nil, nil, fmt.Errorf("reading config in dir %s, file %s, format %s: %w", path, name, format, err)
return nil, 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 {
@ -72,7 +74,7 @@ func readConfigYaml(path, name, format string) ([]ServiceTask, []CronTask, error
crones = append(crones, cronTask)
}
return services, crones, nil
return services, crones, findUtils, nil
}
func parseYamlSchedule(input string) (schedule CronSchedule, err error) {

View File

@ -14,7 +14,7 @@ const (
serviceTag = "service"
)
func (i *Init) service(wg *sync.WaitGroup, task Task, exitFlag <-chan any) {
func (i *Init) service(wg *sync.WaitGroup, task ServiceTask, exitFlag <-chan any) {
defer wg.Done()
var (