feat(ansible): support wait_for sleep
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
56d532885d
commit
b91ad5d485
2 changed files with 58 additions and 7 deletions
19
modules.go
19
modules.go
|
|
@ -2888,7 +2888,12 @@ func (e *Executor) moduleWaitFor(ctx context.Context, client sshExecutorClient,
|
|||
searchRegex := getStringArg(args, "search_regex", "")
|
||||
timeoutMsg := getStringArg(args, "msg", "wait_for timed out")
|
||||
delay := getIntArg(args, "delay", 0)
|
||||
sleep := getIntArg(args, "sleep", 1)
|
||||
timeout := getIntArg(args, "timeout", 300)
|
||||
pollInterval := time.Duration(sleep) * time.Second
|
||||
if pollInterval <= 0 {
|
||||
pollInterval = 250 * time.Millisecond
|
||||
}
|
||||
var compiledRegex *regexp.Regexp
|
||||
if searchRegex != "" {
|
||||
var err error
|
||||
|
|
@ -2910,7 +2915,7 @@ func (e *Executor) moduleWaitFor(ctx context.Context, client sshExecutorClient,
|
|||
|
||||
if path != "" {
|
||||
deadline := time.NewTimer(time.Duration(timeout) * time.Second)
|
||||
ticker := time.NewTicker(250 * time.Millisecond)
|
||||
ticker := time.NewTicker(pollInterval)
|
||||
defer deadline.Stop()
|
||||
defer ticker.Stop()
|
||||
|
||||
|
|
@ -2958,24 +2963,24 @@ func (e *Executor) moduleWaitFor(ctx context.Context, client sshExecutorClient,
|
|||
if port > 0 {
|
||||
switch state {
|
||||
case "started", "present":
|
||||
cmd := sprintf("timeout %d bash -c 'until nc -z %s %d; do sleep 1; done'",
|
||||
timeout, host, port)
|
||||
cmd := sprintf("timeout %d bash -c 'until nc -z %s %d; do sleep %d; done'",
|
||||
timeout, host, port, sleep)
|
||||
stdout, stderr, rc, err := client.Run(ctx, cmd)
|
||||
if err != nil || rc != 0 {
|
||||
return &TaskResult{Failed: true, Msg: stderr, Stdout: stdout, RC: rc}, nil
|
||||
}
|
||||
return &TaskResult{Changed: false}, nil
|
||||
case "stopped", "absent":
|
||||
cmd := sprintf("timeout %d bash -c 'until ! nc -z %s %d; do sleep 1; done'",
|
||||
timeout, host, port)
|
||||
cmd := sprintf("timeout %d bash -c 'until ! nc -z %s %d; do sleep %d; done'",
|
||||
timeout, host, port, sleep)
|
||||
stdout, stderr, rc, err := client.Run(ctx, cmd)
|
||||
if err != nil || rc != 0 {
|
||||
return &TaskResult{Failed: true, Msg: stderr, Stdout: stdout, RC: rc}, nil
|
||||
}
|
||||
return &TaskResult{Changed: false}, nil
|
||||
case "drained":
|
||||
cmd := sprintf("timeout %d bash -c 'until ! ss -Htan state established \"( sport = :%d or dport = :%d )\" | grep -q .; do sleep 1; done'",
|
||||
timeout, port, port)
|
||||
cmd := sprintf("timeout %d bash -c 'until ! ss -Htan state established \"( sport = :%d or dport = :%d )\" | grep -q .; do sleep %d; done'",
|
||||
timeout, port, port, sleep)
|
||||
stdout, stderr, rc, err := client.Run(ctx, cmd)
|
||||
if err != nil || rc != 0 {
|
||||
return &TaskResult{Failed: true, Msg: stderr, Stdout: stdout, RC: rc}, nil
|
||||
|
|
|
|||
|
|
@ -1246,6 +1246,52 @@ func TestModulesAdv_ModuleWaitFor_Good_WaitsForPortDrained(t *testing.T) {
|
|||
assert.True(t, mock.hasExecuted(`ss -Htan state established`))
|
||||
}
|
||||
|
||||
func TestModulesAdv_ModuleWaitFor_Good_UsesCustomSleepInterval(t *testing.T) {
|
||||
e, mock := newTestExecutorWithMock("host1")
|
||||
mock.addFile("/tmp/slow-ready", []byte("ready=false\n"))
|
||||
|
||||
go func() {
|
||||
time.Sleep(150 * time.Millisecond)
|
||||
mock.mu.Lock()
|
||||
mock.files["/tmp/slow-ready"] = []byte("ready=true\n")
|
||||
mock.mu.Unlock()
|
||||
}()
|
||||
|
||||
start := time.Now()
|
||||
result, err := e.moduleWaitFor(context.Background(), mock, map[string]any{
|
||||
"path": "/tmp/slow-ready",
|
||||
"search_regex": "ready=true",
|
||||
"sleep": 2,
|
||||
"timeout": 3,
|
||||
})
|
||||
elapsed := time.Since(start)
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, result)
|
||||
assert.False(t, result.Failed)
|
||||
assert.False(t, result.Changed)
|
||||
assert.GreaterOrEqual(t, elapsed, 2*time.Second)
|
||||
}
|
||||
|
||||
func TestModulesAdv_ModuleWaitFor_Good_UsesCustomSleepInPortLoop(t *testing.T) {
|
||||
e, mock := newTestExecutorWithMock("host1")
|
||||
mock.expectCommand(`timeout 5 bash -c 'until nc -z 127.0.0.1 8080; do sleep 3; done'`, "", "", 0)
|
||||
|
||||
result, err := e.moduleWaitFor(context.Background(), mock, map[string]any{
|
||||
"host": "127.0.0.1",
|
||||
"port": 8080,
|
||||
"state": "started",
|
||||
"timeout": 5,
|
||||
"sleep": 3,
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, result)
|
||||
assert.False(t, result.Failed)
|
||||
assert.False(t, result.Changed)
|
||||
assert.True(t, mock.hasExecuted(`sleep 3`))
|
||||
}
|
||||
|
||||
func TestModulesAdv_ModuleWaitFor_Good_AcceptsStringNumericArgs(t *testing.T) {
|
||||
e, mock := newTestExecutorWithMock("host1")
|
||||
mock.expectCommand(`timeout 0 bash -c 'until ! nc -z 127.0.0.1 8080; do sleep 1; done'`, "", "", 0)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue