Skip to content

Commit c090c8a

Browse files
committed
fix: fall back to the original behaviour if timeout is disabled
Signed-off-by: Oleksii Kurinnyi <[email protected]>
1 parent 732bd4e commit c090c8a

File tree

6 files changed

+56
-212
lines changed

6 files changed

+56
-212
lines changed

pkg/library/lifecycle/poststart.go

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ const (
3131
}
3232
_script_to_run
3333
} 1> >(tee -a "/tmp/poststart-stdout.txt") 2> >(tee -a "/tmp/poststart-stderr.txt" >&2)
34+
`
35+
36+
noTimeoutRedirectOutputFmt = `{
37+
%s
38+
} 1>/tmp/poststart-stdout.txt 2>/tmp/poststart-stderr.txt
3439
`
3540
)
3641

@@ -155,10 +160,9 @@ exit $exit_code
155160
// processCommandsForPostStart processes a list of DevWorkspace commands
156161
// and generates a corev1.LifecycleHandler for the PostStart lifecycle hook.
157162
func processCommandsForPostStart(commands []dw.Command, postStartTimeout *int32) (*corev1.LifecycleHandler, error) {
158-
if postStartTimeout == nil {
159-
// The 'timeout' command treats 0 as "no timeout", so it is disabled by default.
160-
defaultTimeout := int32(0)
161-
postStartTimeout = &defaultTimeout
163+
if postStartTimeout == nil || *postStartTimeout == 0 {
164+
// use the fallback if no timeout propagated
165+
return processCommandsWithoutTimeoutFallback(commands)
162166
}
163167

164168
originalUserScript, err := buildUserScript(commands)
@@ -186,3 +190,41 @@ func processCommandsForPostStart(commands []dw.Command, postStartTimeout *int32)
186190
}
187191
return handler, nil
188192
}
193+
194+
// processCommandsForPostStart builds a lifecycle handler that runs the provided command(s)
195+
// The command has the format
196+
//
197+
// exec:
198+
//
199+
// command:
200+
// - "/bin/sh"
201+
// - "-c"
202+
// - |
203+
// cd <workingDir>
204+
// <commandline>
205+
func processCommandsWithoutTimeoutFallback(commands []dw.Command) (*corev1.LifecycleHandler, error) {
206+
var dwCommands []string
207+
for _, command := range commands {
208+
execCmd := command.Exec
209+
if len(execCmd.Env) > 0 {
210+
return nil, fmt.Errorf("env vars in postStart command %s are unsupported", command.Id)
211+
}
212+
if execCmd.WorkingDir != "" {
213+
dwCommands = append(dwCommands, fmt.Sprintf("cd %s", execCmd.WorkingDir))
214+
}
215+
dwCommands = append(dwCommands, execCmd.CommandLine)
216+
}
217+
218+
joinedCommands := strings.Join(dwCommands, "\n")
219+
220+
handler := &corev1.LifecycleHandler{
221+
Exec: &corev1.ExecAction{
222+
Command: []string{
223+
"/bin/sh",
224+
"-c",
225+
fmt.Sprintf(redirectOutputFmt, joinedCommands),
226+
},
227+
},
228+
}
229+
return handler, nil
230+
}

pkg/library/lifecycle/poststart_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ func TestAddPostStartLifecycleHooks(t *testing.T) {
7575
tests := loadAllPostStartTestCasesOrPanic(t, "./testdata/postStart")
7676
for _, tt := range tests {
7777
t.Run(fmt.Sprintf("%s (%s)", tt.Name, tt.testPath), func(t *testing.T) {
78-
err := AddPostStartLifecycleHooks(tt.Input.Devfile, tt.Input.Containers, nil)
78+
var timeout int32
79+
err := AddPostStartLifecycleHooks(tt.Input.Devfile, tt.Input.Containers, &timeout)
7980
if tt.Output.ErrRegexp != nil && assert.Error(t, err) {
8081
assert.Regexp(t, *tt.Output.ErrRegexp, err.Error(), "Error message should match")
8182
} else {

pkg/library/lifecycle/testdata/postStart/adds_all_postStart_commands.yaml

Lines changed: 3 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -40,47 +40,7 @@ output:
4040
# This script block ensures its exit code is preserved
4141
# while its stdout and stderr are tee'd.
4242
_script_to_run() {
43-
44-
export POSTSTART_TIMEOUT_DURATION="0"
45-
export POSTSTART_KILL_AFTER_DURATION="5"
46-
47-
_TIMEOUT_COMMAND_PART=""
48-
_WAS_TIMEOUT_USED="false" # Use strings "true" or "false" for shell boolean
49-
50-
if command -v timeout >/dev/null 2>&1; then
51-
echo "[postStart hook] Executing commands with timeout: ${POSTSTART_TIMEOUT_DURATION} seconds, kill after: ${POSTSTART_KILL_AFTER_DURATION} seconds" >&2
52-
_TIMEOUT_COMMAND_PART="timeout --preserve-status --kill-after=${POSTSTART_KILL_AFTER_DURATION} ${POSTSTART_TIMEOUT_DURATION}"
53-
_WAS_TIMEOUT_USED="true"
54-
else
55-
echo "[postStart hook] WARNING: 'timeout' utility not found. Executing commands without timeout." >&2
56-
fi
57-
58-
# Execute the user's script
59-
${_TIMEOUT_COMMAND_PART} /bin/sh -c 'set -e
60-
echo '\''hello world 1'\'''
61-
exit_code=$?
62-
63-
# Check the exit code based on whether timeout was attempted
64-
if [ "$_WAS_TIMEOUT_USED" = "true" ]; then
65-
if [ $exit_code -eq 143 ]; then # 128 + 15 (SIGTERM)
66-
echo "[postStart hook] Commands terminated by SIGTERM (likely timed out after ${POSTSTART_TIMEOUT_DURATION}s). Exit code 143." >&2
67-
elif [ $exit_code -eq 137 ]; then # 128 + 9 (SIGKILL)
68-
echo "[postStart hook] Commands forcefully killed by SIGKILL (likely after --kill-after ${POSTSTART_KILL_AFTER_DURATION}s expired). Exit code 137." >&2
69-
elif [ $exit_code -ne 0 ]; then # Catches any other non-zero exit code
70-
echo "[postStart hook] Commands failed with exit code $exit_code." >&2
71-
else
72-
echo "[postStart hook] Commands completed successfully within the time limit." >&2
73-
fi
74-
else
75-
if [ $exit_code -ne 0 ]; then
76-
echo "[postStart hook] Commands failed with exit code $exit_code (no timeout)." >&2
77-
else
78-
echo "[postStart hook] Commands completed successfully (no timeout)." >&2
79-
fi
80-
fi
81-
82-
exit $exit_code
83-
# This will be replaced by scriptWithTimeout
43+
echo 'hello world 1' # This will be replaced by scriptWithTimeout
8444
}
8545
_script_to_run
8646
} 1> >(tee -a "/tmp/poststart-stdout.txt") 2> >(tee -a "/tmp/poststart-stderr.txt" >&2)
@@ -97,50 +57,10 @@ output:
9757
# This script block ensures its exit code is preserved
9858
# while its stdout and stderr are tee'd.
9959
_script_to_run() {
100-
101-
export POSTSTART_TIMEOUT_DURATION="0"
102-
export POSTSTART_KILL_AFTER_DURATION="5"
103-
104-
_TIMEOUT_COMMAND_PART=""
105-
_WAS_TIMEOUT_USED="false" # Use strings "true" or "false" for shell boolean
106-
107-
if command -v timeout >/dev/null 2>&1; then
108-
echo "[postStart hook] Executing commands with timeout: ${POSTSTART_TIMEOUT_DURATION} seconds, kill after: ${POSTSTART_KILL_AFTER_DURATION} seconds" >&2
109-
_TIMEOUT_COMMAND_PART="timeout --preserve-status --kill-after=${POSTSTART_KILL_AFTER_DURATION} ${POSTSTART_TIMEOUT_DURATION}"
110-
_WAS_TIMEOUT_USED="true"
111-
else
112-
echo "[postStart hook] WARNING: 'timeout' utility not found. Executing commands without timeout." >&2
113-
fi
114-
115-
# Execute the user's script
116-
${_TIMEOUT_COMMAND_PART} /bin/sh -c 'set -e
117-
cd '\''/tmp/test-dir'\'' && echo '\''hello world 2'\'''
118-
exit_code=$?
119-
120-
# Check the exit code based on whether timeout was attempted
121-
if [ "$_WAS_TIMEOUT_USED" = "true" ]; then
122-
if [ $exit_code -eq 143 ]; then # 128 + 15 (SIGTERM)
123-
echo "[postStart hook] Commands terminated by SIGTERM (likely timed out after ${POSTSTART_TIMEOUT_DURATION}s). Exit code 143." >&2
124-
elif [ $exit_code -eq 137 ]; then # 128 + 9 (SIGKILL)
125-
echo "[postStart hook] Commands forcefully killed by SIGKILL (likely after --kill-after ${POSTSTART_KILL_AFTER_DURATION}s expired). Exit code 137." >&2
126-
elif [ $exit_code -ne 0 ]; then # Catches any other non-zero exit code
127-
echo "[postStart hook] Commands failed with exit code $exit_code." >&2
128-
else
129-
echo "[postStart hook] Commands completed successfully within the time limit." >&2
130-
fi
131-
else
132-
if [ $exit_code -ne 0 ]; then
133-
echo "[postStart hook] Commands failed with exit code $exit_code (no timeout)." >&2
134-
else
135-
echo "[postStart hook] Commands completed successfully (no timeout)." >&2
136-
fi
137-
fi
138-
139-
exit $exit_code
140-
# This will be replaced by scriptWithTimeout
60+
cd /tmp/test-dir
61+
echo 'hello world 2' # This will be replaced by scriptWithTimeout
14162
}
14263
_script_to_run
14364
} 1> >(tee -a "/tmp/poststart-stdout.txt") 2> >(tee -a "/tmp/poststart-stderr.txt" >&2)
144-
14565
- name: test-component-3
14666
image: test-img

pkg/library/lifecycle/testdata/postStart/basic_postStart.yaml

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -29,47 +29,7 @@ output:
2929
# This script block ensures its exit code is preserved
3030
# while its stdout and stderr are tee'd.
3131
_script_to_run() {
32-
33-
export POSTSTART_TIMEOUT_DURATION="0"
34-
export POSTSTART_KILL_AFTER_DURATION="5"
35-
36-
_TIMEOUT_COMMAND_PART=""
37-
_WAS_TIMEOUT_USED="false" # Use strings "true" or "false" for shell boolean
38-
39-
if command -v timeout >/dev/null 2>&1; then
40-
echo "[postStart hook] Executing commands with timeout: ${POSTSTART_TIMEOUT_DURATION} seconds, kill after: ${POSTSTART_KILL_AFTER_DURATION} seconds" >&2
41-
_TIMEOUT_COMMAND_PART="timeout --preserve-status --kill-after=${POSTSTART_KILL_AFTER_DURATION} ${POSTSTART_TIMEOUT_DURATION}"
42-
_WAS_TIMEOUT_USED="true"
43-
else
44-
echo "[postStart hook] WARNING: 'timeout' utility not found. Executing commands without timeout." >&2
45-
fi
46-
47-
# Execute the user's script
48-
${_TIMEOUT_COMMAND_PART} /bin/sh -c 'set -e
49-
echo '\''hello world'\'''
50-
exit_code=$?
51-
52-
# Check the exit code based on whether timeout was attempted
53-
if [ "$_WAS_TIMEOUT_USED" = "true" ]; then
54-
if [ $exit_code -eq 143 ]; then # 128 + 15 (SIGTERM)
55-
echo "[postStart hook] Commands terminated by SIGTERM (likely timed out after ${POSTSTART_TIMEOUT_DURATION}s). Exit code 143." >&2
56-
elif [ $exit_code -eq 137 ]; then # 128 + 9 (SIGKILL)
57-
echo "[postStart hook] Commands forcefully killed by SIGKILL (likely after --kill-after ${POSTSTART_KILL_AFTER_DURATION}s expired). Exit code 137." >&2
58-
elif [ $exit_code -ne 0 ]; then # Catches any other non-zero exit code
59-
echo "[postStart hook] Commands failed with exit code $exit_code." >&2
60-
else
61-
echo "[postStart hook] Commands completed successfully within the time limit." >&2
62-
fi
63-
else
64-
if [ $exit_code -ne 0 ]; then
65-
echo "[postStart hook] Commands failed with exit code $exit_code (no timeout)." >&2
66-
else
67-
echo "[postStart hook] Commands completed successfully (no timeout)." >&2
68-
fi
69-
fi
70-
71-
exit $exit_code
72-
# This will be replaced by scriptWithTimeout
32+
echo 'hello world' # This will be replaced by scriptWithTimeout
7333
}
7434
_script_to_run
7535
} 1> >(tee -a "/tmp/poststart-stdout.txt") 2> >(tee -a "/tmp/poststart-stderr.txt" >&2)

pkg/library/lifecycle/testdata/postStart/multiple_poststart_commands.yaml

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -34,48 +34,8 @@ output:
3434
# This script block ensures its exit code is preserved
3535
# while its stdout and stderr are tee'd.
3636
_script_to_run() {
37-
38-
export POSTSTART_TIMEOUT_DURATION="0"
39-
export POSTSTART_KILL_AFTER_DURATION="5"
40-
41-
_TIMEOUT_COMMAND_PART=""
42-
_WAS_TIMEOUT_USED="false" # Use strings "true" or "false" for shell boolean
43-
44-
if command -v timeout >/dev/null 2>&1; then
45-
echo "[postStart hook] Executing commands with timeout: ${POSTSTART_TIMEOUT_DURATION} seconds, kill after: ${POSTSTART_KILL_AFTER_DURATION} seconds" >&2
46-
_TIMEOUT_COMMAND_PART="timeout --preserve-status --kill-after=${POSTSTART_KILL_AFTER_DURATION} ${POSTSTART_TIMEOUT_DURATION}"
47-
_WAS_TIMEOUT_USED="true"
48-
else
49-
echo "[postStart hook] WARNING: 'timeout' utility not found. Executing commands without timeout." >&2
50-
fi
51-
52-
# Execute the user's script
53-
${_TIMEOUT_COMMAND_PART} /bin/sh -c 'set -e
54-
echo '\''hello world 1'\''
55-
echo '\''hello world 2'\'''
56-
exit_code=$?
57-
58-
# Check the exit code based on whether timeout was attempted
59-
if [ "$_WAS_TIMEOUT_USED" = "true" ]; then
60-
if [ $exit_code -eq 143 ]; then # 128 + 15 (SIGTERM)
61-
echo "[postStart hook] Commands terminated by SIGTERM (likely timed out after ${POSTSTART_TIMEOUT_DURATION}s). Exit code 143." >&2
62-
elif [ $exit_code -eq 137 ]; then # 128 + 9 (SIGKILL)
63-
echo "[postStart hook] Commands forcefully killed by SIGKILL (likely after --kill-after ${POSTSTART_KILL_AFTER_DURATION}s expired). Exit code 137." >&2
64-
elif [ $exit_code -ne 0 ]; then # Catches any other non-zero exit code
65-
echo "[postStart hook] Commands failed with exit code $exit_code." >&2
66-
else
67-
echo "[postStart hook] Commands completed successfully within the time limit." >&2
68-
fi
69-
else
70-
if [ $exit_code -ne 0 ]; then
71-
echo "[postStart hook] Commands failed with exit code $exit_code (no timeout)." >&2
72-
else
73-
echo "[postStart hook] Commands completed successfully (no timeout)." >&2
74-
fi
75-
fi
76-
77-
exit $exit_code
78-
# This will be replaced by scriptWithTimeout
37+
echo 'hello world 1'
38+
echo 'hello world 2' # This will be replaced by scriptWithTimeout
7939
}
8040
_script_to_run
8141
} 1> >(tee -a "/tmp/poststart-stdout.txt") 2> >(tee -a "/tmp/poststart-stderr.txt" >&2)

pkg/library/lifecycle/testdata/postStart/workingDir_postStart.yaml

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -30,47 +30,8 @@ output:
3030
# This script block ensures its exit code is preserved
3131
# while its stdout and stderr are tee'd.
3232
_script_to_run() {
33-
34-
export POSTSTART_TIMEOUT_DURATION="0"
35-
export POSTSTART_KILL_AFTER_DURATION="5"
36-
37-
_TIMEOUT_COMMAND_PART=""
38-
_WAS_TIMEOUT_USED="false" # Use strings "true" or "false" for shell boolean
39-
40-
if command -v timeout >/dev/null 2>&1; then
41-
echo "[postStart hook] Executing commands with timeout: ${POSTSTART_TIMEOUT_DURATION} seconds, kill after: ${POSTSTART_KILL_AFTER_DURATION} seconds" >&2
42-
_TIMEOUT_COMMAND_PART="timeout --preserve-status --kill-after=${POSTSTART_KILL_AFTER_DURATION} ${POSTSTART_TIMEOUT_DURATION}"
43-
_WAS_TIMEOUT_USED="true"
44-
else
45-
echo "[postStart hook] WARNING: 'timeout' utility not found. Executing commands without timeout." >&2
46-
fi
47-
48-
# Execute the user's script
49-
${_TIMEOUT_COMMAND_PART} /bin/sh -c 'set -e
50-
cd '\''/tmp/test-dir'\'' && echo '\''hello world'\'''
51-
exit_code=$?
52-
53-
# Check the exit code based on whether timeout was attempted
54-
if [ "$_WAS_TIMEOUT_USED" = "true" ]; then
55-
if [ $exit_code -eq 143 ]; then # 128 + 15 (SIGTERM)
56-
echo "[postStart hook] Commands terminated by SIGTERM (likely timed out after ${POSTSTART_TIMEOUT_DURATION}s). Exit code 143." >&2
57-
elif [ $exit_code -eq 137 ]; then # 128 + 9 (SIGKILL)
58-
echo "[postStart hook] Commands forcefully killed by SIGKILL (likely after --kill-after ${POSTSTART_KILL_AFTER_DURATION}s expired). Exit code 137." >&2
59-
elif [ $exit_code -ne 0 ]; then # Catches any other non-zero exit code
60-
echo "[postStart hook] Commands failed with exit code $exit_code." >&2
61-
else
62-
echo "[postStart hook] Commands completed successfully within the time limit." >&2
63-
fi
64-
else
65-
if [ $exit_code -ne 0 ]; then
66-
echo "[postStart hook] Commands failed with exit code $exit_code (no timeout)." >&2
67-
else
68-
echo "[postStart hook] Commands completed successfully (no timeout)." >&2
69-
fi
70-
fi
71-
72-
exit $exit_code
73-
# This will be replaced by scriptWithTimeout
33+
cd /tmp/test-dir
34+
echo 'hello world' # This will be replaced by scriptWithTimeout
7435
}
7536
_script_to_run
7637
} 1> >(tee -a "/tmp/poststart-stdout.txt") 2> >(tee -a "/tmp/poststart-stderr.txt" >&2)

0 commit comments

Comments
 (0)