diff --git a/garden-service/src/plugin-context.ts b/garden-service/src/plugin-context.ts index 165255a2377..1de0a38391f 100644 --- a/garden-service/src/plugin-context.ts +++ b/garden-service/src/plugin-context.ts @@ -13,11 +13,13 @@ import { projectNameSchema, projectSourcesSchema, environmentNameSchema } from " import { PluginError } from "./exceptions" import { defaultProvider, Provider, providerSchema, ProviderConfig } from "./config/provider" import { configStoreSchema } from "./config-store" +import { deline } from "./util/string" type WrappedFromGarden = Pick{ relativeOnly: true }) .description("The absolute path of the project root."), + gardenDirPath: Joi.string() + .uri({ relativeOnly: true }) + .description(deline` + The absolute path of the project's Garden dir. This is the directory the contains builds, logs and + other meta data. A custom path can be set when initialising the Garden class. Defaults to \`.garden\`. + `), projectSources: projectSourcesSchema, configStore: configStoreSchema, environmentName: environmentNameSchema, @@ -59,6 +67,7 @@ export async function createPluginContext(garden: Garden, providerName: string): environmentName: garden.environmentName, projectName: garden.projectName, projectRoot: garden.projectRoot, + gardenDirPath: garden.gardenDirPath, projectSources: cloneDeep(garden.projectSources), configStore: garden.configStore, provider, diff --git a/garden-service/src/plugins/kubernetes/init.ts b/garden-service/src/plugins/kubernetes/init.ts index 6974fdfed1b..2bb0e69f06f 100644 --- a/garden-service/src/plugins/kubernetes/init.ts +++ b/garden-service/src/plugins/kubernetes/init.ts @@ -36,7 +36,7 @@ export async function getEnvironmentStatus({ ctx, log }: GetEnvironmentStatusPar const k8sCtx = ctx const variables = getVariables(k8sCtx.provider.config) - const sysGarden = await getSystemGarden(k8sCtx.provider, variables || {}) + const sysGarden = await getSystemGarden(k8sCtx, variables || {}) const sysCtx = await sysGarden.getPluginContext(k8sCtx.provider.name) let systemReady = true @@ -72,9 +72,9 @@ export async function getEnvironmentStatus({ ctx, log }: GetEnvironmentStatusPar const systemServiceStatuses = await getSystemServiceStatus({ ctx: k8sCtx, log, + sysGarden, namespace, serviceNames: systemServiceNames, - variables: variables || {}, }) systemReady = systemTillerReady && sysNamespaceUpToDate && ( @@ -131,7 +131,7 @@ export async function prepareEnvironment({ ctx, log, force, status }: PrepareEnv if (systemServiceNames.length > 0 && !systemReady) { // Install Tiller to system namespace - const sysGarden = await getSystemGarden(k8sCtx.provider, variables || {}) + const sysGarden = await getSystemGarden(k8sCtx, variables || {}) const sysCtx = await sysGarden.getPluginContext(k8sCtx.provider.name) await installTiller({ ctx: sysCtx, provider: sysCtx.provider, log, force }) @@ -140,11 +140,11 @@ export async function prepareEnvironment({ ctx, log, force, status }: PrepareEnv // Install system services await prepareSystemServices({ log, + sysGarden, namespace, force, ctx: k8sCtx, serviceNames: systemServiceNames, - variables: variables || {}, }) } diff --git a/garden-service/src/plugins/kubernetes/system.ts b/garden-service/src/plugins/kubernetes/system.ts index c5b6ed2e3a8..505901ad176 100644 --- a/garden-service/src/plugins/kubernetes/system.ts +++ b/garden-service/src/plugins/kubernetes/system.ts @@ -37,8 +37,17 @@ export function isSystemGarden(provider: KubernetesProvider): boolean { return provider.config._system === systemSymbol } -export async function getSystemGarden(provider: KubernetesProvider, variables: PrimitiveMap): Promise { +/** + * Note that we initialise system Garden with a custom Garden dir path. This is because + * the system modules are stored in the static directory but we want their build products + * stored at the project level. This way we can run several Garden processes at the same time + * without them all modifying the same system build directory, which can cause unexpected issues. + */ +export async function getSystemGarden( + ctx: KubernetesPluginContext, variables: PrimitiveMap, +): Promise { return Garden.factory(systemProjectPath, { + gardenDirPath: getSystemGardenDirPath(ctx.gardenDirPath), environmentName: "default", config: { path: systemProjectPath, @@ -52,7 +61,7 @@ export async function getSystemGarden(provider: KubernetesProvider, variables: P providers: [ { name: "local-kubernetes", - context: provider.config.context, + context: ctx.provider.config.context, namespace: systemNamespace, _system: systemSymbol, _systemServices: [], @@ -117,18 +126,17 @@ export async function recreateSystemNamespaces(api: KubeApi, log: LogEntry, name interface GetSystemServicesStatusParams { ctx: KubernetesPluginContext, + sysGarden: Garden, log: LogEntry, namespace: string, serviceNames: string[], - variables: PrimitiveMap, } export async function getSystemServiceStatus( - { ctx, log, namespace, serviceNames, variables }: GetSystemServicesStatusParams, + { ctx, sysGarden, log, namespace, serviceNames }: GetSystemServicesStatusParams, ) { let dashboardPages: DashboardPage[] = [] - const sysGarden = await getSystemGarden(ctx.provider, variables) const actions = await sysGarden.getActionHelper() const serviceStatuses = await actions.getServiceStatuses({ log, serviceNames }) @@ -169,7 +177,7 @@ interface PrepareSystemServicesParams extends GetSystemServicesStatusParams { } export async function prepareSystemServices( - { ctx, log, namespace, serviceNames, force, variables }: PrepareSystemServicesParams, + { ctx, sysGarden, log, namespace, serviceNames, force }: PrepareSystemServicesParams, ) { const api = await KubeApi.factory(log, ctx.provider.config.context) @@ -182,7 +190,6 @@ export async function prepareSystemServices( const k8sCtx = ctx const provider = k8sCtx.provider - const sysGarden = await getSystemGarden(provider, variables) // Deploy enabled system services if (serviceNames.length > 0) { @@ -202,3 +209,7 @@ export async function prepareSystemServices( } } } + +export function getSystemGardenDirPath(projectGardenDirPath: string) { + return join(projectGardenDirPath, "kubernetes.garden") +}