Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@elastic.io/component-build-helper

Package Overview
Dependencies
Maintainers
12
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@elastic.io/component-build-helper - npm Package Compare versions

Comparing version 0.1.0 to 1.0.0-dev.1

spec/fixtures/invalid-java-version.gradle

2

dist/src/ComponentContextLoader.js

@@ -28,2 +28,4 @@ "use strict";

'gradlew',
// Java > 8
'jdeps.info',
// Common

@@ -30,0 +32,0 @@ 'component.json',

8

dist/src/DockerfileGenerator.d.ts

@@ -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 sailorBuildGradle;
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

@@ -57,5 +57,8 @@ "use strict";

getLabels() {
// need to stringify 2 times to get escaped json string
const componentJsonLabel = JSON.stringify(JSON.stringify(this.componentJson))
// Escape substitution in the dockerfile
.split('$').join('\\$');
return [
// need to stringify 2 times to get escaped json string
`LABEL elastic.io.component=${this.prepareLabel(JSON.stringify(JSON.stringify(this.componentJson)))}`,
`LABEL elastic.io.component=${this.prepareLabel(componentJsonLabel)}`,
`LABEL elastic.io.logo="${this.prepareLabel(this._icon)}"`

@@ -88,3 +91,5 @@ ];

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;

@@ -108,15 +113,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 ./ ./',
build.push('ARG CLASSES_MAIN_DIR=./build/classes/main', 'RUN apk add --update git 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.sailorBuildGradle.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',

@@ -126,2 +131,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(),

@@ -131,2 +138,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',

@@ -138,13 +146,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');
}
/**

@@ -158,9 +182,10 @@ * Load needed information from build.gradle and calculate needed java version

// build/elasticio/dependencies/ folder
this.sailorBuildGralde = (await fs_1.promises.readFile(`${path_1.default.resolve(__dirname, '../component/sailor_jvm_build.gradle')}`))
this.sailorBuildGradle = (await fs_1.promises.readFile(`${path_1.default.resolve(__dirname, '../component/sailor_jvm_build.gradle').toString()}`))
.toString();
// build.gradle is provided by component developer
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;

@@ -170,2 +195,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();

@@ -201,3 +228,3 @@ this.initialized = true;

`FROM ${this.getComponentBuildImage()} AS base`,
'RUN apk add --update tini python3 make g++ && rm -rf /var/cache/apk/*',
'RUN apk add --update git tini python3 make g++ && rm -rf /var/cache/apk/*',
'WORKDIR /home/node',

@@ -204,0 +231,0 @@ `COPY --chown=node:node . ./`,

{
"name": "@elastic.io/component-build-helper",
"version": "0.1.0",
"version": "1.0.0-dev.1",
"description": "Helpers for the component build process",

@@ -5,0 +5,0 @@ "main": "dist/src/index.js",

@@ -18,2 +18,3 @@ {

"title": "Executes custom code",
"placeholder": "INSERT INTO films (code,title,kind) VALUES (${code},${title},${kind})",
"metadata" : {

@@ -20,0 +21,0 @@ "in" : "./in/in-metadata.json"

@@ -14,3 +14,3 @@ import sinon, { SinonSandbox } from 'sinon';

gradleDockerfile,
gradleWrapperDockerfile, labelsWithSplittedLogo,
gradleWrapperDockerfile, java11Dockerfile, java11PredefinedJdepsInfo, labelsWithSplittedLogo,
predefinedDockerfile

@@ -87,3 +87,3 @@ } from '../fixtures/DockerfileGenerator.data';

'FROM node:16-alpine AS base\n' +
'RUN apk add --update tini python3 make g++ && rm -rf /var/cache/apk/*\n' +
'RUN apk add --update git tini python3 make g++ && rm -rf /var/cache/apk/*\n' +
'WORKDIR /home/node\n' +

@@ -100,3 +100,3 @@ 'COPY --chown=node:node . ./\n' +

'FROM node:16-alpine AS release\n' +
`LABEL elastic.io.component=${JSON.stringify(JSON.stringify(componentJsonLabel))}\n` +
`LABEL elastic.io.component=${componentJsonLabel}\n` +
`LABEL elastic.io.logo="${logo}"\n` +

@@ -117,3 +117,3 @@ 'WORKDIR /home/node\n' +

await expect(dockerfileGenerator.genDockerfile()).to.eventually.equal(predefinedDockerfile +
`\nLABEL elastic.io.component=${JSON.stringify(JSON.stringify(componentJsonLabel))}\n` +
`\nLABEL elastic.io.component=${componentJsonLabel}\n` +
`LABEL elastic.io.logo="${logo}"`);

@@ -138,3 +138,3 @@ });

'FROM node:15-alpine AS base\n' +
'RUN apk add --update tini python3 make g++ && rm -rf /var/cache/apk/*\n' +
'RUN apk add --update git tini python3 make g++ && rm -rf /var/cache/apk/*\n' +
'WORKDIR /home/node\n' +

@@ -249,4 +249,34 @@ 'COPY --chown=node:node . ./\n' +

});
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 {

@@ -76,5 +77,8 @@ protected _componentLanguage: COMPONENT_LANGUAGE;

protected getLabels() {
// need to stringify 2 times to get escaped json string
const componentJsonLabel = JSON.stringify(JSON.stringify(this.componentJson))
// Escape substitution in the dockerfile
.split('$').join('\\$');
return [
// need to stringify 2 times to get escaped json string
`LABEL elastic.io.component=${this.prepareLabel(JSON.stringify(JSON.stringify(this.componentJson)))}`,
`LABEL elastic.io.component=${this.prepareLabel(componentJsonLabel)}`,
`LABEL elastic.io.logo="${this.prepareLabel(this._icon)}"`

@@ -107,5 +111,8 @@ ];

export class GradleDockerfileGenerator extends DockerfileGenerator {
readonly defaultGradleVersion = '7.4.2';
private javaVersion: '1.8' | '11' | '17';
private sailorBuildGralde: string;
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 sailorBuildGradle: string;
private predefinedJdeps: string;

@@ -137,4 +144,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',

@@ -152,3 +159,3 @@ 'WORKDIR /opt',

build.push(
`FROM amazoncorretto:${this.getComponentBuildImage()} as build`
`FROM ${this.getComponentBuildImage()} as build`
);

@@ -158,9 +165,10 @@ }

'ARG CLASSES_MAIN_DIR=./build/classes/main',
'RUN apk add --update tini python3 make g++ && rm -rf /var/cache/apk/*',
'RUN apk add --update git 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 echo $'${this.sailorBuildGradle.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'
'COPY ./component.json $CLASSES_MAIN_DIR',
this.prepareJreModules()
);

@@ -171,3 +179,3 @@

...build,
`FROM amazoncorretto:${this.getComponentRuntimeImage()}`,
`FROM ${this.getComponentRuntimeImage()}`,
'ARG CLASSES_MAIN_DIR=./build/classes/main',

@@ -177,2 +185,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(),

@@ -182,2 +192,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',

@@ -190,15 +201,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');
}
/**

@@ -212,9 +240,10 @@ * Load needed information from build.gradle and calculate needed java version

// build/elasticio/dependencies/ folder
this.sailorBuildGralde = (await fs.readFile(`${path.resolve(__dirname, '../component/sailor_jvm_build.gradle')}`))
this.sailorBuildGradle = (await fs.readFile(`${path.resolve(__dirname, '../component/sailor_jvm_build.gradle').toString()}`))
.toString();
// build.gradle is provided by component developer
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 =>

@@ -225,2 +254,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();

@@ -262,3 +293,3 @@ this.initialized = true;

`FROM ${this.getComponentBuildImage()} AS base`,
'RUN apk add --update tini python3 make g++ && rm -rf /var/cache/apk/*',
'RUN apk add --update git tini python3 make g++ && rm -rf /var/cache/apk/*',
'WORKDIR /home/node',

@@ -265,0 +296,0 @@ `COPY --chown=node:node . ./`,

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc