Skip to content

Commit

Permalink
feat(k8s): add timeout to container services
Browse files Browse the repository at this point in the history
This has been requested by a few users. The deployment timeout for
`container` services can now be configured.
  • Loading branch information
thsig committed Nov 4, 2021
1 parent c523e94 commit 2927fa5
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 13 deletions.
3 changes: 3 additions & 0 deletions core/src/plugins/container/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { dedent, deline } from "../../util/string"
import { getModuleTypeUrl } from "../../docs/common"
import { ContainerModuleOutputs } from "./container"
import { devModeGuideLink } from "../kubernetes/dev-mode"
import { k8sDeploymentTimeoutSchema } from "../kubernetes/config"

export const defaultContainerLimits: ServiceLimitSpec = {
cpu: 1000, // = 1000 millicpu = 1 CPU
Expand Down Expand Up @@ -121,6 +122,7 @@ export interface ContainerServiceSpec extends CommonServiceSpec {
healthCheck?: ServiceHealthCheckSpec
hotReloadCommand?: string[]
hotReloadArgs?: string[]
timeout?: number
limits?: ServiceLimitSpec
cpu: ContainerResourcesSpec["cpu"]
memory: ContainerResourcesSpec["memory"]
Expand Down Expand Up @@ -610,6 +612,7 @@ const containerServiceSchema = () =>
these arguments when the service is deployed with hot reloading enabled.`
)
.example(["npm", "run", "dev"]),
timeout: k8sDeploymentTimeoutSchema(),
limits: limitsSchema()
.description("Specify resource limits for the service.")
.meta({ deprecated: "Please use the `cpu` and `memory` fields instead." }),
Expand Down
13 changes: 10 additions & 3 deletions core/src/plugins/kubernetes/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { ArtifactSpec } from "../../config/validation"
import { V1Toleration } from "@kubernetes/client-node"
import { runPodSpecIncludeFields } from "./run"
import { KubernetesDevModeDefaults, kubernetesDevModeDefaultsSchema } from "./dev-mode"
import { KUBECTL_DEFAULT_TIMEOUT } from "./kubectl"

export const DEFAULT_KANIKO_IMAGE = "gcr.io/kaniko-project/executor:v1.6.0-debug"
export interface ProviderSecretRef {
Expand Down Expand Up @@ -282,6 +283,12 @@ const storageSchema = (defaults: KubernetesStorageSpec, deprecated: boolean) =>
})
.default(defaults)

export const k8sDeploymentTimeoutSchema = () =>
joi
.number()
.default(KUBECTL_DEFAULT_TIMEOUT)
.description("The maximum duration (in seconds) to wait for resources to deploy and become healthy.")

export const k8sContextSchema = () =>
joi
.string()
Expand Down Expand Up @@ -838,7 +845,7 @@ export const portForwardsSchema = () =>
"Manually specify port forwards that Garden should set up when deploying in dev or watch mode. If specified, these override the auto-detection of forwardable ports, so you'll need to specify the full list of port forwards to create."
)

const runPodSpecWhitelistDescription = runPodSpecIncludeFields.map((f) => `* \`${f}\``).join("\n")
const runPodSpecWhitelistDescription = () => runPodSpecIncludeFields.map((f) => `* \`${f}\``).join("\n")

export const kubernetesTaskSchema = () =>
baseTaskSpecSchema()
Expand All @@ -851,7 +858,7 @@ export const kubernetesTaskSchema = () =>
${serviceResourceDescription}
The following pod spec fields from the service resource will be used (if present) when executing the task:
${runPodSpecWhitelistDescription}`
${runPodSpecWhitelistDescription()}`
),
cacheResult: cacheResultSchema(),
command: joi
Expand Down Expand Up @@ -880,7 +887,7 @@ export const kubernetesTestSchema = () =>
${serviceResourceDescription}
The following pod spec fields from the service resource will be used (if present) when executing the test suite:
${runPodSpecWhitelistDescription}`
${runPodSpecWhitelistDescription()}`
),
command: joi
.sparseArray()
Expand Down
2 changes: 1 addition & 1 deletion core/src/plugins/kubernetes/container/deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export async function deployContainerServiceRolling(params: DeployServiceParams<
serviceName: service.name,
resources: manifests,
log,
timeoutSec: KUBECTL_DEFAULT_TIMEOUT,
timeoutSec: service.spec.timeout || KUBECTL_DEFAULT_TIMEOUT,
})
}

Expand Down
7 changes: 2 additions & 5 deletions core/src/plugins/kubernetes/kubernetes-module/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ import {
serviceResourceDescription,
portForwardsSchema,
PortForwardSpec,
k8sDeploymentTimeoutSchema,
} from "../config"
import { ContainerModule } from "../../container/config"
import { kubernetesDevModeSchema, KubernetesDevModeSpec } from "../dev-mode"
import { KUBECTL_DEFAULT_TIMEOUT } from "../kubectl"

