Skip to content

Commit f6536f0

Browse files
authored
chore: add retry to pod exec (#12)
* lets'go * empty commit for ci * bump v
1 parent f9c069f commit f6536f0

File tree

4 files changed

+73
-28
lines changed

4 files changed

+73
-28
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hooks",
3-
"version": "0.3.12",
3+
"version": "0.3.13",
44
"description": "Three projects are included - k8s: a kubernetes hook implementation that spins up pods dynamically to run a job - docker: A hook implementation of the runner's docker implementation - A hook lib, which contains shared typescript definitions and utilities that the other packages consume",
55
"main": "",
66
"directories": {

packages/k8s/package-lock.json

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/k8s/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"@actions/io": "^1.1.2",
1919
"@kubernetes/client-node": "^0.16.3",
2020
"@types/lodash": "^4.14.191",
21+
"exponential-backoff": "^3.1.1",
2122
"hooklib": "file:../hooklib"
2223
},
2324
"devDependencies": {

packages/k8s/src/k8s/index.ts

Lines changed: 60 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
} from '../hooks/constants'
1515
import { PodPhase } from './utils'
1616
import * as fs from 'fs'
17+
import { backOff } from 'exponential-backoff'
1718

1819
const kc = new k8s.KubeConfig()
1920

@@ -222,38 +223,70 @@ export async function execPodStep(
222223
): Promise<void> {
223224
const exec = new k8s.Exec(kc)
224225
await new Promise(async function (resolve, reject) {
226+
const backOffOptions = {
227+
numOfAttempts: 3,
228+
retry: (e, attemptNumber) => {
229+
core.debug(e.toString())
230+
core.debug(
231+
`an error occurred trying to execute command in pod, retrying (${attemptNumber}/3)`
232+
)
233+
return true
234+
}
235+
}
225236
try {
226-
await exec.exec(
227-
namespace(),
228-
podName,
229-
containerName,
230-
command,
231-
process.stdout,
232-
process.stderr,
233-
stdin ?? null,
234-
false /* tty */,
235-
resp => {
236-
// kube.exec returns an error if exit code is not 0, but we can't actually get the exit code
237-
if (resp.status === 'Success') {
238-
resolve(resp.code)
239-
} else {
240-
core.debug(
241-
JSON.stringify({
242-
message: resp?.message,
243-
details: resp?.details
244-
})
245-
)
246-
reject(resp?.message)
247-
}
248-
}
249-
)
250-
} catch (error) {
251-
core.error(`Failed to exec pod step`)
252-
core.error(error as Error)
237+
await backOff(async () => {
238+
await execInPod(
239+
exec,
240+
command,
241+
podName,
242+
containerName,
243+
resolve,
244+
reject,
245+
stdin
246+
)
247+
}, backOffOptions)
248+
} catch (e) {
249+
core.debug('something went wrong in calling pod exec')
250+
reject(e)
253251
}
254252
})
255253
}
256254

255+
async function execInPod(
256+
exec: k8s.Exec,
257+
command: string[],
258+
podName: string,
259+
containerName: string,
260+
resolve: (value?: number | PromiseLike<number> | undefined) => void,
261+
reject: (reason?: any) => void,
262+
stdin?: stream.Readable
263+
): Promise<void> {
264+
await exec.exec(
265+
namespace(),
266+
podName,
267+
containerName,
268+
command,
269+
process.stdout,
270+
process.stderr,
271+
stdin ?? null,
272+
false /* tty */,
273+
resp => {
274+
// kube.exec returns an error if exit code is not 0, but we can't actually get the exit code
275+
if (resp.status === 'Success') {
276+
resolve(resp.code)
277+
} else {
278+
core.debug(
279+
JSON.stringify({
280+
message: resp?.message,
281+
details: resp?.details
282+
})
283+
)
284+
reject(resp?.message)
285+
}
286+
}
287+
)
288+
}
289+
257290
export async function waitForJobToComplete(jobName: string): Promise<void> {
258291
const backOffManager = new BackOffManager()
259292
while (true) {

0 commit comments

Comments
 (0)