Skip to content

Commit

Permalink
improvement(k8s): retry the most used kubectl commands on failures
Browse files Browse the repository at this point in the history
The retry machinery uses some build-in checks to avoid retriying on any error.
For `kubectl` custom `RetryOpts` are configured.
  • Loading branch information
vvagaytsev committed Jul 5, 2023
1 parent 1015287 commit 07224f0
Showing 1 changed file with 28 additions and 3 deletions.
31 changes: 28 additions & 3 deletions core/src/plugins/kubernetes/kubectl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { PluginContext } from "../../plugin-context"
import { KubeApi } from "./api"
import { pathExists } from "fs-extra"
import { ConfigurationError } from "../../exceptions"
import { requestWithRetry, RetryOpts } from "./retry"

// Corresponds to the default prune whitelist in `kubectl`.
// See: https://github.com/kubernetes/kubectl/blob/master/pkg/cmd/apply/prune.go#L176-L192
Expand Down Expand Up @@ -52,10 +53,13 @@ export interface ApplyParams {
dryRun?: boolean
pruneLabels?: { [label: string]: string }
validate?: boolean
retryOpts?: RetryOpts
}

export const KUBECTL_DEFAULT_TIMEOUT = 300

const KUBECTL_DEFAULT_RETRY_OPTS: RetryOpts = { maxRetries: 3, minTimeoutMs: 300 }

export async function apply({
log,
ctx,
Expand Down Expand Up @@ -112,7 +116,18 @@ export async function apply({
args.push("--output=json", "-f", "-")
!validate && args.push("--validate=false")

const result = await kubectl(ctx, provider).stdout({ log, namespace, args, input })
const result = await requestWithRetry(
log,
`kubectl ${args.join(" ")}`,
() =>
kubectl(ctx, provider).stdout({
log,
namespace,
args,
input,
}),
KUBECTL_DEFAULT_RETRY_OPTS
)

if (namespace && resourcesToPrune.length > 0) {
await deleteResources({
Expand Down Expand Up @@ -162,7 +177,12 @@ export async function deleteResourceKeys({

includeUninitialized && args.push("--include-uninitialized")

return kubectl(ctx, provider).stdout({ namespace, args, log })
return await requestWithRetry(
log,
`kubectl ${args.join(" ")}`,
() => kubectl(ctx, provider).stdout({ namespace, args, log }),
KUBECTL_DEFAULT_RETRY_OPTS
)
}

export async function deleteObjectsBySelector({
Expand All @@ -186,7 +206,12 @@ export async function deleteObjectsBySelector({

includeUninitialized && args.push("--include-uninitialized")

return kubectl(ctx, provider).stdout({ namespace, args, log })
return await requestWithRetry(
log,
`kubectl ${args.join(" ")}`,
() => kubectl(ctx, provider).stdout({ namespace, args, log }),
KUBECTL_DEFAULT_RETRY_OPTS
)
}

interface KubectlParams extends ExecParams {
Expand Down

0 comments on commit 07224f0

Please sign in to comment.