// A Kubernetes Module always maps to a single Service
export type KubernetesModuleSpec = KubernetesServiceSpec
Expand Down Expand Up @@ -105,10 +105,7 @@ export const kubernetesModuleSpecSchema = () =>
}),
tasks: joiSparseArray(kubernetesTaskSchema()),
tests: joiSparseArray(kubernetesTestSchema()),
timeout: joi
.number()
.default(KUBECTL_DEFAULT_TIMEOUT)
.description("The maximum duration (in seconds) to wait for resources to deploy and become healthy."),
timeout: k8sDeploymentTimeoutSchema(),
})

export async function configureKubernetesModule({
Expand Down
2 changes: 2 additions & 0 deletions core/test/unit/src/commands/get/get-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { sortBy } from "lodash"
import { DEFAULT_API_VERSION } from "../../../../../src/constants"
import { defaultWorkflowResources, WorkflowConfig } from "../../../../../src/config/workflow"
import { defaultContainerLimits, defaultContainerResources } from "../../../../../src/plugins/container/config"
import { KUBECTL_DEFAULT_TIMEOUT } from "../../../../../src/plugins/kubernetes/kubectl"

describe("GetConfigCommand", () => {
it("should get the project configuration", async () => {
Expand Down Expand Up @@ -491,6 +492,7 @@ describe("GetConfigCommand", () => {
cpu: defaultContainerResources.cpu,
memory: defaultContainerResources.memory,
ports: [],
timeout: KUBECTL_DEFAULT_TIMEOUT,
volumes: [],
},
hotReloadable: false,
Expand Down
6 changes: 3 additions & 3 deletions core/test/unit/src/garden.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4454,9 +4454,9 @@ describe("Garden", () => {
})

context("test against fixed version hashes", async () => {
const moduleAVersionString = "v-02baf73977"
const moduleBVersionString = "v-2ef2ef79d3"
const moduleCVersionString = "v-dc9d7af247"
const moduleAVersionString = "v-f6743d2423"
const moduleBVersionString = "v-97a77e8414"
const moduleCVersionString = "v-afb847fa9a"

it("should return the same module versions between runtimes", async () => {
const projectRoot = getDataDir("test-projects", "fixed-version-hashes-1")
Expand Down
2 changes: 1 addition & 1 deletion core/test/unit/src/vcs/vcs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ describe("getModuleVersionString", () => {
const garden = await makeTestGarden(projectRoot)
const module = await garden.resolveModule("module-a")

const fixedVersionString = "v-02baf73977"
const fixedVersionString = "v-f6743d2423"
expect(module.version.versionString).to.eql(fixedVersionString)

delete process.env.TEST_ENV_VAR
Expand Down
13 changes: 13 additions & 0 deletions docs/reference/module-types/container.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,9 @@ services:
# deployed with hot reloading enabled.
hotReloadArgs:

# The maximum duration (in seconds) to wait for resources to deploy and become healthy.
timeout: 300

cpu:
# The minimum amount of CPU the service needs to be available for it to be deployed, in millicpus (i.e. 1000 = 1
# CPU)
Expand Down Expand Up @@ -1550,6 +1553,16 @@ services:
- dev
```

### `services[].timeout`

[services](#services) > timeout

The maximum duration (in seconds) to wait for resources to deploy and become healthy.

| Type | Default | Required |
| -------- | ------- | -------- |
| `number` | `300` | No |

### `services[].limits`

[services](#services) > limits
Expand Down
13 changes: 13 additions & 0 deletions docs/reference/module-types/jib-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,9 @@ services:
# deployed with hot reloading enabled.
hotReloadArgs:

# The maximum duration (in seconds) to wait for resources to deploy and become healthy.
timeout: 300

cpu:
# The minimum amount of CPU the service needs to be available for it to be deployed, in millicpus (i.e. 1000 = 1
# CPU)
Expand Down Expand Up @@ -1621,6 +1624,16 @@ services:
- dev
```

### `services[].timeout`

[services](#services) > timeout

The maximum duration (in seconds) to wait for resources to deploy and become healthy.

| Type | Default | Required |
| -------- | ------- | -------- |
| `number` | `300` | No |

### `services[].limits`

[services](#services) > limits
Expand Down
13 changes: 13 additions & 0 deletions docs/reference/module-types/maven-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,9 @@ services:
# deployed with hot reloading enabled.
hotReloadArgs:

# The maximum duration (in seconds) to wait for resources to deploy and become healthy.
timeout: 300

cpu:
# The minimum amount of CPU the service needs to be available for it to be deployed, in millicpus (i.e. 1000 = 1
# CPU)
Expand Down Expand Up @@ -1560,6 +1563,16 @@ services:
- dev
```

### `services[].timeout`

[services](#services) > timeout

The maximum duration (in seconds) to wait for resources to deploy and become healthy.

| Type | Default | Required |
| -------- | ------- | -------- |
| `number` | `300` | No |

### `services[].limits`

[services](#services) > limits
Expand Down

0 comments on commit 2927fa5

Please sign in to comment.