Skip to content

Commit

Permalink
improvement(k8s): default in-cluster registry namespace to project name
Browse files Browse the repository at this point in the history
This means that by default builds are shared between users when sharing
a cluster. Image _layers_ were anyway shared, but this change will
accelerate builds and tests through reducing the number of steps
involved when all layers already exist.

Co-authored-by: swist <[email protected]>
  • Loading branch information
swist authored and eysi09 committed Mar 5, 2020
1 parent 4babaef commit 7ed4648
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 8 deletions.
4 changes: 3 additions & 1 deletion garden-service/src/plugins/kubernetes/kubernetes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ export async function configureProvider({
// to make sure every node in the cluster can resolve the image from the registry we deploy in-cluster.
config.deploymentRegistry = {
hostname: inClusterRegistryHostname,
namespace: config.namespace,
// Default to use the project name as the namespace in the in-cluster registry, if none is explicitly
// configured. This allows users to share builds for a project.
namespace: config.deploymentRegistry?.namespace || projectName,
}
config._systemServices.push("docker-registry", "registry-proxy")
}
Expand Down
9 changes: 7 additions & 2 deletions garden-service/test/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { mapValues, fromPairs } from "lodash"
import { ModuleVersion } from "../src/vcs/vcs"
import { GARDEN_SERVICE_ROOT, LOCAL_CONFIG_FILENAME } from "../src/constants"
import { EventBus, Events } from "../src/events"
import { ValueOf } from "../src/util/util"
import { ValueOf, exec } from "../src/util/util"
import { LogEntry } from "../src/logger/log-entry"
import timekeeper = require("timekeeper")
import { GLOBAL_OPTIONS, GlobalOptions } from "../src/cli/cli"
Expand Down Expand Up @@ -507,10 +507,15 @@ export type TempDirectory = tmp.DirectoryResult
/**
* Create a temp directory. Make sure to clean it up after use using the `cleanup()` method on the returned object.
*/
export async function makeTempDir(): Promise<TempDirectory> {
export async function makeTempDir({ git = false } = {}): Promise<TempDirectory> {
const tmpDir = await tmp.dir({ unsafeCleanup: true })
// Fully resolve path so that we don't get path mismatches in tests
tmpDir.path = await realpath(tmpDir.path)

if (git) {
await exec("git", ["init"], { cwd: tmpDir.path })
}

return tmpDir
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { clusterInit } from "../../../../../../src/plugins/kubernetes/commands/c

const root = getDataDir("test-projects", "container")
const defaultEnvironment = process.env.GARDEN_INTEG_TEST_MODE === "remote" ? "cluster-docker" : "local"
let initialized = false
let initializedEnv: string
let localInstance: Garden

export async function getContainerTestGarden(environmentName: string = defaultEnvironment) {
Expand All @@ -41,7 +41,9 @@ export async function getContainerTestGarden(environmentName: string = defaultEn
localInstance = await makeTestGarden(root, { environmentName: "local" })
}

if (!initialized && environmentName !== "local") {
const needsInit = !environmentName.startsWith("local") && initializedEnv !== environmentName

if (needsInit) {
// Load the test authentication for private registries
const localProvider = <KubernetesProvider>await localInstance.resolveProvider("local-kubernetes")
const api = await KubeApi.factory(garden.log, localProvider)
Expand Down Expand Up @@ -74,11 +76,10 @@ export async function getContainerTestGarden(environmentName: string = defaultEn
const provider = <KubernetesProvider>await garden.resolveProvider("local-kubernetes")
const ctx = garden.getPluginContext(provider)

// We only need to run the cluster-init flow once, because the configurations are compatible
if (!initialized && environmentName !== "local") {
if (needsInit) {
// Run cluster-init
await clusterInit.handler({ ctx, log: garden.log })
initialized = true
initializedEnv = environmentName
}

return garden
Expand Down
94 changes: 94 additions & 0 deletions garden-service/test/unit/src/plugins/kubernetes/kubernetes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2018-2020 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 { configureProvider } from "../../../../../src/plugins/kubernetes/kubernetes"
import { KubernetesConfig, defaultResources, defaultStorage } from "../../../../../src/plugins/kubernetes/config"
import { defaultSystemNamespace } from "../../../../../src/plugins/kubernetes/system"
import { makeDummyGarden } from "../../../../../src/cli/cli"
import { expect } from "chai"
import { TempDirectory, makeTempDir } from "../../../../helpers"

describe("kubernetes configureProvider", () => {
const basicConfig: KubernetesConfig = {
name: "kubernetes",
buildMode: "local-docker",
context: "my-cluster",
defaultHostname: "my.domain.com",
forceSsl: false,
gardenSystemNamespace: defaultSystemNamespace,
imagePullSecrets: [],
ingressClass: "nginx",
ingressHttpPort: 80,
ingressHttpsPort: 443,
resources: defaultResources,
storage: defaultStorage,
registryProxyTolerations: [],
tlsCertificates: [],
_systemServices: [],
}

let tmpDir: TempDirectory

beforeEach(async () => {
tmpDir = await makeTempDir({ git: true })
})

afterEach(async () => {
await tmpDir.cleanup()
})

context("cluster-docker mode", () => {
it("should set a default deploymentRegistry with projectName as namespace", async () => {
const garden = await makeDummyGarden(tmpDir.path)
const config: KubernetesConfig = {
...basicConfig,
buildMode: "cluster-docker",
}

const result = await configureProvider({
projectName: garden.projectName,
projectRoot: garden.projectRoot,
config,
log: garden.log,
dependencies: [],
configStore: garden.configStore,
})

expect(result.config.deploymentRegistry).to.eql({
hostname: "127.0.0.1:5000",
namespace: garden.projectName,
})
})

it("should allow overriding the deploymentRegistry namespace for the in-cluster registry", async () => {
const garden = await makeDummyGarden(tmpDir.path)
const config: KubernetesConfig = {
...basicConfig,
buildMode: "cluster-docker",
deploymentRegistry: {
hostname: "127.0.0.1:5000",
namespace: "my-namespace",
},
}

const result = await configureProvider({
projectName: garden.projectName,
projectRoot: garden.projectRoot,
config,
log: garden.log,
dependencies: [],
configStore: garden.configStore,
})

expect(result.config.deploymentRegistry).to.eql({
hostname: "127.0.0.1:5000",
namespace: "my-namespace",
})
})
})
})

0 comments on commit 7ed4648

Please sign in to comment.