Skip to content

Commit

Permalink
fix: use faas-cli to delete OpenFAAS services
Browse files Browse the repository at this point in the history
  • Loading branch information
thsig committed Sep 20, 2018
1 parent 8d3f366 commit b38113e
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 64 deletions.
2 changes: 1 addition & 1 deletion garden-cli/src/plugins/kubernetes/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export async function deleteService(params: DeleteServiceParams): Promise<Servic
const provider = ctx.provider

await deleteContainerService(
{ provider, namespace, serviceName: service.name, deploymentOnly: false, logEntry })
{ provider, namespace, serviceName: service.name, logEntry })

return getContainerServiceStatus(params)
}
Expand Down
23 changes: 18 additions & 5 deletions garden-cli/src/plugins/kubernetes/deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,18 +323,31 @@ export async function createDeployment(
}

export async function deleteContainerService(
{ namespace, provider, serviceName, deploymentOnly, logEntry },
{ namespace, provider, serviceName, logEntry },
) {

let found = true
const context = provider.config.context
await deleteContainerDeployment({ namespace, provider, serviceName, logEntry })
await deleteObjectsByLabel({
context,
namespace,
labelKey: "service",
labelValue: serviceName,
objectTypes: ["deployment", "service", "ingress"],
includeUninitialized: false,
})

}

export async function deleteContainerDeployment(
{ namespace, provider, serviceName, logEntry },
) {

let found = true
const api = new KubeApi(provider)

try {
await api.extensions.deleteNamespacedDeployment(serviceName, namespace, <any>{})
if (!deploymentOnly) {
await deleteObjectsByLabel(context, namespace, "service", serviceName)
}
} catch (err) {
if (err.code === 404) {
found = false
Expand Down
25 changes: 16 additions & 9 deletions garden-cli/src/plugins/kubernetes/kubectl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ export interface ApplyOptions {
namespace?: string,
}

export interface DeleteOptions {
includeUninitialized?: boolean,
objectTypes?: string[]
}

export const KUBECTL_DEFAULT_TIMEOUT = 300

export class Kubectl {
Expand Down Expand Up @@ -199,12 +194,24 @@ export async function applyMany(
}
}

const defaultObjectTypesForDelete = ["deployment", "service", "ingress"]
export interface DeleteObjectsParams {
context: string,
namespace: string,
labelKey: string,
labelValue: string,
objectTypes: string[],
includeUninitialized?: boolean,
}

export async function deleteObjectsByLabel(
context: string, namespace: string, labelKey: string, labelValue: string,
{ includeUninitialized = false, objectTypes = defaultObjectTypesForDelete }: DeleteOptions = {},
) {
{
context,
namespace,
labelKey,
labelValue,
objectTypes,
includeUninitialized = false,
}: DeleteObjectsParams) {

let args = [
"delete",
Expand Down
44 changes: 44 additions & 0 deletions garden-cli/src/plugins/openfaas/faas-cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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 { builderWorkDir, stackFilename } from "./openfaas"

export interface FaasCliCmdParams {
buildPath: string,
imageId: string,
faasCmd: string,
faasOpts?: string[],
dockerOpts?: string[],
}

export function faasCliCmd(
cmdParams: FaasCliCmdParams,
): string[] {

return [
"docker",
...(faasCliDockerArgs(cmdParams)),
]

}

export function faasCliDockerArgs(
{ buildPath, imageId, faasCmd, faasOpts = [], dockerOpts = [] }: FaasCliCmdParams): string[] {

return [
"run", "-i",
"-v", `${buildPath}:${builderWorkDir}`,
"-v", "/var/run/docker.sock:/var/run/docker.sock",
"--workdir", builderWorkDir,
...dockerOpts,
imageId,
"faas-cli", faasCmd, "-f", stackFilename,
...faasOpts,
]

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,55 +9,56 @@
import * as Joi from "joi"
import { join, resolve } from "path"
import { resolve as urlResolve } from "url"
import { STATIC_DIR } from "../constants"
import { PluginError, ConfigurationError } from "../exceptions"
import { Garden } from "../garden"
import { PluginContext } from "../plugin-context"
import { joiArray, validate, PrimitiveMap } from "../config/common"
import { Module } from "../types/module"
import { ValidateModuleResult } from "../types/plugin/outputs"
import { STATIC_DIR } from "../../constants"
import { PluginError, ConfigurationError } from "../../exceptions"
import { Garden } from "../../garden"
import { PluginContext } from "../../plugin-context"
import { joiArray, validate, PrimitiveMap } from "../../config/common"
import { Module } from "../../types/module"
import { ValidateModuleResult } from "../../types/plugin/outputs"
import {
PrepareEnvironmentParams,
GetEnvironmentStatusParams,
ValidateModuleParams,
DeleteServiceParams,
} from "../types/plugin/params"
} from "../../types/plugin/params"
import {
ServiceStatus,
ServiceIngress,
Service,
} from "../types/service"
} from "../../types/service"
import {
buildGenericModule,
GenericModuleSpec,
genericModuleSpecSchema,
GenericTestSpec,
testGenericModule,
getGenericModuleBuildStatus,
} from "./generic"
import { KubernetesProvider } from "./kubernetes/kubernetes"
import { getNamespace, getAppNamespace } from "./kubernetes/namespace"
} from "../generic"
import { KubernetesProvider } from "../kubernetes/kubernetes"
import { getNamespace, getAppNamespace } from "../kubernetes/namespace"
import {
DeployServiceParams,
GetServiceStatusParams,
BuildModuleParams,
GetServiceOutputsParams,
} from "../types/plugin/params"
} from "../../types/plugin/params"
import { every, values } from "lodash"
import { dumpYaml, findByName } from "../util/util"
import { dumpYaml, findByName } from "../../util/util"
import * as execa from "execa"
import { KubeApi } from "./kubernetes/api"
import { waitForObjects, checkDeploymentStatus } from "./kubernetes/status"
import { systemSymbol } from "./kubernetes/system"
import { BaseServiceSpec } from "../config/service"
import { GardenPlugin } from "../types/plugin/plugin"
import { deleteContainerService } from "./kubernetes/deployment"
import { Provider, providerConfigBaseSchema } from "../config/project"
import { KubeApi } from "../kubernetes/api"
import { waitForObjects, checkDeploymentStatus } from "../kubernetes/status"
import { systemSymbol } from "../kubernetes/system"
import { BaseServiceSpec } from "../../config/service"
import { GardenPlugin } from "../../types/plugin/plugin"
import { Provider, providerConfigBaseSchema } from "../../config/project"
import dedent = require("dedent")
import { faasCliCmd, faasCliDockerArgs } from "./faas-cli"

const systemProjectPath = join(STATIC_DIR, "openfaas", "system")
const stackFilename = "stack.yml"
const builderWorkDir = "/wd"
export const stackFilename = "stack.yml"
export const builderWorkDir = "/wd"
export const FAAS_CLI_IMAGE_ID = "openfaas/faas-cli:0.7.3"

export interface OpenFaasModuleSpec extends GenericModuleSpec {
handler: string
Expand Down Expand Up @@ -151,14 +152,11 @@ export function gardenPlugin({ config }: { config: OpenFaasConfig }): GardenPlug
)

// 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.command = faasCliCmd({
buildPath: `\${modules.${moduleConfig.name}.buildPath}`,
imageId: `openfaas--builder:\${modules.openfaas--builder.version}`,
faasCmd: "build",
})

