diff --git a/garden-service/src/plugins/kubernetes/actions.ts b/garden-service/src/plugins/kubernetes/actions.ts index b59e077d61..e0b0e1e925 100644 --- a/garden-service/src/plugins/kubernetes/actions.ts +++ b/garden-service/src/plugins/kubernetes/actions.ts @@ -8,15 +8,12 @@ import * as Bluebird from "bluebird" import * as execa from "execa" -import * as split from "split" import { includes } from "lodash" -import moment = require("moment") import { DeploymentError, ConfigurationError } from "../../exceptions" -import { GetServiceLogsResult, HotReloadResult, RunResult, TestResult } from "../../types/plugin/outputs" +import { HotReloadResult, RunResult, TestResult } from "../../types/plugin/outputs" import { ExecInServiceParams, - GetServiceLogsParams, GetServiceOutputsParams, GetTestResultParams, HotReloadParams, @@ -28,7 +25,7 @@ import { } from "../../types/plugin/params" import { ModuleVersion } from "../../vcs/base" import { ContainerModule, helpers, validateContainerModule } from "../container" -import { deserializeValues, serializeValues, splitFirst } from "../../util/util" +import { deserializeValues, serializeValues } from "../../util/util" import { KubeApi } from "./api" import { getAppNamespace, getMetadataNamespace } from "./namespace" import { kubectl } from "./kubectl" diff --git a/garden-service/src/plugins/kubernetes/logs.ts b/garden-service/src/plugins/kubernetes/logs.ts index f276647864..54a5236d85 100644 --- a/garden-service/src/plugins/kubernetes/logs.ts +++ b/garden-service/src/plugins/kubernetes/logs.ts @@ -8,27 +8,35 @@ import * as split from "split" import moment = require("moment") -import Stream from "ts-stream" -import { GetServiceLogsResult, ServiceLogEntry } from "../../types/plugin/outputs" +import { GetServiceLogsResult } from "../../types/plugin/outputs" import { GetServiceLogsParams } from "../../types/plugin/params" import { ContainerModule } from "../container" import { getAppNamespace } from "./namespace" import { splitFirst } from "../../util/util" import { BinaryCmd } from "../../util/ext-tools" import { kubectl } from "./kubectl" -import { ContainerService } from "../../../tmp/dist/build/plugins/container" -import { LogEntry } from "../../logger/log-entry" -export async function getServiceLogs( - { ctx, log, service, stream, tail }: GetServiceLogsParams, -) { +interface GetKubernetesLogsParams extends GetServiceLogsParams { + context: string + namespace: string + selector: string +} + +export async function getServiceLogs(params: GetServiceLogsParams) { + const { ctx, service } = params const context = ctx.provider.config.context const namespace = await getAppNamespace(ctx, ctx.provider) + const selector = `service=${service.name}` + + return getKubernetesLogs({ ...params, context, namespace, selector }) +} - const proc = tail - ? await tailLogs(context, namespace, service, stream, log) - : await getLogs(context, namespace, service, stream) +export async function getKubernetesLogs(params: GetKubernetesLogsParams) { + // Currently Stern doesn't support just returning the logs and exiting, it can only follow + const proc = params.tail + ? await tailLogs(params) + : await getLogs(params) return new Promise((resolve, reject) => { proc.on("error", reject) @@ -39,20 +47,16 @@ export async function getServiceLogs( }) } -async function tailLogs( - context: string, namespace: string, service: ContainerService, stream: Stream, log: LogEntry, -) { +async function tailLogs({ context, namespace, service, selector, stream, log }: GetKubernetesLogsParams) { const args = [ "--color", "never", "--context", context, "--namespace", namespace, "--output", "json", - "--selector", `service=${service.name}`, + "--selector", selector, "--timestamps", ] - console.log(args.join(" ")) - const proc = await stern.spawn({ args, log }) let timestamp: Date | undefined @@ -73,11 +77,13 @@ async function tailLogs( return proc } -async function getLogs( - context: string, namespace: string, service: ContainerService, stream: Stream, -) { - const resourceType = service.spec.daemon ? "daemonset" : "deployment" - const kubectlArgs = ["logs", `${resourceType}/${service.name}`, "--timestamps=true"] +async function getLogs({ context, namespace, service, selector, stream }: GetKubernetesLogsParams) { + // TODO: do this via API instead of kubectl + const kubectlArgs = [ + "logs", + "--selector", selector, + "--timestamps=true", + ] const proc = kubectl(context, namespace).spawn(kubectlArgs) let timestamp: Date diff --git a/garden-service/src/plugins/openfaas/openfaas.ts b/garden-service/src/plugins/openfaas/openfaas.ts index c023f342b6..d7689951bd 100644 --- a/garden-service/src/plugins/openfaas/openfaas.ts +++ b/garden-service/src/plugins/openfaas/openfaas.ts @@ -21,6 +21,7 @@ import { GetEnvironmentStatusParams, ValidateModuleParams, DeleteServiceParams, + GetServiceLogsParams, } from "../../types/plugin/params" import { ServiceStatus, @@ -53,6 +54,7 @@ import { Provider, providerConfigBaseSchema } from "../../config/project" import { faasCli } from "./faas-cli" import { CleanupEnvironmentParams } from "../../types/plugin/params" import dedent = require("dedent") +import { getKubernetesLogs } from "../kubernetes/logs" const systemProjectPath = join(STATIC_DIR, "openfaas", "system") export const stackFilename = "stack.yml" @@ -209,6 +211,15 @@ export function gardenPlugin({ config }: { config: OpenFaasConfig }): GardenPlug } }, + async getServiceLogs(params: GetServiceLogsParams) { + const { ctx, service } = params + const k8sProvider = getK8sProvider(ctx) + const context = k8sProvider.config.context + const namespace = await getAppNamespace(ctx, k8sProvider) + const selector = `faas_function=${service.name}` + return getKubernetesLogs({ ...params, context, namespace, selector }) + }, + async deployService(params: DeployServiceParams): Promise { const { ctx, module, service, log, runtimeContext } = params