Skip to content

Commit

Permalink
Merge pull request #646 from garden-io/cache-task-results
Browse files Browse the repository at this point in the history
feat(k8s): cache task results
  • Loading branch information
edvald authored Mar 19, 2019
2 parents d3bf60d + 5769aeb commit 9c19132
Show file tree
Hide file tree
Showing 17 changed files with 241 additions and 64 deletions.
11 changes: 10 additions & 1 deletion garden-service/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ import {
TestResult,
PluginActionOutputs,
PublishResult,
RunTaskResult,
TaskActionOutputs,
HotReloadServiceResult,
RunTaskResult,
} from "./types/plugin/outputs"
import {
BuildModuleParams,
Expand Down Expand Up @@ -70,6 +70,7 @@ import {
PluginTaskActionParamsBase,
RunTaskParams,
TaskActionParams,
GetTaskResultParams,
} from "./types/plugin/params"
import { Service, ServiceStatus, getServiceRuntimeContext } from "./types/service"
import { mapValues, values, keyBy, omit, pickBy, fromPairs } from "lodash"
Expand Down Expand Up @@ -329,6 +330,14 @@ export class ActionHelper implements TypeGuard {
return this.callTaskHandler({ params, actionType: "runTask" })
}

async getTaskResult(params: TaskActionHelperParams<GetTaskResultParams>): Promise<RunTaskResult | null> {
return this.callTaskHandler({
params,
actionType: "getTaskResult",
defaultHandler: async () => null,
})
}

//endregion

//===========================================================================
Expand Down
2 changes: 1 addition & 1 deletion garden-service/src/commands/run/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class RunTaskCommand extends Command<Args, Opts> {

await garden.actions.prepareEnvironment({ log })

const taskTask = new TaskTask({ garden, graph, task, log, force: true, forceBuild: opts["force-build"] })
const taskTask = await TaskTask.factory({ garden, graph, task, log, force: true, forceBuild: opts["force-build"] })
await garden.addTask(taskTask)

const result = (await garden.processTasks())[taskTask.getBaseKey()]
Expand Down
4 changes: 4 additions & 0 deletions garden-service/src/commands/run/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import dedent = require("dedent")
import { prepareRuntimeContext } from "../../types/service"
import { logHeader } from "../../logger/util"
import { PushTask } from "../../tasks/push"
import { getTestVersion } from "../../tasks/test"

const runArgs = {
module: new StringParameter({
Expand Down Expand Up @@ -101,13 +102,16 @@ export class RunTestCommand extends Command<Args, Opts> {

printRuntimeContext(log, runtimeContext)

const testVersion = await getTestVersion(garden, graph, module, testConfig)

const result = await garden.actions.testModule({
log,
module,
interactive,
runtimeContext,
silent: false,
testConfig,
testVersion,
})

return { result }
Expand Down
2 changes: 2 additions & 0 deletions garden-service/src/plugins/kubernetes/container/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { getContainerServiceStatus } from "./status"
import { getTestResult } from "../test"
import { ContainerModule } from "../../container/config"
import { configureMavenContainerModule, MavenContainerModule } from "../../maven-container/maven-container"
import { getTaskResult } from "../task-results"

async function configure(params: ConfigureModuleParams<ContainerModule>) {
const config = await configureContainerModule(params)
Expand Down Expand Up @@ -46,6 +47,7 @@ export const containerHandlers = {
runModule: runContainerModule,
runService: runContainerService,
runTask: runContainerTask,
getTaskResult,
testModule: testContainerModule,
}

Expand Down
17 changes: 12 additions & 5 deletions garden-service/src/plugins/kubernetes/container/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { getContainerServiceStatus } from "./status"
import { runPod } from "../run"
import { containerHelpers } from "../../container/helpers"
import { KubernetesPluginContext, KubernetesProvider } from "../kubernetes"
import { storeTaskResult } from "../task-results"

export async function execInService(params: ExecInServiceParams<ContainerModule>) {
const { ctx, service, command, interactive } = params
Expand Down Expand Up @@ -115,7 +116,7 @@ export async function runContainerService(
}

export async function runContainerTask(
{ ctx, log, module, task, interactive, runtimeContext }: RunTaskParams<ContainerModule>,
{ ctx, log, module, task, taskVersion, interactive, runtimeContext }: RunTaskParams<ContainerModule>,
): Promise<RunTaskResult> {
extend(runtimeContext.envVars, task.spec.env || {})

Expand All @@ -124,7 +125,7 @@ export async function runContainerTask(
const namespace = await getAppNamespace(ctx, provider)
const image = await containerHelpers.getDeploymentImageId(module, provider.config.deploymentRegistry)

const result = await runPod({
const res = await runPod({
context,
namespace,
module,
Expand All @@ -139,8 +140,14 @@ export async function runContainerTask(
log,
})

return {
...result,
const result = { ...res, taskName: task.name }

await storeTaskResult({
ctx,
result,
taskVersion,
taskName: task.name,
}
})

return result
}
4 changes: 2 additions & 2 deletions garden-service/src/plugins/kubernetes/container/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { runContainerModule } from "./run"
import { storeTestResult } from "../test"

export async function testContainerModule(
{ ctx, interactive, module, runtimeContext, testConfig, log }:
{ ctx, interactive, module, runtimeContext, testConfig, testVersion, log }:
TestModuleParams<ContainerModule>,
): Promise<TestResult> {
const testName = testConfig.name
Expand All @@ -32,5 +32,5 @@ export async function testContainerModule(
log,
})

return storeTestResult({ ctx, module, testName, result })
return storeTestResult({ ctx, module, testName, testVersion, result })
}
15 changes: 11 additions & 4 deletions garden-service/src/plugins/kubernetes/helm/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { PluginContext } from "../../../plugin-context"
import { LogEntry } from "../../../logger/log-entry"
import { ConfigurationError } from "../../../exceptions"
import { KubernetesPluginContext } from "../kubernetes"
import { storeTaskResult } from "../task-results"

export async function runHelmModule(
{
Expand Down Expand Up @@ -52,7 +53,7 @@ export async function runHelmModule(
}

export async function runHelmTask(
{ ctx, log, module, task, interactive, runtimeContext, timeout }: RunTaskParams<HelmModule>,
{ ctx, log, module, task, taskVersion, interactive, runtimeContext, timeout }: RunTaskParams<HelmModule>,
): Promise<RunTaskResult> {
const k8sCtx = <KubernetesPluginContext>ctx
const context = k8sCtx.provider.config.context
Expand All @@ -74,10 +75,16 @@ export async function runHelmTask(
log,
})

return {
const result = { ...res, taskName: task.name }

await storeTaskResult({
ctx,
result,
taskVersion,
taskName: task.name,
...res,
}
})

return result
}

async function getImage(ctx: PluginContext, module: HelmModule, log: LogEntry, resourceSpec: HelmResourceSpec) {
Expand Down
4 changes: 2 additions & 2 deletions garden-service/src/plugins/kubernetes/helm/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { findServiceResource, getChartResources, getResourceContainer, getServic
import { KubernetesPluginContext } from "../kubernetes"

export async function testHelmModule(
{ ctx, log, interactive, module, runtimeContext, testConfig }:
{ ctx, log, interactive, module, runtimeContext, testConfig, testVersion }:
TestModuleParams<HelmModule>,
): Promise<TestResult> {
const testName = testConfig.name
Expand Down Expand Up @@ -48,5 +48,5 @@ export async function testHelmModule(
log,
})

return storeTestResult({ ctx: k8sCtx, module, testName, result })
return storeTestResult({ ctx: k8sCtx, module, testName, testVersion, result })
}
81 changes: 81 additions & 0 deletions garden-service/src/plugins/kubernetes/task-results.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (C) 2018 Garden Technologies, Inc. <[email protected]>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { GetTaskResultParams } from "../../types/plugin/params"
import { ContainerModule } from "../container/config"
import { HelmModule } from "./helm/config"
import { ModuleVersion } from "../../vcs/base"
import { KubernetesPluginContext, KubernetesProvider } from "./kubernetes"
import { KubeApi } from "./api"
import { getMetadataNamespace } from "./namespace"
import { RunTaskResult } from "../../types/plugin/outputs"
import { deserializeValues, serializeValues } from "../../util/util"
import { PluginContext } from "../../plugin-context"

export async function getTaskResult(
{ ctx, task, taskVersion }: GetTaskResultParams<ContainerModule | HelmModule>,
): Promise<RunTaskResult | null> {
const k8sCtx = <KubernetesPluginContext>ctx
const api = new KubeApi(k8sCtx.provider.config.context)
const ns = await getMetadataNamespace(k8sCtx, k8sCtx.provider)
const resultKey = getTaskResultKey(task.name, taskVersion)

try {
const res = await api.core.readNamespacedConfigMap(resultKey, ns)
return <RunTaskResult>deserializeValues(res.body.data)
} catch (err) {
if (err.code === 404) {
return null
} else {
throw err
}
}
}

export function getTaskResultKey(taskName: string, version: ModuleVersion) {
return `task-result--${taskName}--${version.versionString}`
}

/**
* Store a task run result as a ConfigMap in the cluster.
*
* TODO: Implement a CRD for this.
*/
export async function storeTaskResult(
{ ctx, taskName, taskVersion, result }:
{ ctx: PluginContext, taskName: string, taskVersion: ModuleVersion, result: RunTaskResult },
): Promise<RunTaskResult> {
const provider = <KubernetesProvider>ctx.provider
const api = new KubeApi(provider.config.context)
const ns = await getMetadataNamespace(ctx, provider)
const resultKey = getTaskResultKey(taskName, taskVersion)

const body = {
apiVersion: "v1",
kind: "ConfigMap",
metadata: {
name: resultKey,
annotations: {
"garden.io/generated": "true",
},
},
data: serializeValues(result),
}

try {
await api.core.createNamespacedConfigMap(ns, <any>body)
} catch (err) {
if (err.code === 409) {
await api.core.patchNamespacedConfigMap(resultKey, ns, body)
} else {
throw err
}
}

return result
}
14 changes: 7 additions & 7 deletions garden-service/src/plugins/kubernetes/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import { PluginContext } from "../../plugin-context"
import { KubernetesPluginContext } from "./kubernetes"

export async function getTestResult(
{ ctx, module, testName, version }: GetTestResultParams<ContainerModule | HelmModule>,
) {
{ ctx, module, testName, testVersion }: GetTestResultParams<ContainerModule | HelmModule>,
): Promise<TestResult | null> {
const k8sCtx = <KubernetesPluginContext>ctx
const api = new KubeApi(k8sCtx.provider.config.context)
const ns = await getMetadataNamespace(k8sCtx, k8sCtx.provider)
const resultKey = getTestResultKey(module, testName, version)
const resultKey = getTestResultKey(module, testName, testVersion)

try {
const res = await api.core.readNamespacedConfigMap(resultKey, ns)
Expand All @@ -48,9 +48,9 @@ export function getTestResultKey(module: Module, testName: string, version: Modu
* TODO: Implement a CRD for this.
*/
export async function storeTestResult(
{ ctx, module, testName, result }:
{ ctx: PluginContext, module: Module, testName: string, result: RunResult },
) {
{ ctx, module, testName, testVersion, result }:
{ ctx: PluginContext, module: Module, testName: string, testVersion: ModuleVersion, result: RunResult },
): Promise<TestResult> {
const k8sCtx = <KubernetesPluginContext>ctx
const api = new KubeApi(k8sCtx.provider.config.context)

Expand All @@ -60,7 +60,7 @@ export async function storeTestResult(
}

const ns = await getMetadataNamespace(k8sCtx, k8sCtx.provider)
const resultKey = getTestResultKey(module, testName, result.version)
const resultKey = getTestResultKey(module, testName, testVersion)
const body = {
apiVersion: "v1",
kind: "ConfigMap",
Expand Down
6 changes: 3 additions & 3 deletions garden-service/src/tasks/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ export class DeployTask extends BaseTask {
if (this.fromWatch && includes(this.hotReloadServiceNames, this.service.name)) {
return deployTasks
} else {
const taskTasks = deps.task.map(task => {
return new TaskTask({
const taskTasks = await Bluebird.map(deps.task, (task) => {
return TaskTask.factory({
task,
garden: this.garden,
log: this.log,
graph: this.graph,
force: false,
force: this.force,
forceBuild: this.forceBuild,
})
})
Expand Down
Loading

0 comments on commit 9c19132

Please sign in to comment.