moduleConfig.build.dependencies.push({
name: "builder",
Expand Down Expand Up @@ -216,15 +214,12 @@ export function gardenPlugin({ config }: { config: OpenFaasConfig }): GardenPlug
await writeStackFile(ctx, module, runtimeContext.envVars)

// use faas-cli to do the deployment
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,
])
await execa("docker", faasCliDockerArgs({
buildPath: module.buildPath,
imageId: FAAS_CLI_IMAGE_ID,
faasCmd: "deploy",
dockerOpts: ["--net", "host"],
}))

// wait until deployment is ready
const k8sProvider = getK8sProvider(ctx)
Expand All @@ -240,16 +235,37 @@ export function gardenPlugin({ config }: { config: OpenFaasConfig }): GardenPlug
},

async deleteService(params: DeleteServiceParams<OpenFaasModule>): Promise<ServiceStatus> {
const { ctx, logEntry, service } = params
const provider = getK8sProvider(ctx)
const namespace = await getAppNamespace(ctx, provider)
const { ctx, logEntry, service, runtimeContext } = params
let status
let found = true

try {

status = await getServiceStatus({
ctx,
service,
runtimeContext,
module: service.module,
})

found = !!status.state

await execa("docker", faasCliDockerArgs({
buildPath: service.module.buildPath,
imageId: FAAS_CLI_IMAGE_ID,
faasCmd: "remove",
dockerOpts: ["--net", "host"],
}))

} catch (err) {
found = false
}

await deleteContainerService({
namespace, provider, serviceName: service.name,
deploymentOnly: true, logEntry,
})
if (logEntry) {
found ? logEntry.setSuccess("Service deleted") : logEntry.setWarn("Service not deployed")
}

return await getServiceStatus(params)
return status
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion garden-cli/src/plugins/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const builtinPlugins: RegisterPluginParam[] = [
"./kubernetes/local",
"./npm-package",
"./google/google-app-engine",
"./openfaas",
"./openfaas/openfaas",
].map(p => resolve(__dirname, p))

// These plugins are always loaded
Expand Down

0 comments on commit b38113e

Please sign in to comment.