Skip to content

Commit

Permalink
[7.17] [build] Cross compile docker images (elastic#128272)
Browse files Browse the repository at this point in the history
* [build] Cross compile docker images

* typo

* debug

* Revert "[build] Cross compile docker images"

This reverts commit 621780e.

* revert

* support docker-cross-compile flag

* fix types/tests

* fix more tests

* download cloud dependencies based on cross compile flag

* fix array

* fix more tests
  • Loading branch information
jbudz committed Apr 1, 2022
1 parent 6472bf7 commit be42eb8
Show file tree
Hide file tree
Showing 14 changed files with 99 additions and 3 deletions.
7 changes: 7 additions & 0 deletions src/dev/build/args.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ it('build default and oss dist for current platform, without packages, by defaul
"createGenericFolders": true,
"createPlatformFolders": true,
"createRpmPackage": false,
"dockerCrossCompile": false,
"downloadFreshNode": true,
"initialize": true,
"isRelease": false,
Expand Down Expand Up @@ -63,6 +64,7 @@ it('builds packages if --all-platforms is passed', () => {
"createGenericFolders": true,
"createPlatformFolders": true,
"createRpmPackage": true,
"dockerCrossCompile": false,
"downloadFreshNode": true,
"initialize": true,
"isRelease": false,
Expand Down Expand Up @@ -90,6 +92,7 @@ it('limits packages if --rpm passed with --all-platforms', () => {
"createGenericFolders": true,
"createPlatformFolders": true,
"createRpmPackage": true,
"dockerCrossCompile": false,
"downloadFreshNode": true,
"initialize": true,
"isRelease": false,
Expand Down Expand Up @@ -117,6 +120,7 @@ it('limits packages if --deb passed with --all-platforms', () => {
"createGenericFolders": true,
"createPlatformFolders": true,
"createRpmPackage": false,
"dockerCrossCompile": false,
"downloadFreshNode": true,
"initialize": true,
"isRelease": false,
Expand Down Expand Up @@ -145,6 +149,7 @@ it('limits packages if --docker passed with --all-platforms', () => {
"createGenericFolders": true,
"createPlatformFolders": true,
"createRpmPackage": false,
"dockerCrossCompile": false,
"downloadFreshNode": true,
"initialize": true,
"isRelease": false,
Expand Down Expand Up @@ -180,6 +185,7 @@ it('limits packages if --docker passed with --skip-docker-ubi and --all-platform
"createGenericFolders": true,
"createPlatformFolders": true,
"createRpmPackage": false,
"dockerCrossCompile": false,
"downloadFreshNode": true,
"initialize": true,
"isRelease": false,
Expand Down Expand Up @@ -208,6 +214,7 @@ it('limits packages if --all-platforms passed with --skip-docker-ubuntu', () =>
"createGenericFolders": true,
"createPlatformFolders": true,
"createRpmPackage": true,
"dockerCrossCompile": false,
"downloadFreshNode": true,
"initialize": true,
"isRelease": false,
Expand Down
3 changes: 3 additions & 0 deletions src/dev/build/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export function readCliArgs(argv: string[]) {
'skip-os-packages',
'rpm',
'deb',
'docker-cross-compile',
'docker-images',
'skip-docker-contexts',
'skip-docker-ubi',
Expand Down Expand Up @@ -49,6 +50,7 @@ export function readCliArgs(argv: string[]) {
rpm: null,
deb: null,
'docker-images': null,
'docker-cross-compile': false,
'version-qualifier': '',
},
unknown: (flag) => {
Expand Down Expand Up @@ -94,6 +96,7 @@ export function readCliArgs(argv: string[]) {
const buildOptions: BuildOptions = {
isRelease: Boolean(flags.release),
versionQualifier: flags['version-qualifier'],
dockerCrossCompile: Boolean(flags['docker-cross-compile']),
initialize: !Boolean(flags['skip-initialize']),
downloadFreshNode: !Boolean(flags['skip-node-download']),
createGenericFolders: !Boolean(flags['skip-generic-folders']),
Expand Down
1 change: 1 addition & 0 deletions src/dev/build/build_distributables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as Tasks from './tasks';

export interface BuildOptions {
isRelease: boolean;
dockerCrossCompile: boolean;
downloadFreshNode: boolean;
initialize: boolean;
createGenericFolders: boolean;
Expand Down
1 change: 1 addition & 0 deletions src/dev/build/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ if (showHelp) {
--rpm {dim Only build the rpm packages}
--deb {dim Only build the deb packages}
--docker-images {dim Only build the Docker images}
--docker-cross-compile {dim Produce arm64 and amd64 Docker images}
--docker-contexts {dim Only build the Docker build contexts}
--skip-docker-ubi {dim Don't build the docker ubi image}
--skip-docker-ubuntu {dim Don't build the docker ubuntu image}
Expand Down
1 change: 1 addition & 0 deletions src/dev/build/lib/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const config = new Config(
buildSha: 'abcd1234',
buildVersion: '8.0.0',
},
false,
true
);

Expand Down
1 change: 1 addition & 0 deletions src/dev/build/lib/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const setup = async ({ targetAllPlatforms = true }: { targetAllPlatforms?: boole
return await Config.create({
isRelease: true,
targetAllPlatforms,
dockerCrossCompile: false,
});
};

Expand Down
17 changes: 16 additions & 1 deletion src/dev/build/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ interface Options {
isRelease: boolean;
targetAllPlatforms: boolean;
versionQualifier?: string;
dockerCrossCompile: boolean;
}

interface Package {
Expand All @@ -29,7 +30,12 @@ interface Package {
}

export class Config {
static async create({ isRelease, targetAllPlatforms, versionQualifier }: Options) {
static async create({
isRelease,
targetAllPlatforms,
versionQualifier,
dockerCrossCompile,
}: Options) {
const pkgPath = resolve(__dirname, '../../../../package.json');
const pkg: Package = loadJsonFile.sync(pkgPath);

Expand All @@ -43,6 +49,7 @@ export class Config {
versionQualifier,
pkg,
}),
dockerCrossCompile,
isRelease
);
}
Expand All @@ -53,6 +60,7 @@ export class Config {
private readonly nodeVersion: string,
private readonly repoRoot: string,
private readonly versionInfo: VersionInfo,
private readonly dockerCrossCompile: boolean,
public readonly isRelease: boolean
) {}

Expand All @@ -70,6 +78,13 @@ export class Config {
return this.nodeVersion;
}

/**
* Get docker cross compile
*/
getDockerCrossCompile() {
return this.dockerCrossCompile;
}

/**
* Convert an absolute path to a relative path, based from the repo
*/
Expand Down
1 change: 1 addition & 0 deletions src/dev/build/lib/runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const setup = async () => {
isRelease: true,
targetAllPlatforms: true,
versionQualifier: '-SNAPSHOT',
dockerCrossCompile: false,
});

const run = createRunner({
Expand Down
61 changes: 61 additions & 0 deletions src/dev/build/tasks/download_cloud_dependencies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import Path from 'path';
import del from 'del';
import Axios from 'axios';
import { Task, downloadToDisk, downloadToString } from '../lib';

export const DownloadCloudDependencies: Task = {
description: 'Downloading cloud dependencies',

async run(config, log, build) {
const downloadBeat = async (beat: string, id: string) => {
const subdomain = config.isRelease ? 'artifacts' : 'snapshots';
const version = config.getBuildVersion();
const buildId = id.match(/[0-9]\.[0-9]\.[0-9]-[0-9a-z]{8}/);
const buildIdUrl = buildId ? `${buildId[0]}/` : '';

const localArchitecture = [process.arch === 'arm64' ? 'arm64' : 'x86_64'];
const allArchitectures = ['arm64', 'x86_64'];
const architectures = config.getDockerCrossCompile() ? allArchitectures : localArchitecture;
const downloads = architectures.map(async (arch) => {
const url = `https://${subdomain}-no-kpi.elastic.co/${buildIdUrl}downloads/beats/${beat}/${beat}-${version}-linux-${arch}.tar.gz`;
const checksum = await downloadToString({ log, url: url + '.sha512', expectStatus: 200 });
const destination = config.resolveFromRepo('.beats', Path.basename(url));
return downloadToDisk({
log,
url,
destination,
shaChecksum: checksum.split(' ')[0],
shaAlgorithm: 'sha512',
maxAttempts: 3,
});
});
return Promise.all(downloads);
};

let buildId = '';
if (!config.isRelease) {
const manifestUrl = `https://artifacts-api.elastic.co/v1/versions/${config.getBuildVersion()}/builds/latest`;
try {
const manifest = await Axios.get(manifestUrl);
buildId = manifest.data.build.build_id;
} catch (e) {
log.error(
`Unable to find Elastic artifacts for ${config.getBuildVersion()} at ${manifestUrl}.`
);
throw e;
}
}
await del([config.resolveFromRepo('.beats')]);

await downloadBeat('metricbeat', buildId);
await downloadBeat('filebeat', buildId);
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ async function setup({ failOnUrl }: { failOnUrl?: string } = {}) {
const config = await Config.create({
isRelease: true,
targetAllPlatforms: true,
dockerCrossCompile: false,
});

getNodeDownloadInfo.mockImplementation((_: Config, platform: Platform) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ async function setup() {
const config = await Config.create({
isRelease: true,
targetAllPlatforms: true,
dockerCrossCompile: false,
});

return { config };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ async function setup(actualShaSums?: Record<string, string>) {
const config = await Config.create({
isRelease: true,
targetAllPlatforms: true,
dockerCrossCompile: false,
});

getNodeShasums.mockReturnValue(
Expand Down
3 changes: 2 additions & 1 deletion src/dev/build/tasks/os_packages/docker_generator/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export async function runDockerGenerator(
: []),
];

const dockerCrossCompile = config.getDockerCrossCompile();
const publicArtifactSubdomain = config.isRelease ? 'artifacts' : 'snapshots-no-kpi';
const scope: TemplateContext = {
artifactPrefix,
Expand Down Expand Up @@ -104,7 +105,7 @@ export async function runDockerGenerator(
arm64: 'aarch64',
};
const buildArchitectureSupported = hostTarget[process.arch] === flags.architecture;
if (flags.architecture && !buildArchitectureSupported) {
if (flags.architecture && !buildArchitectureSupported && !dockerCrossCompile) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function generator({
baseOSImage,
architecture,
}: TemplateContext) {
const dockerArchitecture = architecture === 'aarch64' ? 'linux/arm64' : 'linux/amd64';
return dedent(`
#!/usr/bin/env bash
#
Expand Down Expand Up @@ -54,7 +55,7 @@ function generator({
retry_docker_pull ${baseOSImage}
echo "Building: kibana${imageFlavor}-docker"; \\
docker build -t ${imageTag}${imageFlavor}:${version} -f Dockerfile . || exit 1;
docker buildx build --platform ${dockerArchitecture} -t ${imageTag}${imageFlavor}:${version} -f Dockerfile . || exit 1;
docker save ${imageTag}${imageFlavor}:${version} | gzip -c > ${dockerTargetFilename}
Expand Down

0 comments on commit be42eb8

Please sign in to comment.