@elastic.io/component-build-helper
Advanced tools
Comparing version 0.1.0 to 1.0.0
@@ -28,2 +28,4 @@ "use strict"; | ||
'gradlew', | ||
// Java > 8 | ||
'jdeps.info', | ||
// Common | ||
@@ -30,0 +32,0 @@ 'component.json', |
@@ -27,5 +27,8 @@ import { ComponentContextLoader } from './ComponentContextLoader'; | ||
export declare class GradleDockerfileGenerator extends DockerfileGenerator { | ||
readonly defaultGradleVersion = "7.4.2"; | ||
readonly SUPPORTED_JAVA_VERSIONS: string[]; | ||
readonly DEFAULT_GRADLE_VERSION = "7.4.2"; | ||
readonly JAVA_8 = "1.8"; | ||
private javaVersion; | ||
private sailorBuildGralde; | ||
private predefinedJdeps; | ||
constructor(componentContextLoader: ComponentContextLoader); | ||
@@ -37,2 +40,3 @@ static detect(componentContextLoader: ComponentContextLoader): Promise<boolean>; | ||
getComponentRuntimeImage(): Promise<string> | string; | ||
private prepareJreModules; | ||
/** | ||
@@ -39,0 +43,0 @@ * Load needed information from build.gradle and calculate needed java version |
@@ -87,3 +87,5 @@ "use strict"; | ||
super(componentContextLoader); | ||
this.defaultGradleVersion = '7.4.2'; | ||
this.SUPPORTED_JAVA_VERSIONS = ['1.8', '11', '17', '18']; | ||
this.DEFAULT_GRADLE_VERSION = '7.4.2'; | ||
this.JAVA_8 = '1.8'; | ||
this._componentLanguage = index_1.COMPONENT_LANGUAGE.JAVA; | ||
@@ -107,15 +109,15 @@ } | ||
// installing gradle, because wrapper is not exists in the component | ||
gradle.push(`FROM amazoncorretto:${this.getComponentBuildImage()} as gradle`, `ARG GRADLE_VERSION=${this.defaultGradleVersion}`, 'ENV GRADLE_ARCHIVE gradle-$GRADLE_VERSION-bin.zip', 'WORKDIR /opt', 'RUN apk update && apk add --no-cache wget libstdc++ && rm -rf /var/cache/apk/*', 'RUN wget --no-verbose https://services.gradle.org/distributions/$GRADLE_ARCHIVE', 'RUN unzip -q $GRADLE_ARCHIVE && rm $GRADLE_ARCHIVE', 'ENV PATH "$PATH:/opt/gradle-$GRADLE_VERSION/bin/"'); | ||
gradle.push(`FROM ${this.getComponentBuildImage()} as gradle`, `ARG GRADLE_VERSION=${this.DEFAULT_GRADLE_VERSION}`, 'ENV GRADLE_ARCHIVE gradle-$GRADLE_VERSION-bin.zip', 'WORKDIR /opt', 'RUN apk update && apk add --no-cache wget libstdc++ && rm -rf /var/cache/apk/*', 'RUN wget --no-verbose https://services.gradle.org/distributions/$GRADLE_ARCHIVE', 'RUN unzip -q $GRADLE_ARCHIVE && rm $GRADLE_ARCHIVE', 'ENV PATH "$PATH:/opt/gradle-$GRADLE_VERSION/bin/"'); | ||
build.push('FROM gradle as build'); | ||
} | ||
else { | ||
build.push(`FROM amazoncorretto:${this.getComponentBuildImage()} as build`); | ||
build.push(`FROM ${this.getComponentBuildImage()} as build`); | ||
} | ||
build.push('ARG CLASSES_MAIN_DIR=./build/classes/main', 'RUN apk add --update tini python3 make g++ && rm -rf /var/cache/apk/*', 'WORKDIR /home/apprunner', 'COPY ./ ./', | ||
// https://stackoverflow.com/questions/33439230/how-to-write-commands-with-multiple-lines-in-dockerfile-while-preserving-the-new | ||
`RUN echo $'${this.sailorBuildGralde.replace(/\n/g, '\\n\\\n')}' > sailor_jvm_build.gradle`, `RUN ${this.isWrapperExists() ? './gradlew' : 'gradle'} clean prepareSailorWithDependencies -b ./sailor_jvm_build.gradle`, 'COPY ./component.json $CLASSES_MAIN_DIR'); | ||
`RUN echo $'${this.sailorBuildGralde.replace(/\n/g, '\\n\\\n')}' > sailor_jvm_build.gradle`, `RUN ${this.isWrapperExists() ? './gradlew' : 'gradle'} clean prepareSailorWithDependencies -b ./sailor_jvm_build.gradle`, 'COPY ./component.json $CLASSES_MAIN_DIR', this.prepareJreModules()); | ||
return [ | ||
...gradle, | ||
...build, | ||
`FROM amazoncorretto:${this.getComponentRuntimeImage()}`, | ||
`FROM ${this.getComponentRuntimeImage()}`, | ||
'ARG CLASSES_MAIN_DIR=./build/classes/main', | ||
@@ -125,2 +127,4 @@ 'ARG RESOURCES_MAIN_DIR=./build/resources/main', | ||
'ENV CLASSPATH $CLASSES_MAIN_DIR:$RESOURCES_MAIN_DIR:$DEPENDENCIES_DIR/*', | ||
// add generated jre to the path | ||
this.javaVersion === this.JAVA_8 ? '' : 'ENV PATH="/home/apprunner/jre/bin:$PATH"', | ||
...this.getLabels(), | ||
@@ -130,2 +134,3 @@ 'RUN addgroup -S apprunner && adduser -S apprunner -G apprunner -h /home/apprunner', | ||
'USER apprunner', | ||
'COPY --from=build --chown=apprunner /home/apprunner/jre /home/apprunner/jre', | ||
'COPY --from=build --chown=apprunner /home/apprunner/build /home/apprunner/build', | ||
@@ -137,13 +142,29 @@ 'COPY --from=build --chown=apprunner /sbin/tini /sbin/tini', | ||
getComponentBuildImage() { | ||
if (this.javaVersion === '1.8') { | ||
return `8-alpine-jdk`; | ||
if (this.javaVersion === this.JAVA_8) { | ||
return `amazoncorretto:8-alpine-jdk`; | ||
} | ||
return `${this.javaVersion}-alpine-jdk`; | ||
return `amazoncorretto:${this.javaVersion}-alpine-jdk`; | ||
} | ||
getComponentRuntimeImage() { | ||
if (this.javaVersion === '1.8') { | ||
return `8-alpine-jre`; | ||
if (this.javaVersion === this.JAVA_8) { | ||
return `amazoncorretto:8-alpine-jre`; | ||
} | ||
return `${this.javaVersion}-alpine-jdk`; | ||
return `alpine:latest`; | ||
} | ||
prepareJreModules() { | ||
// do not calc modules for java 8 | ||
if (this.javaVersion === this.JAVA_8) { | ||
return ''; | ||
} | ||
const calculatedModules = []; | ||
// in case jdeps.info file is found in the sources - use it | ||
if (this.predefinedJdeps) { | ||
calculatedModules.push(`RUN echo "${this.predefinedJdeps.replace(/\n/g, '\\n\\\n')}" > jdeps.info`); | ||
} | ||
else { | ||
calculatedModules.push(`RUN jdeps --ignore-missing-deps --print-module-deps -q --multi-release ${this.javaVersion} --class-path ./build/dependencies/* ./build/classes/main > jdeps.info`); | ||
} | ||
calculatedModules.push(`RUN jlink --verbose --compress 2 --strip-debug --no-header-files --no-man-pages --output jre --add-modules $(cat jdeps.info)`); | ||
return calculatedModules.join('\n'); | ||
} | ||
/** | ||
@@ -161,5 +182,6 @@ * Load needed information from build.gradle and calculate needed java version | ||
const buildGradle = await parser_1.default.parseText(context['build.gradle']); | ||
// TODO allow read version from buildGradle.targetCompatibility || buildGradle.sourceCompatibility | ||
// after generateDockerfile will support java versions >=11 | ||
this.javaVersion = '1.8'; | ||
this.javaVersion = buildGradle.targetCompatibility || '17'; | ||
if (!this.SUPPORTED_JAVA_VERSIONS.includes(this.javaVersion)) { | ||
throw new Error(`Unsupported Java version. Allowed values: ${JSON.stringify(this.SUPPORTED_JAVA_VERSIONS)}`); | ||
} | ||
this._sailorVersion = buildGradle.dependencies.find(item => item.name === 'sailor-jvm' && item.group === 'io.elastic').version; | ||
@@ -169,2 +191,4 @@ if (!this._sailorVersion) { | ||
} | ||
// jdeps.info can be used to specify the list of needed for component runtime env java modules | ||
this.predefinedJdeps = this.componentContextLoader.context['jdeps.info']; | ||
this.checkIsDockerfilePredefined(); | ||
@@ -171,0 +195,0 @@ this.initialized = true; |
{ | ||
"name": "@elastic.io/component-build-helper", | ||
"version": "0.1.0", | ||
"version": "1.0.0", | ||
"description": "Helpers for the component build process", | ||
@@ -5,0 +5,0 @@ "main": "dist/src/index.js", |
@@ -14,3 +14,3 @@ import sinon, { SinonSandbox } from 'sinon'; | ||
gradleDockerfile, | ||
gradleWrapperDockerfile, labelsWithSplittedLogo, | ||
gradleWrapperDockerfile, java11Dockerfile, java11PredefinedJdepsInfo, labelsWithSplittedLogo, | ||
predefinedDockerfile | ||
@@ -245,4 +245,34 @@ } from '../fixtures/DockerfileGenerator.data'; | ||
}); | ||
it('genDockerfile should return dockerfile with jdeps/jlink dockerfile for java version >=11', async () => { | ||
const path = './spec/fixtures/component/gradle'; | ||
const readFileStub = sandbox.stub(fsPromise, 'readFile'); | ||
readFileStub.withArgs(`${path}/build.Gradle`).resolves(await fsPromise.readFile('./spec/fixtures/java11/build.gradle')); | ||
readFileStub.callThrough(); | ||
componentContextLoader = await ComponentContextLoader.getInstance(path); | ||
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader); | ||
await expect(dockerfileGenerator.genDockerfile()).to.be.equal(java11Dockerfile); | ||
}); | ||
it('genDockerfile should return dockerfile with jdeps/jlink dockerfile with predefined jdeps.info', async () => { | ||
const path = './spec/fixtures/component/gradle'; | ||
const buildGradle = await fsPromise.readFile('./spec/fixtures/java11/build.gradle'); | ||
const jdepsInfo = await fsPromise.readFile('./spec/fixtures/java11/jdeps.info'); | ||
const readFileStub = sandbox.stub(fsPromise, 'readFile'); | ||
readFileStub.withArgs(`${path}/build.gradle`).resolves(buildGradle); | ||
readFileStub.withArgs(`${path}/jdeps.info`).resolves(jdepsInfo); | ||
readFileStub.callThrough(); | ||
componentContextLoader = await ComponentContextLoader.getInstance(path); | ||
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader); | ||
await expect(dockerfileGenerator.genDockerfile()).to.be.equal(java11PredefinedJdepsInfo); | ||
}); | ||
it('genDockerfile should get an error in case unsupported java version specified', async () => { | ||
const path = './spec/fixtures/component/gradle'; | ||
const buildGradle = await fsPromise.readFile('./spec/fixtures/invalid-java-version.gradle'); | ||
const readFileStub = sandbox.stub(fsPromise, 'readFile'); | ||
readFileStub.withArgs(`${path}/build.gradle`).resolves(buildGradle); | ||
readFileStub.callThrough(); | ||
componentContextLoader = await ComponentContextLoader.getInstance(path); | ||
await expect(DockerfileGenerator.getInstance(componentContextLoader)).to.be.rejectedWith('Unsupported Java version. Allowed values: ["1.8","11","17","18"]'); | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -19,2 +19,4 @@ /* eslint-disable @typescript-eslint/no-use-before-define */ | ||
'gradlew', | ||
// Java > 8 | ||
'jdeps.info', | ||
// Common | ||
@@ -21,0 +23,0 @@ 'component.json', |
@@ -10,2 +10,3 @@ /* eslint-disable @typescript-eslint/no-use-before-define */ | ||
import path from 'path'; | ||
export abstract class DockerfileGenerator { | ||
@@ -106,5 +107,8 @@ protected _componentLanguage: COMPONENT_LANGUAGE; | ||
export class GradleDockerfileGenerator extends DockerfileGenerator { | ||
readonly defaultGradleVersion = '7.4.2'; | ||
private javaVersion: '1.8' | '11' | '17'; | ||
readonly SUPPORTED_JAVA_VERSIONS = ['1.8', '11', '17', '18']; | ||
readonly DEFAULT_GRADLE_VERSION = '7.4.2'; | ||
readonly JAVA_8 = '1.8'; | ||
private javaVersion: '1.8' | '11' | '17' | '18'; | ||
private sailorBuildGralde: string; | ||
private predefinedJdeps: string; | ||
@@ -136,4 +140,4 @@ constructor(componentContextLoader: ComponentContextLoader) { | ||
gradle.push( | ||
`FROM amazoncorretto:${this.getComponentBuildImage()} as gradle`, | ||
`ARG GRADLE_VERSION=${this.defaultGradleVersion}`, | ||
`FROM ${this.getComponentBuildImage()} as gradle`, | ||
`ARG GRADLE_VERSION=${this.DEFAULT_GRADLE_VERSION}`, | ||
'ENV GRADLE_ARCHIVE gradle-$GRADLE_VERSION-bin.zip', | ||
@@ -151,3 +155,3 @@ 'WORKDIR /opt', | ||
build.push( | ||
`FROM amazoncorretto:${this.getComponentBuildImage()} as build` | ||
`FROM ${this.getComponentBuildImage()} as build` | ||
); | ||
@@ -163,3 +167,4 @@ } | ||
`RUN ${this.isWrapperExists() ? './gradlew' : 'gradle'} clean prepareSailorWithDependencies -b ./sailor_jvm_build.gradle`, | ||
'COPY ./component.json $CLASSES_MAIN_DIR' | ||
'COPY ./component.json $CLASSES_MAIN_DIR', | ||
this.prepareJreModules() | ||
); | ||
@@ -170,3 +175,3 @@ | ||
...build, | ||
`FROM amazoncorretto:${this.getComponentRuntimeImage()}`, | ||
`FROM ${this.getComponentRuntimeImage()}`, | ||
'ARG CLASSES_MAIN_DIR=./build/classes/main', | ||
@@ -176,2 +181,4 @@ 'ARG RESOURCES_MAIN_DIR=./build/resources/main', | ||
'ENV CLASSPATH $CLASSES_MAIN_DIR:$RESOURCES_MAIN_DIR:$DEPENDENCIES_DIR/*', | ||
// add generated jre to the path | ||
this.javaVersion === this.JAVA_8 ? '' : 'ENV PATH="/home/apprunner/jre/bin:$PATH"', | ||
...this.getLabels(), | ||
@@ -181,2 +188,3 @@ 'RUN addgroup -S apprunner && adduser -S apprunner -G apprunner -h /home/apprunner', | ||
'USER apprunner', | ||
'COPY --from=build --chown=apprunner /home/apprunner/jre /home/apprunner/jre', | ||
'COPY --from=build --chown=apprunner /home/apprunner/build /home/apprunner/build', | ||
@@ -189,15 +197,32 @@ 'COPY --from=build --chown=apprunner /sbin/tini /sbin/tini', | ||
getComponentBuildImage(): Promise<string> | string { | ||
if (this.javaVersion === '1.8') { | ||
return `8-alpine-jdk`; | ||
if (this.javaVersion === this.JAVA_8) { | ||
return `amazoncorretto:8-alpine-jdk`; | ||
} | ||
return `${this.javaVersion}-alpine-jdk`; | ||
return `amazoncorretto:${this.javaVersion}-alpine-jdk`; | ||
} | ||
getComponentRuntimeImage(): Promise<string> | string { | ||
if (this.javaVersion === '1.8') { | ||
return `8-alpine-jre`; | ||
if (this.javaVersion === this.JAVA_8) { | ||
return `amazoncorretto:8-alpine-jre`; | ||
} | ||
return `${this.javaVersion}-alpine-jdk`; | ||
return `alpine:latest`; | ||
} | ||
private prepareJreModules() { | ||
// do not calc modules for java 8 | ||
if (this.javaVersion === this.JAVA_8) { | ||
return ''; | ||
} | ||
const calculatedModules = []; | ||
// in case jdeps.info file is found in the sources - use it | ||
if (this.predefinedJdeps) { | ||
calculatedModules.push(`RUN echo "${this.predefinedJdeps.replace(/\n/g, '\\n\\\n')}" > jdeps.info`); | ||
} else { | ||
calculatedModules.push(`RUN jdeps --ignore-missing-deps --print-module-deps -q --multi-release ${this.javaVersion} --class-path ./build/dependencies/* ./build/classes/main > jdeps.info`); | ||
} | ||
calculatedModules.push(`RUN jlink --verbose --compress 2 --strip-debug --no-header-files --no-man-pages --output jre --add-modules $(cat jdeps.info)`); | ||
return calculatedModules.join('\n'); | ||
} | ||
/** | ||
@@ -215,5 +240,6 @@ * Load needed information from build.gradle and calculate needed java version | ||
const buildGradle = await g2js.parseText(context['build.gradle']); | ||
// TODO allow read version from buildGradle.targetCompatibility || buildGradle.sourceCompatibility | ||
// after generateDockerfile will support java versions >=11 | ||
this.javaVersion = '1.8'; | ||
this.javaVersion = buildGradle.targetCompatibility || '17'; | ||
if (!this.SUPPORTED_JAVA_VERSIONS.includes(this.javaVersion)) { | ||
throw new Error(`Unsupported Java version. Allowed values: ${JSON.stringify(this.SUPPORTED_JAVA_VERSIONS)}`); | ||
} | ||
this._sailorVersion = buildGradle.dependencies.find(item => | ||
@@ -224,2 +250,4 @@ item.name === 'sailor-jvm' && item.group === 'io.elastic').version; | ||
} | ||
// jdeps.info can be used to specify the list of needed for component runtime env java modules | ||
this.predefinedJdeps = this.componentContextLoader.context['jdeps.info']; | ||
this.checkIsDockerfilePredefined(); | ||
@@ -226,0 +254,0 @@ this.initialized = true; |
Sorry, the diff of this file is too big to display
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
775770
77
3451
1