diff --git a/garden-cli/src/config/config-context.ts b/garden-cli/src/config/config-context.ts index e8e7e10283..0782e734df 100644 --- a/garden-cli/src/config/config-context.ts +++ b/garden-cli/src/config/config-context.ts @@ -197,10 +197,18 @@ class ModuleContext extends ConfigContext { @schema(Joi.string().description("The current version of the module.").example(exampleVersion)) public version: string + @schema( + Joi.string() + .description("The build path of the module.") + .example("/home/me/code/my-project/.garden/build/my-module"), + ) + public buildPath: string + constructor(root: ConfigContext, module: Module) { super(root) this.path = module.path this.version = module.version.versionString + this.buildPath = module.buildPath } } diff --git a/garden-cli/src/plugins/openfaas.ts b/garden-cli/src/plugins/openfaas.ts index 9698e070f0..4193eb7c48 100644 --- a/garden-cli/src/plugins/openfaas.ts +++ b/garden-cli/src/plugins/openfaas.ts @@ -53,9 +53,11 @@ import { BaseServiceSpec } from "../config/service" import { GardenPlugin } from "../types/plugin/plugin" import { deleteContainerService } from "./kubernetes/deployment" import { Provider, providerConfigBaseSchema } from "../config/project" +import dedent = require("dedent") const systemProjectPath = join(STATIC_DIR, "openfaas", "system") const stackFilename = "stack.yml" +const builderWorkDir = "/wd" export interface OpenFaasModuleSpec extends GenericModuleSpec { handler: string @@ -91,9 +93,12 @@ const configSchema = providerConfigBaseSchema .keys({ hostname: Joi.string() .hostname() - .description( - "The hostname to configure for the function gateway. " + - "Defaults to the default hostname of the configured Kubernetes provider.", + .description(dedent` + The hostname to configure for the function gateway. + Defaults to the default hostname of the configured Kubernetes provider. + + Important: If you have other types of services, this should be different from their ingress hostnames, + or the other services should not expose paths under /function and /system to avoid routing conflicts.`, ) .example("functions.mydomain.com"), }) @@ -104,7 +109,7 @@ export function gardenPlugin({ config }: { config: OpenFaasConfig }): GardenPlug config = validate(config, configSchema, { context: "OpenFaaS provider config" }) return { - modules: [join(STATIC_DIR, "openfaas", "openfaas-builder")], + modules: [join(STATIC_DIR, "openfaas", "builder")], actions: { async getEnvironmentStatus({ ctx }: GetEnvironmentStatusParams) { const ofGarden = await getOpenFaasGarden(ctx) @@ -145,15 +150,20 @@ export function gardenPlugin({ config }: { config: OpenFaasConfig }): GardenPlug { context: `module ${moduleConfig.name}` }, ) - // stack.yml is populated in the build handler below - moduleConfig.build.command = ["./faas-cli", "build", "-f", stackFilename] + // FIXME: this feels too magicky and convoluted, we should make this type of flow feel more natural + moduleConfig.build.command = [ + "docker", "run", "-i", + "-v", `\${modules.${moduleConfig.name}.buildPath}:${builderWorkDir}`, + "-v", "/var/run/docker.sock:/var/run/docker.sock", + "--workdir", builderWorkDir, + `openfaas--builder:\${modules.openfaas--builder.version}`, + "faas-cli", "build", "-f", stackFilename, + ] moduleConfig.build.dependencies.push({ - name: "openfaas-builder", + name: "builder", plugin: "openfaas", - copy: [ - { source: "*", target: "." }, - ], + copy: [], }) moduleConfig.serviceConfigs = [{ @@ -206,9 +216,15 @@ export function gardenPlugin({ config }: { config: OpenFaasConfig }): GardenPlug await writeStackFile(ctx, module, runtimeContext.envVars) // use faas-cli to do the deployment - await execa("./faas-cli", ["deploy", "-f", stackFilename], { - cwd: module.buildPath, - }) + await execa("docker", [ + "run", "-i", + "-v", `${module.buildPath}:${builderWorkDir}`, + "-v", "/var/run/docker.sock:/var/run/docker.sock", + "--workdir", builderWorkDir, + "--net", "host", + "openfaas/faas-cli:0.7.3", + "faas-cli", "deploy", "-f", stackFilename, + ]) // wait until deployment is ready const k8sProvider = getK8sProvider(ctx) @@ -252,7 +268,7 @@ async function writeStackFile( functions: { [module.name]: { lang: module.spec.lang, - handler: resolve(module.path, module.spec.handler), + handler: resolve(builderWorkDir, module.spec.handler), image, environment: envVars, }, @@ -404,7 +420,7 @@ export async function getOpenFaasGarden(ctx: PluginContext): Promise { dirname: "system", path: systemProjectPath, project: { - name: "garden-openfaas-system", + name: `${ctx.projectName}-openfaas`, environmentDefaults: { providers: [], variables: {}, diff --git a/garden-cli/static/openfaas/builder/Dockerfile b/garden-cli/static/openfaas/builder/Dockerfile new file mode 100644 index 0000000000..912672f496 --- /dev/null +++ b/garden-cli/static/openfaas/builder/Dockerfile @@ -0,0 +1,6 @@ +FROM openfaas/faas-cli:0.7.3 + +WORKDIR /build + +RUN apk add docker +RUN faas-cli template pull diff --git a/garden-cli/static/openfaas/builder/garden.yml b/garden-cli/static/openfaas/builder/garden.yml new file mode 100644 index 0000000000..3642ebd240 --- /dev/null +++ b/garden-cli/static/openfaas/builder/garden.yml @@ -0,0 +1,4 @@ +module: + description: Base image used for building openfaas modules + name: builder + type: container diff --git a/garden-cli/static/openfaas/openfaas-builder/bootstrap.sh b/garden-cli/static/openfaas/openfaas-builder/bootstrap.sh deleted file mode 100755 index 62ae849c38..0000000000 --- a/garden-cli/static/openfaas/openfaas-builder/bootstrap.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -set -e - -cli_filename="faas-cli" - -if [ "${PLATFORM}" = "darwin" ]; then - cli_filename="faas-cli-darwin" -elif [ "${PLATFORM}" = "win32" ]; then - cli_filename="faas-cli.exe" -fi - -# use npx for cross-platform compatibility -npx node-wget -- https://github.com/openfaas/faas-cli/releases/download/0.6.15/${cli_filename} -mv ${cli_filename} faas-cli || true -chmod +x faas-cli - -./faas-cli template pull diff --git a/garden-cli/static/openfaas/openfaas-builder/garden.yml b/garden-cli/static/openfaas/openfaas-builder/garden.yml deleted file mode 100644 index 72b70eb260..0000000000 --- a/garden-cli/static/openfaas/openfaas-builder/garden.yml +++ /dev/null @@ -1,8 +0,0 @@ -module: - description: Base image used for building openfaas modules - name: openfaas-builder - type: generic - build: - command: [./bootstrap.sh] - env: - PLATFORM: ${local.platform} diff --git a/garden-cli/static/openfaas/system/openfaas-system/garden.yml b/garden-cli/static/openfaas/system/openfaas-system/garden.yml index 89d487564d..91de585553 100644 --- a/garden-cli/static/openfaas/system/openfaas-system/garden.yml +++ b/garden-cli/static/openfaas/system/openfaas-system/garden.yml @@ -4,7 +4,7 @@ module: type: helm repo: https://openfaas.github.io/faas-netes/ chart: openfaas - version: 1.2.2 + version: 1.2.3 parameters: exposeServices: false functionNamespace: ${variables.function-namespace} @@ -14,7 +14,11 @@ module: - host: ${variables.gateway-hostname} serviceName: gateway servicePort: 8080 - path: / + path: /function/ + - host: ${variables.gateway-hostname} + serviceName: gateway + servicePort: 8080 + path: /system/ faasnetesd: imagePullPolicy: IfNotPresent securityContext: false