From b24c6a92cc5d15d70489f7ae4229f76af9616774 Mon Sep 17 00:00:00 2001 From: Jon Edvald Date: Mon, 24 Sep 2018 17:02:39 +0200 Subject: [PATCH] refactor: add buildDependencies key to plugin module action params --- garden-service/src/actions.ts | 23 ++++++++++++++----- .../plugins/google/google-cloud-functions.ts | 4 ++-- .../src/plugins/kubernetes/actions.ts | 6 +++-- garden-service/src/plugins/kubernetes/helm.ts | 6 ++--- .../src/plugins/local/local-docker-swarm.ts | 16 +++++++++---- .../src/plugins/openfaas/openfaas.ts | 5 ++-- garden-service/src/types/plugin/params.ts | 5 +++- garden-service/test/helpers.ts | 5 +++- garden-service/test/src/plugins/container.ts | 14 +++++------ 9 files changed, 56 insertions(+), 28 deletions(-) diff --git a/garden-service/src/actions.ts b/garden-service/src/actions.ts index 66f6a8ce29..56d92c17a9 100644 --- a/garden-service/src/actions.ts +++ b/garden-service/src/actions.ts @@ -10,7 +10,7 @@ import Bluebird = require("bluebird") import chalk from "chalk" import { Garden } from "./garden" import { PrimitiveMap } from "./config/common" -import { Module } from "./types/module" +import { Module, ModuleMap } from "./types/module" import { ModuleActions, ServiceActions, PluginActions } from "./types/plugin/plugin" import { BuildResult, @@ -90,10 +90,10 @@ export interface DeployServicesParams { type ActionHelperParams = Omit & { pluginName?: string } type ModuleActionHelperParams = - Omit & { pluginName?: string } + Omit & { pluginName?: string } // additionally make runtimeContext param optional type ServiceActionHelperParams = - Omit + Omit & { runtimeContext?: RuntimeContext, pluginName?: string } type RequirePluginName = T & { pluginName: string } @@ -292,13 +292,18 @@ export class ActionHelper implements TypeGuard { //region Helper Methods //=========================================================================== + private async getBuildDependencies(module: Module): Promise { + const dependencies = await this.garden.resolveModuleDependencies(module.build.dependencies, []) + return keyBy(dependencies, "name") + } + async getStatus(): Promise { const envStatus: EnvironmentStatusMap = await this.getEnvironmentStatus({}) const services = keyBy(await this.garden.getServices(), "name") const serviceStatus = await Bluebird.props(mapValues(services, async (service: Service) => { - const dependencies = await this.garden.getServices(service.config.dependencies) - const runtimeContext = await prepareRuntimeContext(this.garden, service.module, dependencies) + const serviceDependencies = await this.garden.getServices(service.config.dependencies) + const runtimeContext = await prepareRuntimeContext(this.garden, service.module, serviceDependencies) return this.getServiceStatus({ service, runtimeContext }) })) @@ -372,10 +377,14 @@ export class ActionHelper implements TypeGuard { pluginName, defaultHandler, }) + + const buildDependencies = await this.getBuildDependencies(module) + const handlerParams: any = { ...this.commonParams(handler), - ...omit(params, ["module"]), + ...params, module: omit(module, ["_ConfigType"]), + buildDependencies, } // TODO: figure out why this doesn't compile without the function cast return (handler)(handlerParams) @@ -396,6 +405,7 @@ export class ActionHelper implements TypeGuard { }) // TODO: figure out why this doesn't compile without the casts + const buildDependencies = await this.getBuildDependencies(module) const deps = await this.garden.getServices(service.config.dependencies) const runtimeContext = ((params).runtimeContext || await prepareRuntimeContext(this.garden, module, deps)) @@ -404,6 +414,7 @@ export class ActionHelper implements TypeGuard { ...params, module, runtimeContext, + buildDependencies, } return (handler)(handlerParams) diff --git a/garden-service/src/plugins/google/google-cloud-functions.ts b/garden-service/src/plugins/google/google-cloud-functions.ts index 06dfe3dcde..c0ae3451ab 100644 --- a/garden-service/src/plugins/google/google-cloud-functions.ts +++ b/garden-service/src/plugins/google/google-cloud-functions.ts @@ -110,7 +110,7 @@ export const gardenPlugin = (): GardenPlugin => ({ validate: parseGcfModule, async deployService( - { ctx, module, service, runtimeContext, logEntry }: DeployServiceParams, + { ctx, module, service, runtimeContext, logEntry, buildDependencies }: DeployServiceParams, ) { // TODO: provide env vars somehow to function const project = getProject(service, ctx.provider) @@ -126,7 +126,7 @@ export const gardenPlugin = (): GardenPlugin => ({ "--trigger-http", ]) - return getServiceStatus({ ctx, module, service, runtimeContext, logEntry }) + return getServiceStatus({ ctx, module, service, runtimeContext, logEntry, buildDependencies }) }, async getServiceOutputs({ ctx, service }: GetServiceOutputsParams) { diff --git a/garden-service/src/plugins/kubernetes/actions.ts b/garden-service/src/plugins/kubernetes/actions.ts index cdaf748ef5..668852d2df 100644 --- a/garden-service/src/plugins/kubernetes/actions.ts +++ b/garden-service/src/plugins/kubernetes/actions.ts @@ -175,7 +175,7 @@ export async function runModule( } export async function runService( - { ctx, service, interactive, runtimeContext, silent, timeout, logEntry }: + { ctx, service, interactive, runtimeContext, silent, timeout, logEntry, buildDependencies }: RunServiceParams, ) { return runModule({ @@ -187,11 +187,12 @@ export async function runService( silent, timeout, logEntry, + buildDependencies, }) } export async function testModule( - { ctx, interactive, module, runtimeContext, silent, testConfig, logEntry }: + { ctx, interactive, module, runtimeContext, silent, testConfig, logEntry, buildDependencies }: TestModuleParams, ): Promise { const testName = testConfig.name @@ -208,6 +209,7 @@ export async function testModule( silent, timeout, logEntry, + buildDependencies, }) const api = new KubeApi(ctx.provider) diff --git a/garden-service/src/plugins/kubernetes/helm.ts b/garden-service/src/plugins/kubernetes/helm.ts index 8cf62d9fd4..6b4b03cbb7 100644 --- a/garden-service/src/plugins/kubernetes/helm.ts +++ b/garden-service/src/plugins/kubernetes/helm.ts @@ -295,12 +295,12 @@ async function getChartObjects(ctx: PluginContext, service: Service, logEntry?: } async function getServiceStatus( - { ctx, service, module, logEntry }: GetServiceStatusParams, + { ctx, service, module, logEntry, buildDependencies }: GetServiceStatusParams, ): Promise { // need to build to be able to check the status - const buildStatus = await getGenericModuleBuildStatus({ ctx, module, logEntry }) + const buildStatus = await getGenericModuleBuildStatus({ ctx, module, logEntry, buildDependencies }) if (!buildStatus.ready) { - await build({ ctx, module, logEntry }) + await build({ ctx, module, logEntry, buildDependencies }) } // first check if the installed objects on the cluster match the current code diff --git a/garden-service/src/plugins/local/local-docker-swarm.ts b/garden-service/src/plugins/local/local-docker-swarm.ts index fc57958923..05f24fe96d 100644 --- a/garden-service/src/plugins/local/local-docker-swarm.ts +++ b/garden-service/src/plugins/local/local-docker-swarm.ts @@ -45,7 +45,7 @@ export const gardenPlugin = (): GardenPlugin => ({ getServiceStatus, async deployService( - { ctx, module, service, runtimeContext, logEntry }: DeployServiceParams, + { ctx, module, service, runtimeContext, logEntry, buildDependencies }: DeployServiceParams, ) { // TODO: split this method up and test const { versionString } = service.module.version @@ -116,7 +116,14 @@ export const gardenPlugin = (): GardenPlugin => ({ } const docker = getDocker() - const serviceStatus = await getServiceStatus({ ctx, service, module, runtimeContext, logEntry }) + const serviceStatus = await getServiceStatus({ + ctx, + service, + module, + runtimeContext, + logEntry, + buildDependencies, + }) let swarmServiceStatus let serviceId @@ -172,7 +179,7 @@ export const gardenPlugin = (): GardenPlugin => ({ msg: `Ready`, }) - return getServiceStatus({ ctx, module, service, runtimeContext, logEntry }) + return getServiceStatus({ ctx, module, service, runtimeContext, logEntry, buildDependencies }) }, async getServiceOutputs({ ctx, service }: GetServiceOutputsParams) { @@ -182,7 +189,7 @@ export const gardenPlugin = (): GardenPlugin => ({ }, async execInService( - { ctx, service, command, runtimeContext, logEntry }: ExecInServiceParams, + { ctx, service, command, runtimeContext, logEntry, buildDependencies }: ExecInServiceParams, ) { const status = await getServiceStatus({ ctx, @@ -190,6 +197,7 @@ export const gardenPlugin = (): GardenPlugin => ({ module: service.module, runtimeContext, logEntry, + buildDependencies, }) if (!status.state || status.state !== "ready") { diff --git a/garden-service/src/plugins/openfaas/openfaas.ts b/garden-service/src/plugins/openfaas/openfaas.ts index 4444a05f0b..13b2db3216 100644 --- a/garden-service/src/plugins/openfaas/openfaas.ts +++ b/garden-service/src/plugins/openfaas/openfaas.ts @@ -214,7 +214,7 @@ export function gardenPlugin({ config }: { config: OpenFaasConfig }): GardenPlug }, async deployService(params: DeployServiceParams): Promise { - const { ctx, module, service, logEntry, runtimeContext } = params + const { ctx, module, service, logEntry, runtimeContext, buildDependencies } = params // write the stack file again with environment variables await writeStackFile(ctx, module, runtimeContext.envVars) @@ -236,7 +236,7 @@ export function gardenPlugin({ config }: { config: OpenFaasConfig }): GardenPlug }, async deleteService(params: DeleteServiceParams): Promise { - const { ctx, logEntry, service, runtimeContext } = params + const { ctx, logEntry, service, runtimeContext, buildDependencies } = params let status let found = true @@ -245,6 +245,7 @@ export function gardenPlugin({ config }: { config: OpenFaasConfig }): GardenPlug ctx, service, runtimeContext, + buildDependencies, module: service.module, }) diff --git a/garden-service/src/types/plugin/params.ts b/garden-service/src/types/plugin/params.ts index 3173da6905..e3e092139a 100644 --- a/garden-service/src/types/plugin/params.ts +++ b/garden-service/src/types/plugin/params.ts @@ -10,7 +10,7 @@ import Stream from "ts-stream" import { LogEntry } from "../../logger/log-entry" import { PluginContext, pluginContextSchema } from "../../plugin-context" import { ModuleVersion, moduleVersionSchema } from "../../vcs/base" -import { Primitive, joiPrimitive, joiArray } from "../../config/common" +import { Primitive, joiPrimitive, joiArray, joiIdentifierMap } from "../../config/common" import { Module, moduleSchema } from "../module" import { RuntimeContext, Service, serviceSchema, runtimeContextSchema } from "../service" import { EnvironmentStatus, ServiceLogEntry, environmentStatusSchema } from "./outputs" @@ -39,10 +39,13 @@ const actionParamsSchema = Joi.object() export interface PluginModuleActionParamsBase extends PluginActionParamsBase { module: T + buildDependencies: { [name: string]: Module } } const moduleActionParamsSchema = actionParamsSchema .keys({ module: moduleSchema, + buildDependencies: joiIdentifierMap(moduleSchema) + .description("All build dependencies of this module, keyed by name."), }) export interface PluginServiceActionParamsBase extends PluginModuleActionParamsBase { diff --git a/garden-service/test/helpers.ts b/garden-service/test/helpers.ts index d1a9f10774..102b0ea0ba 100644 --- a/garden-service/test/helpers.ts +++ b/garden-service/test/helpers.ts @@ -138,7 +138,9 @@ export const testPlugin: PluginFactory = (): GardenPlugin => { build: buildGenericModule, runModule, - async runService({ ctx, service, interactive, runtimeContext, silent, timeout }: RunServiceParams) { + async runService( + { ctx, service, interactive, runtimeContext, silent, timeout, buildDependencies }: RunServiceParams, + ) { return runModule({ ctx, module: service.module, @@ -147,6 +149,7 @@ export const testPlugin: PluginFactory = (): GardenPlugin => { runtimeContext, silent, timeout, + buildDependencies, }) }, diff --git a/garden-service/test/src/plugins/container.ts b/garden-service/test/src/plugins/container.ts index 7f489cf966..9b47b6c2e9 100644 --- a/garden-service/test/src/plugins/container.ts +++ b/garden-service/test/src/plugins/container.ts @@ -486,7 +486,7 @@ describe("plugins.container", () => { td.replace(helpers, "imageExistsLocally", async () => true) - const result = await getBuildStatus({ ctx, module }) + const result = await getBuildStatus({ ctx, module, buildDependencies: {} }) expect(result).to.eql({ ready: true }) }) @@ -514,7 +514,7 @@ describe("plugins.container", () => { td.replace(helpers, "imageExistsLocally", async () => false) - const result = await getBuildStatus({ ctx, module }) + const result = await getBuildStatus({ ctx, module, buildDependencies: {} }) expect(result).to.eql({ ready: false }) }) }) @@ -547,7 +547,7 @@ describe("plugins.container", () => { td.replace(helpers, "pullImage", async () => null) td.replace(helpers, "imageExistsLocally", async () => false) - const result = await build({ ctx, module }) + const result = await build({ ctx, module, buildDependencies: {} }) expect(result).to.eql({ fetched: true }) }) @@ -581,7 +581,7 @@ describe("plugins.container", () => { const dockerCli = td.replace(helpers, "dockerCli") - const result = await build({ ctx, module }) + const result = await build({ ctx, module, buildDependencies: {} }) expect(result).to.eql({ fresh: true, @@ -618,7 +618,7 @@ describe("plugins.container", () => { td.replace(helpers, "hasDockerfile", async () => false) - const result = await publishModule({ ctx, module }) + const result = await publishModule({ ctx, module, buildDependencies: {} }) expect(result).to.eql({ published: false }) }) @@ -651,7 +651,7 @@ describe("plugins.container", () => { const dockerCli = td.replace(helpers, "dockerCli") - const result = await publishModule({ ctx, module }) + const result = await publishModule({ ctx, module, buildDependencies: {} }) expect(result).to.eql({ message: "Published some/image:12345", published: true }) td.verify(dockerCli(module, "tag some/image:12345 some/image:12345"), { times: 0 }) @@ -687,7 +687,7 @@ describe("plugins.container", () => { const dockerCli = td.replace(helpers, "dockerCli") - const result = await publishModule({ ctx, module }) + const result = await publishModule({ ctx, module, buildDependencies: {} }) expect(result).to.eql({ message: "Published some/image:1.1", published: true }) td.verify(dockerCli(module, "tag some/image:12345 some/image:1.1"))