Skip to content

Commit

Permalink
fix(k8s): issues with remote cluster deployments
Browse files Browse the repository at this point in the history
  • Loading branch information
edvald committed Mar 19, 2019
1 parent 864468e commit 982e6e2
Show file tree
Hide file tree
Showing 24 changed files with 139 additions and 89 deletions.
6 changes: 3 additions & 3 deletions garden-service/src/commands/run/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/

import chalk from "chalk"
import { BuildTask } from "../../tasks/build"
import { RunResult } from "../../types/plugin/outputs"
import {
BooleanParameter,
Expand All @@ -25,6 +24,7 @@ import { printRuntimeContext } from "./run"
import dedent = require("dedent")
import { prepareRuntimeContext } from "../../types/service"
import { logHeader } from "../../logger/util"
import { PushTask } from "../../tasks/push"

const runArgs = {
module: new StringParameter({
Expand Down Expand Up @@ -90,8 +90,8 @@ export class RunModuleCommand extends Command<Args, Opts> {

await garden.actions.prepareEnvironment({ log })

const buildTask = new BuildTask({ garden, log, module, force: opts["force-build"] })
await garden.addTask(buildTask)
const pushTask = new PushTask({ garden, log, module, force: opts["force-build"] })
await garden.addTask(pushTask)
await garden.processTasks()

const command = args.command || []
Expand Down
6 changes: 3 additions & 3 deletions garden-service/src/commands/run/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/

import chalk from "chalk"
import { BuildTask } from "../../tasks/build"
import { RunResult } from "../../types/plugin/outputs"
import {
BooleanParameter,
Expand All @@ -20,6 +19,7 @@ import { printRuntimeContext } from "./run"
import dedent = require("dedent")
import { prepareRuntimeContext } from "../../types/service"
import { logHeader } from "../../logger/util"
import { PushTask } from "../../tasks/push"

const runArgs = {
service: new StringParameter({
Expand Down Expand Up @@ -67,8 +67,8 @@ export class RunServiceCommand extends Command<Args, Opts> {

await garden.actions.prepareEnvironment({ log })

const buildTask = new BuildTask({ garden, log, module, force: opts["force-build"] })
await garden.addTask(buildTask)
const pushTask = new PushTask({ garden, log, module, force: opts["force-build"] })
await garden.addTask(pushTask)
await garden.processTasks()

const dependencies = await graph.getServices(module.serviceDependencyNames)
Expand Down
6 changes: 3 additions & 3 deletions garden-service/src/commands/run/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import chalk from "chalk"
import { ParameterError } from "../../exceptions"
import { BuildTask } from "../../tasks/build"
import { RunResult } from "../../types/plugin/outputs"
import {
findByName,
Expand All @@ -25,6 +24,7 @@ import { printRuntimeContext } from "./run"
import dedent = require("dedent")
import { prepareRuntimeContext } from "../../types/service"
import { logHeader } from "../../logger/util"
import { PushTask } from "../../tasks/push"

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

await garden.actions.prepareEnvironment({ log })

const buildTask = new BuildTask({ garden, log, module, force: opts["force-build"] })
await garden.addTask(buildTask)
const pushTask = new PushTask({ garden, log, module, force: opts["force-build"] })
await garden.addTask(pushTask)
await garden.processTasks()

const interactive = opts.interactive
Expand Down
11 changes: 11 additions & 0 deletions garden-service/src/plugins/container/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { keyBy } from "lodash"
import { containerHelpers } from "./helpers"
import { ContainerModule, containerModuleSpecSchema } from "./config"
import { buildContainerModule, getContainerBuildStatus } from "./build"
import { KubernetesProvider } from "../kubernetes/kubernetes"

export async function configureContainerModule({ ctx, moduleConfig }: ConfigureModuleParams<ContainerModule>) {
moduleConfig.spec = validateWithPath({
Expand Down Expand Up @@ -136,6 +137,16 @@ export async function configureContainerModule({ ctx, moduleConfig }: ConfigureM
)
}

const provider = <KubernetesProvider>ctx.provider
const deploymentImageName = await containerHelpers.getDeploymentImageName(
moduleConfig,
provider.config.deploymentRegistry,
)

moduleConfig.outputs = {
"deployment-image-name": deploymentImageName,
}

return moduleConfig
}

Expand Down
33 changes: 23 additions & 10 deletions garden-service/src/plugins/container/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import { join } from "path"
import { ConfigurationError } from "../../exceptions"
import { splitFirst, spawn } from "../../util/util"
import { ModuleConfig } from "../../config/module"
import { ContainerModule, ContainerRegistryConfig, defaultTag, defaultNamespace } from "./config"
import { ContainerModule, ContainerRegistryConfig, defaultTag, defaultNamespace, ContainerModuleConfig } from "./config"

interface ParsedImageId {
host?: string
namespace?: string
repository: string
tag: string
tag?: string
}

function getDockerfilePath(basePath: string, dockerfile?: string) {
Expand Down Expand Up @@ -78,24 +78,37 @@ export const containerHelpers = {
},

/**
* Returns the image ID to be used when pushing to deployment registries.
* Returns the image name (sans tag/version) to be used when pushing to deployment registries.
*/
async getDeploymentImageId(module: ContainerModule, registryConfig?: ContainerRegistryConfig) {
const localId = await containerHelpers.getLocalImageId(module)
async getDeploymentImageName(moduleConfig: ContainerModuleConfig, registryConfig?: ContainerRegistryConfig) {
const localName = moduleConfig.spec.image || moduleConfig.name
const parsedId = containerHelpers.parseImageId(localName)
const withoutVersion = containerHelpers.unparseImageId({ ...parsedId, tag: undefined })

if (!registryConfig) {
return localId
return withoutVersion
}

const parsedId = containerHelpers.parseImageId(localId)

const host = registryConfig.port ? `${registryConfig.hostname}:${registryConfig.port}` : registryConfig.hostname

return containerHelpers.unparseImageId({
host,
namespace: registryConfig.namespace,
repository: parsedId.repository,
tag: parsedId.tag,
tag: undefined,
})
},

/**
* Returns the image ID to be used when pushing to deployment registries. This always has the module version
* set as the tag.
*/
async getDeploymentImageId(module: ContainerModule, registryConfig?: ContainerRegistryConfig) {
const imageName = await containerHelpers.getDeploymentImageName(module, registryConfig)

return containerHelpers.unparseImageId({
repository: imageName,
tag: module.version.versionString,
})
},

Expand Down Expand Up @@ -138,7 +151,7 @@ export const containerHelpers = {
},

unparseImageId(parsed: ParsedImageId) {
const name = `${parsed.repository}:${parsed.tag}`
const name = parsed.tag ? `${parsed.repository}:${parsed.tag}` : parsed.repository

if (parsed.host) {
return `${parsed.host}/${parsed.namespace || defaultNamespace}/${name}`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,5 +431,5 @@ export async function pushModule({ ctx, module, log }: PushModuleParams<Containe
await containerHelpers.dockerCli(module, ["tag", localId, remoteId])
await containerHelpers.dockerCli(module, ["push", remoteId])

return { pushed: true, message: `Pushed ${localId}` }
return { pushed: true, message: `Pushed ${remoteId}` }
}
24 changes: 13 additions & 11 deletions garden-service/src/plugins/kubernetes/container/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { kubectl } from "../kubectl"
import { getContainerServiceStatus } from "./status"
import { runPod } from "../run"
import { containerHelpers } from "../../container/helpers"
import { KubernetesPluginContext } from "../kubernetes"
import { KubernetesPluginContext, KubernetesProvider } from "../kubernetes"

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

export async function runContainerModule(
{
ctx, module, command, ignoreError = true, interactive, runtimeContext, timeout,
ctx, log, module, command, ignoreError = true, interactive, runtimeContext, timeout,
}: RunModuleParams<ContainerModule>,
): Promise<RunResult> {
const k8sCtx = <KubernetesPluginContext>ctx
const context = k8sCtx.provider.config.context
const namespace = await getAppNamespace(k8sCtx, k8sCtx.provider)
const image = await containerHelpers.getLocalImageId(module)
const provider = <KubernetesProvider>ctx.provider
const context = provider.config.context
const namespace = await getAppNamespace(ctx, provider)
const image = await containerHelpers.getDeploymentImageId(module, provider.config.deploymentRegistry)

return runPod({
context,
Expand All @@ -96,6 +96,7 @@ export async function runContainerModule(
interactive,
ignoreError,
timeout,
log,
})
}

Expand All @@ -114,14 +115,14 @@ export async function runContainerService(
}

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

const k8sCtx = <KubernetesPluginContext>ctx
const context = k8sCtx.provider.config.context
const namespace = await getAppNamespace(k8sCtx, k8sCtx.provider)
const image = await containerHelpers.getLocalImageId(module)
const provider = <KubernetesProvider>ctx.provider
const context = provider.config.context
const namespace = await getAppNamespace(ctx, provider)
const image = await containerHelpers.getDeploymentImageId(module, provider.config.deploymentRegistry)

const result = await runPod({
context,
Expand All @@ -135,6 +136,7 @@ export async function runContainerTask(
timeout: task.spec.timeout || 9999,
// Workaround to make sure sidecars are not injected, due to https://github.com/kubernetes/kubernetes/issues/25908
overrides: { metadata: { annotations: { "sidecar.istio.io/inject": "false" } } },
log,
})

return {
Expand Down
2 changes: 2 additions & 0 deletions garden-service/src/plugins/kubernetes/helm/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export async function runHelmModule(
interactive,
ignoreError,
timeout,
log,
})
}

Expand All @@ -70,6 +71,7 @@ export async function runHelmTask(
interactive,
ignoreError: false,
timeout,
log,
})

return {
Expand Down
1 change: 1 addition & 0 deletions garden-service/src/plugins/kubernetes/helm/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export async function testHelmModule(
interactive,
ignoreError: true,
timeout,
log,
})

return storeTestResult({ ctx: k8sCtx, module, testName, result })
Expand Down
8 changes: 2 additions & 6 deletions garden-service/src/plugins/kubernetes/kubectl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface ApplyOptions {
export const KUBECTL_DEFAULT_TIMEOUT = 300

export class Kubectl {
public context?: string
public context: string
public namespace?: string
public configPath?: string

Expand Down Expand Up @@ -52,16 +52,12 @@ export class Kubectl {
}

private prepareArgs(args: string[]) {
const opts: string[] = []
const opts: string[] = [`--context=${this.context}`]

if (this.namespace) {
opts.push(`--namespace=${this.namespace}`)
}

if (this.context) {
opts.push(`--context=${this.context}`)
}

if (this.configPath) {
opts.push(`--kubeconfig=${this.configPath}`)
}
Expand Down
2 changes: 1 addition & 1 deletion garden-service/src/plugins/kubernetes/kubernetes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export interface KubernetesBaseConfig extends ProviderConfig {
}

export interface KubernetesConfig extends KubernetesBaseConfig {
deploymentRegistry: ContainerRegistryConfig
deploymentRegistry?: ContainerRegistryConfig
}

export type KubernetesProvider = Provider<KubernetesConfig>
Expand Down
4 changes: 0 additions & 4 deletions garden-service/src/plugins/kubernetes/local/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,6 @@ export async function configureProvider({ config, log, projectName }: ConfigureP
name: config.name,
context,
defaultHostname,
deploymentRegistry: {
hostname: "foo.garden", // this is not used by this plugin, but required by the base plugin
namespace: "_",
},
forceSsl: false,
imagePullSecrets: config.imagePullSecrets,
ingressHttpPort: 80,
Expand Down
1 change: 1 addition & 0 deletions garden-service/src/plugins/kubernetes/local/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export function gardenPlugin(): GardenPlugin {

// no need to push before deploying locally
delete plugin.moduleActions!.container.pushModule
delete plugin.moduleActions!["maven-container"].pushModule

return plugin
}
6 changes: 5 additions & 1 deletion garden-service/src/plugins/kubernetes/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { RunResult } from "../../types/plugin/outputs"
import { kubectl } from "./kubectl"
import { PrimitiveMap } from "../../config/common"
import { Module } from "../../types/module"
import { LogEntry } from "../../logger/log-entry"

interface RunPodParams {
context: string,
Expand All @@ -22,10 +23,11 @@ interface RunPodParams {
ignoreError: boolean,
timeout?: number,
overrides?: any,
log: LogEntry,
}

export async function runPod(
{ context, namespace, module, image, envVars, args, interactive, ignoreError, timeout, overrides }: RunPodParams,
{ context, namespace, module, image, envVars, args, interactive, ignoreError, timeout, overrides, log }: RunPodParams,
): Promise<RunResult> {
const envArgs = Object.entries(envVars).map(([k, v]) => `--env=${k}=${v}`)

Expand Down Expand Up @@ -59,6 +61,8 @@ export async function runPod(
commandStr,
]

log.verbose(`Running kubectl ${kubecmd.join(" ")}`)

const startedAt = new Date()

const res = await kubectl(context, namespace).call(kubecmd, {
Expand Down
5 changes: 3 additions & 2 deletions garden-service/src/tasks/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { BaseTask } from "../tasks/base"
import { Garden } from "../garden"
import { DependencyGraphNodeType } from "../config-graph"
import { LogEntry } from "../logger/log-entry"
import { PushTask } from "./push"

export interface BuildTaskParams {
garden: Garden
Expand All @@ -39,12 +40,12 @@ export class BuildTask extends BaseTask {
this.hotReloadServiceNames = hotReloadServiceNames
}

async getDependencies(): Promise<BuildTask[]> {
async getDependencies() {
const dg = await this.garden.getConfigGraph()
const deps = (await dg.getDependencies(this.depType, this.getName(), false)).build

return Bluebird.map(deps, async (m: Module) => {
return new BuildTask({
return new PushTask({
garden: this.garden,
log: this.log,
module: m,
Expand Down
Loading

0 comments on commit 982e6e2

Please sign in to comment.