Skip to content

Commit

Permalink
feat(maven-container): automatically fetch Maven and OpenJDK
Browse files Browse the repository at this point in the history
Along the way, improved the external tool helper to support libraries
as well as executable binaries.
  • Loading branch information
edvald committed Mar 14, 2019
1 parent 80e5a97 commit 5045cd3
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 105 deletions.
2 changes: 1 addition & 1 deletion docs/reference/module-types/maven-container.md
Expand Up @@ -578,7 +578,7 @@ module:
### `module.jdkVersion`
[module](#module) > jdkVersion

The Java version to run
The JDK version to use.

| Type | Required |
| ---- | -------- |
Expand Down
6 changes: 3 additions & 3 deletions garden-service/src/plugins/kubernetes/helm/helm-cli.ts
Expand Up @@ -17,23 +17,23 @@ const helmCmd = new BinaryCmd({
sha256: "166318b2159613f87a7cb02af1614c96244b3d3c119f8e010429c1b4449681d5",
extract: {
format: "tar",
executablePath: ["darwin-amd64", "helm"],
targetPath: ["darwin-amd64", "helm"],
},
},
linux: {
url: "https://storage.googleapis.com/kubernetes-helm/helm-v2.13.0-linux-amd64.tar.gz",
sha256: "15eca6ad225a8279de80c7ced42305e24bc5ac60bb7d96f2d2fa4af86e02c794",
extract: {
format: "tar",
executablePath: ["linux-amd64", "helm"],
targetPath: ["linux-amd64", "helm"],
},
},
win32: {
url: "https://storage.googleapis.com/kubernetes-helm/helm-v2.13.0-windows-amd64.zip",
sha256: "63fdb71ad6fac0572a21ad81da7508b1f0cae960ea944670f4d2f7fbaf23acb2",
extract: {
format: "zip",
executablePath: ["windows-amd64", "helm.exe"],
targetPath: ["windows-amd64", "helm.exe"],
},
},
},
Expand Down
64 changes: 26 additions & 38 deletions garden-service/src/plugins/maven-container/maven-container.ts
Expand Up @@ -6,7 +6,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import * as execa from "execa"
import * as Joi from "joi"
import { omit, pick, get } from "lodash"
import { copy, pathExists, readFile } from "fs-extra"
Expand All @@ -16,6 +15,7 @@ import {
ContainerServiceSpec,
ContainerTestSpec,
ContainerModuleConfig,
ContainerTaskSpec,
} from "../container/config"
import { validateWithPath } from "../../config/common"
import { BuildModuleParams, ConfigureModuleParams, GetBuildStatusParams } from "../../types/plugin/params"
Expand All @@ -29,6 +29,8 @@ import { STATIC_DIR } from "../../constants"
import { xml2json } from "xml-js"
import { containerModuleSpecSchema } from "../container/config"
import { providerConfigBaseSchema } from "../../config/project"
import { openJdks } from "./openjdk"
import { maven } from "./maven"

const defaultDockerfilePath = resolve(STATIC_DIR, "maven-container", "Dockerfile")

Expand All @@ -41,10 +43,11 @@ interface MavenContainerModuleSpec extends ContainerModuleSpec {
// type MavenContainerModuleConfig = ModuleConfig<MavenContainerModuleSpec>

interface MavenContainerModule<
M extends ContainerModuleSpec = MavenContainerModuleSpec,
M extends MavenContainerModuleSpec = MavenContainerModuleSpec,
S extends ContainerServiceSpec = ContainerServiceSpec,
T extends ContainerTestSpec = ContainerTestSpec
> extends Module<M, S, T> { }
T extends ContainerTestSpec = ContainerTestSpec,
W extends ContainerTaskSpec = ContainerTaskSpec
> extends Module<M, S, T, W> { }

const mavenKeys = {
jarPath: Joi.string()
Expand All @@ -53,16 +56,15 @@ const mavenKeys = {
.example("target/my-module.jar"),
jdkVersion: Joi.number()
.integer()
.min(8)
.allow(8, 11)
.default(8)
.description("The Java version to run"),
.description("The JDK version to use."),
}

const mavenFieldsSchema = Joi.object()
.keys(mavenKeys)

export const mavenContainerModuleSpecSchema = containerModuleSpecSchema.keys(mavenKeys)

export const mavenContainerConfigSchema = providerConfigBaseSchema

export const gardenPlugin = (): GardenPlugin => {
Expand Down Expand Up @@ -95,9 +97,11 @@ async function configure(params: ConfigureModuleParams<MavenContainerModule>) {
let containerConfig: ContainerModuleConfig = { ...moduleConfig }
containerConfig.spec = <ContainerModuleSpec>omit(moduleConfig.spec, Object.keys(mavenKeys))

const jdkVersion = mavenFields.jdkVersion!

containerConfig.spec.buildArgs = {
JAR_PATH: mavenFields.jarPath!,
JDK_VERSION: mavenFields.jdkVersion!.toString(),
JDK_VERSION: jdkVersion.toString(),
}

const configured = await configureContainerModule({ ...params, moduleConfig: containerConfig })
Expand Down Expand Up @@ -127,7 +131,7 @@ async function getBuildStatus(params: GetBuildStatusParams<MavenContainerModule>
async function build(params: BuildModuleParams<MavenContainerModule>) {
// Run the maven build
const { ctx, module, log } = params
let { jarPath } = module.spec
let { jarPath, jdkVersion } = module.spec

const pom = await loadPom(module.path)
const artifactId = get(pom, ["project", "artifactId", "_text"])
Expand All @@ -136,6 +140,11 @@ async function build(params: BuildModuleParams<MavenContainerModule>) {
throw new ConfigurationError(`Could not read artifact ID from pom.xml in ${module.path}`, { path: module.path })
}

log.setState(`Creating jar artifact...`)

const openJdk = openJdks[jdkVersion]
const openJdkPath = await openJdk.getPath(log)

const mvnArgs = [
"package",
"--batch-mode",
Expand All @@ -145,8 +154,14 @@ async function build(params: BuildModuleParams<MavenContainerModule>) {
]
const mvnCmdStr = "mvn " + mvnArgs.join(" ")

log.setState(`Creating jar artifact...`)
await mvn(ctx.projectRoot, mvnArgs)
await maven.exec({
args: mvnArgs,
cwd: ctx.projectRoot,
log,
env: {
JAVA_HOME: openJdkPath,
},
})

// Copy the artifact to the module build directory
const resolvedJarPath = resolve(module.path, jarPath)
Expand All @@ -164,10 +179,6 @@ async function build(params: BuildModuleParams<MavenContainerModule>) {
return buildContainerModule(params)
}

async function mvn(cwd: string, args: string[]) {
return execa.stdout("mvn", args, { cwd, maxBuffer: 10 * 1024 * 1024 })
}

async function loadPom(dir: string) {
try {
const pomPath = resolve(dir, "pom.xml")
Expand All @@ -177,26 +188,3 @@ async function loadPom(dir: string) {
throw new ConfigurationError(`Could not load pom.xml from directory ${dir}`, { dir })
}
}

// TODO: see if we could make this perform adequately, or perhaps use this only on Linux...
//
// async function mvn(jdkVersion: number, projectRoot: string, args: string[]) {
// const mvnImage = `maven:3.6.0-jdk-${jdkVersion}-slim`
// const m2Path = resolve(homedir(), ".m2")

// const dockerArgs = [
// "run",
// "--rm",
// "--interactive",
// "--volume", `${m2Path}:/root/.m2`,
// "--volume", `${projectRoot}:/project`,
// "--workdir", "/project",
// mvnImage,
// "--",
// ...args,
// ]

// console.log(dockerArgs.join(" "))

// return execa.stdout("docker", dockerArgs, { maxBuffer: 10 * 1024 * 1024 })
// }
27 changes: 27 additions & 0 deletions garden-service/src/plugins/maven-container/maven.ts
@@ -0,0 +1,27 @@
/*
* Copyright (C) 2018 Garden Technologies, Inc. <info@garden.io>
*
* 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 { BinaryCmd, LibraryPlatformSpec } from "../../util/ext-tools"

const spec: LibraryPlatformSpec = {
url: "http://mirror.23media.de/apache/maven/maven-3/3.6.0/binaries/apache-maven-3.6.0-bin.tar.gz",
sha256: "6a1b346af36a1f1a491c1c1a141667c5de69b42e6611d3687df26868bc0f4637",
extract: {
format: "tar",
targetPath: ["apache-maven-3.6.0", "bin", "mvn"],
},
}

export const maven = new BinaryCmd({
name: "maven",
specs: {
darwin: spec,
linux: spec,
win32: spec,
},
})
70 changes: 70 additions & 0 deletions garden-service/src/plugins/maven-container/openjdk.ts
@@ -0,0 +1,70 @@
/*
* Copyright (C) 2018 Garden Technologies, Inc. <info@garden.io>
*
* 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 { Library, LibraryPlatformSpec } from "../../util/ext-tools"

const jdk8Version = "jdk8u202-b08"

function jdk8Spec(filename: string, sha256: string): LibraryPlatformSpec {
return {
url: `https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/${jdk8Version}/${filename}`,
sha256,
extract: {
format: "tar",
targetPath: [jdk8Version, "Contents", "Home"],
},
}
}

function jdk11Spec(filename: string, sha256: string): LibraryPlatformSpec {
return {
url: `https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.2%2B9/${filename}`,
sha256,
extract: {
format: "tar",
targetPath: ["jdk-11.0.2+9", "Contents", "Home"],
},
}
}

export const openJdks: { [version: number]: Library } = {
8: new Library({
name: "openjdk-8",
specs: {
darwin: jdk8Spec(
"OpenJDK8U-jdk_x64_mac_hotspot_8u202b08.tar.gz",
"059f7c18faa6722aa636bbd79bcdff3aee6a6da5b34940b072ea6e3af85bbe1d",
),
linux: jdk8Spec(
"OpenJDK8U-jdk_x64_linux_hotspot_8u202b08.tar.gz",
"f5a1c9836beb3ca933ec3b1d39568ecbb68bd7e7ca6a9989a21ff16a74d910ab",
),
win32: jdk8Spec(
"OpenJDK8U-jdk_x64_windows_hotspot_8u202b08.zip",
"2637dab3bc81274e19991eebc27684276b482dd71d0f84fedf703d4fba3576e5",
),
},
}),
11: new Library({
name: "openjdk-11",
specs: {
darwin: jdk11Spec(
"OpenJDK11U-jdk_x64_mac_hotspot_11.0.2_9.tar.gz",
"fffd4ed283e5cd443760a8ec8af215c8ca4d33ec5050c24c1277ba64b5b5e81a",
),
linux: jdk11Spec(
"OpenJDK11U-jdk_x64_linux_hotspot_11.0.2_9.tar.gz",
"d02089d834f7702ac1a9776d8d0d13ee174d0656cf036c6b68b9ffb71a6f610e",
),
win32: jdk11Spec(
"OpenJDK11U-jdk_x64_windows_hotspot_11.0.2_9.zip",
"bde1648333abaf49c7175c9ee8ba9115a55fc160838ff5091f07d10c4bb50b3a",
),
},
}),
}

0 comments on commit 5045cd3

Please sign in to comment.