Skip to content

Commit 0dddc52

Browse files
committed
fixup! fixup! fixup! fix: fall back to the original behaviour if timeout is disabled
Signed-off-by: Oleksii Kurinnyi <[email protected]>
1 parent 443872c commit 0dddc52

File tree

1 file changed

+72
-72
lines changed

1 file changed

+72
-72
lines changed

pkg/library/lifecycle/poststart.go

Lines changed: 72 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,78 @@ func AddPostStartLifecycleHooks(wksp *dw.DevWorkspaceTemplateSpec, containers []
8181
return nil
8282
}
8383

84+
// processCommandsForPostStart processes a list of DevWorkspace commands
85+
// and generates a corev1.LifecycleHandler for the PostStart lifecycle hook.
86+
func processCommandsForPostStart(commands []dw.Command, postStartTimeout *int32) (*corev1.LifecycleHandler, error) {
87+
if postStartTimeout == nil || *postStartTimeout == 0 {
88+
// use the fallback if no timeout propagated
89+
return processCommandsWithoutTimeoutFallback(commands)
90+
}
91+
92+
originalUserScript, err := buildUserScript(commands)
93+
if err != nil {
94+
return nil, fmt.Errorf("failed to build aggregated user script: %w", err)
95+
}
96+
97+
// The user script needs 'set -e' to ensure it exits on error.
98+
// This script is then passed to `sh -c '...'`, so single quotes within it must be escaped.
99+
scriptToExecute := "set -e\n" + originalUserScript
100+
escapedUserScriptForTimeoutWrapper := strings.ReplaceAll(scriptToExecute, "'", `'\''`)
101+
102+
fullScriptWithTimeout := generateScriptWithTimeout(escapedUserScriptForTimeoutWrapper, *postStartTimeout)
103+
104+
finalScriptForHook := fmt.Sprintf(redirectOutputFmt, fullScriptWithTimeout)
105+
106+
handler := &corev1.LifecycleHandler{
107+
Exec: &corev1.ExecAction{
108+
Command: []string{
109+
"/bin/sh",
110+
"-c",
111+
finalScriptForHook,
112+
},
113+
},
114+
}
115+
return handler, nil
116+
}
117+
118+
// processCommandsWithoutTimeoutFallback builds a lifecycle handler that runs the provided command(s)
119+
// The command has the format
120+
//
121+
// exec:
122+
//
123+
// command:
124+
// - "/bin/sh"
125+
// - "-c"
126+
// - |
127+
// cd <workingDir>
128+
// <commandline>
129+
func processCommandsWithoutTimeoutFallback(commands []dw.Command) (*corev1.LifecycleHandler, error) {
130+
var dwCommands []string
131+
for _, command := range commands {
132+
execCmd := command.Exec
133+
if len(execCmd.Env) > 0 {
134+
return nil, fmt.Errorf("env vars in postStart command %s are unsupported", command.Id)
135+
}
136+
if execCmd.WorkingDir != "" {
137+
dwCommands = append(dwCommands, fmt.Sprintf("cd %s", execCmd.WorkingDir))
138+
}
139+
dwCommands = append(dwCommands, execCmd.CommandLine)
140+
}
141+
142+
joinedCommands := strings.Join(dwCommands, "\n")
143+
144+
handler := &corev1.LifecycleHandler{
145+
Exec: &corev1.ExecAction{
146+
Command: []string{
147+
"/bin/sh",
148+
"-c",
149+
fmt.Sprintf(noTimeoutRedirectOutputFmt, joinedCommands),
150+
},
151+
},
152+
}
153+
return handler, nil
154+
}
155+
84156
// buildUserScript takes a list of DevWorkspace commands and constructs a single
85157
// shell script string that executes them sequentially.
86158
func buildUserScript(commands []dw.Command) (string, error) {
@@ -156,75 +228,3 @@ fi
156228
exit $exit_code
157229
`, timeoutSeconds, escapedUserScript)
158230
}
159-
160-
// processCommandsForPostStart processes a list of DevWorkspace commands
161-
// and generates a corev1.LifecycleHandler for the PostStart lifecycle hook.
162-
func processCommandsForPostStart(commands []dw.Command, postStartTimeout *int32) (*corev1.LifecycleHandler, error) {
163-
if postStartTimeout == nil || *postStartTimeout == 0 {
164-
// use the fallback if no timeout propagated
165-
return processCommandsWithoutTimeoutFallback(commands)
166-
}
167-
168-
originalUserScript, err := buildUserScript(commands)
169-
if err != nil {
170-
return nil, fmt.Errorf("failed to build aggregated user script: %w", err)
171-
}
172-
173-
// The user script needs 'set -e' to ensure it exits on error.
174-
// This script is then passed to `sh -c '...'`, so single quotes within it must be escaped.
175-
scriptToExecute := "set -e\n" + originalUserScript
176-
escapedUserScriptForTimeoutWrapper := strings.ReplaceAll(scriptToExecute, "'", `'\''`)
177-
178-
fullScriptWithTimeout := generateScriptWithTimeout(escapedUserScriptForTimeoutWrapper, *postStartTimeout)
179-
180-
finalScriptForHook := fmt.Sprintf(redirectOutputFmt, fullScriptWithTimeout)
181-
182-
handler := &corev1.LifecycleHandler{
183-
Exec: &corev1.ExecAction{
184-
Command: []string{
185-
"/bin/sh",
186-
"-c",
187-
finalScriptForHook,
188-
},
189-
},
190-
}
191-
return handler, nil
192-
}
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(noTimeoutRedirectOutputFmt, joinedCommands),
226-
},
227-
},
228-
}
229-
return handler, nil
230-
}

0 commit comments

Comments
 (0)