fix(splitargs): wrong code, check should be outside of loop

feat(config): added WMPidProxyCheckVersion and WMExecCheckVersion to the interface; mutex for accessing viper
fixed(docker/bookworm-newconfig): golang version and config path
feat(UtilDepCheck): added utility dependency check before running the task
This commit is contained in:
2024-03-27 23:04:30 +11:00
parent a63646aab2
commit 7db6f6f8f3
13 changed files with 295 additions and 40 deletions

View File

@@ -1,6 +1,10 @@
package task
import (
"crypto/sha256"
"encoding/json"
"fmt"
"gitea.suyono.dev/suyono/wingmate"
"time"
wminit "gitea.suyono.dev/suyono/wingmate/init"
@@ -70,14 +74,16 @@ func (cms *CronMultiOccurrenceSpec) Match(u uint8) bool {
type CronTask struct {
CronSchedule
userGroup
name string
command []string
environ []string
setsid bool
workingDir string
lastRun time.Time
hasRun bool //NOTE: make sure initialised as false
config config
cronScheduleString string
name string
command []string
cmdLine []string
environ []string
setsid bool
workingDir string
lastRun time.Time
hasRun bool //NOTE: make sure initialised as false
config config
}
func NewCronTask(name string) *CronTask {
@@ -119,7 +125,8 @@ func (c *CronTask) SetGroup(group string) *CronTask {
return c
}
func (c *CronTask) SetSchedule(schedule CronSchedule) *CronTask {
func (c *CronTask) SetSchedule(scheduleStr string, schedule CronSchedule) *CronTask {
c.cronScheduleString = scheduleStr
c.CronSchedule = schedule
return c
}
@@ -129,21 +136,104 @@ func (c *CronTask) SetConfig(config config) *CronTask {
return c
}
func (c *CronTask) Equals(another *CronTask) bool {
if another == nil {
return false
}
type toCompare struct {
Name string
Command string
Arguments []string
Environ []string
Setsid bool
UserGroup string
WorkingDir string
Schedule string
}
cmpStruct := func(p *CronTask) ([]byte, error) {
s := &toCompare{
Name: c.Name(),
Command: c.Command(),
Arguments: c.Arguments(),
Environ: c.Environ(),
Setsid: c.Setsid(),
UserGroup: c.UserGroup().String(),
WorkingDir: c.WorkingDir(),
Schedule: c.cronScheduleString,
}
return json.Marshal(s)
}
var (
err error
ours, theirs []byte
ourHash, theirHash [sha256.Size]byte
)
if ours, err = cmpStruct(c); err != nil {
wingmate.Log().Error().Msgf("cron task equals: %+v", err)
return false
}
ourHash = sha256.Sum256(ours)
if theirs, err = cmpStruct(another); err != nil {
wingmate.Log().Error().Msgf("cron task equals: %+v", err)
return false
}
theirHash = sha256.Sum256(theirs)
for i := 0; i < sha256.Size; i++ {
if ourHash[i] != theirHash[i] {
return false
}
}
return true
}
func (c *CronTask) Name() string {
return c.name
}
func (c *CronTask) UtilDepCheck() error {
c.cmdLine = make([]string, 0)
if c.setsid || c.UserGroup().IsSet() {
if err := c.config.WMExecCheckVersion(); err != nil {
return fmt.Errorf("utility dependency check: %w", err)
}
c.cmdLine = append(c.cmdLine, c.config.WMExecPath())
if c.setsid {
c.cmdLine = append(c.cmdLine, "--setsid")
}
if c.UserGroup().IsSet() {
c.cmdLine = append(c.cmdLine, "--user", c.UserGroup().String())
}
c.cmdLine = append(c.cmdLine, "--")
}
c.cmdLine = append(c.cmdLine, c.command...)
return nil
}
func (c *CronTask) Command() string {
return c.command[0]
return c.cmdLine[0]
}
func (c *CronTask) Arguments() []string {
if len(c.command) == 1 {
if len(c.cmdLine) == 1 {
return nil
}
retval := make([]string, len(c.command)-1)
copy(retval, c.command[1:])
retval := make([]string, len(c.cmdLine)-1)
copy(retval, c.cmdLine[1:])
return retval
}

View File

@@ -1,14 +1,19 @@
package task
import (
"crypto/sha256"
"encoding/json"
"fmt"
"gitea.suyono.dev/suyono/wingmate"
wminit "gitea.suyono.dev/suyono/wingmate/init"
)
type config interface {
WMPidProxyPath() string
WMPidProxyCheckVersion() error
WMExecPath() string
WMExecCheckVersion() error
}
type Tasks struct {
@@ -33,7 +38,7 @@ func (ts *Tasks) AddService(serviceTask *ServiceTask) *ServiceTask {
}
func (ts *Tasks) AddV0Cron(schedule CronSchedule, path string) {
ts.AddCron(NewCronTask(path)).SetCommand(path).SetSchedule(schedule)
ts.AddCron(NewCronTask(path)).SetCommand(path).SetSchedule("", schedule)
}
func (ts *Tasks) AddCron(cronTask *CronTask) *CronTask {
@@ -138,6 +143,70 @@ func (t *ServiceTask) SetConfig(config config) *ServiceTask {
return t
}
func (t *ServiceTask) Equals(another *ServiceTask) bool {
if another == nil {
return false
}
type toCompare struct {
Name string
Command string
Arguments []string
Environ []string
Setsid bool
UserGroup string
WorkingDir string
PidFile string
StartSecs uint
AutoStart bool
AutoRestart bool
}
cmpStruct := func(p *ServiceTask) ([]byte, error) {
s := &toCompare{
Name: p.Name(),
Command: p.Command(),
Arguments: p.Arguments(),
Environ: p.Environ(),
Setsid: p.Setsid(),
UserGroup: p.UserGroup().String(),
WorkingDir: p.WorkingDir(),
PidFile: p.PidFile(),
StartSecs: p.StartSecs(),
AutoStart: p.AutoStart(),
AutoRestart: p.AutoRestart(),
}
return json.Marshal(s)
}
var (
err error
ours, theirs []byte
ourHash, theirHash [sha256.Size]byte
)
if ours, err = cmpStruct(t); err != nil {
wingmate.Log().Error().Msgf("task equals: %+v", err)
return false
}
ourHash = sha256.Sum256(ours)
if theirs, err = cmpStruct(another); err != nil {
wingmate.Log().Error().Msgf("task equals: %+v", err)
return false
}
theirHash = sha256.Sum256(theirs)
for i := 0; i < sha256.Size; i++ {
if ourHash[i] != theirHash[i] {
return false
}
}
return true
}
func (t *ServiceTask) Validate() error {
// call this function for validate the field
return validate( /* input the validators here */ )
@@ -176,19 +245,50 @@ func (t *ServiceTask) prepareCommandLine() []string {
return t.cmdLine
}
func (t *ServiceTask) UtilDepCheck() error {
t.cmdLine = make([]string, 0)
if t.background {
if err := t.config.WMPidProxyCheckVersion(); err != nil {
return fmt.Errorf("utility dependency check: %w", err)
}
t.cmdLine = append(t.cmdLine, t.config.WMPidProxyPath(), "--pid-file", t.pidFile, "--")
}
if t.setsid || t.UserGroup().IsSet() {
if err := t.config.WMExecCheckVersion(); err != nil {
return fmt.Errorf("utility dependency check: %w", err)
}
t.cmdLine = append(t.cmdLine, t.config.WMExecPath())
if t.setsid {
t.cmdLine = append(t.cmdLine, "--setsid")
}
if t.UserGroup().IsSet() {
t.cmdLine = append(t.cmdLine, "--user", t.UserGroup().String())
}
t.cmdLine = append(t.cmdLine, "--")
}
t.cmdLine = append(t.cmdLine, t.command...)
return nil
}
func (t *ServiceTask) Command() string {
cl := t.prepareCommandLine()
return cl[0]
return t.cmdLine[0]
}
func (t *ServiceTask) Arguments() []string {
cl := t.prepareCommandLine()
if len(cl) == 1 {
if len(t.cmdLine) == 1 {
return nil
}
retval := make([]string, len(cl)-1)
copy(retval, cl[1:])
retval := make([]string, len(t.cmdLine)-1)
copy(retval, t.cmdLine[1:])
return retval
}