kibana/src/dev/build/tasks/patch_native_modules_task.ts
Tyler Smalley e892b03173
[build] Provide ARM build of RE2 (#84163)
Signed-off-by: Tyler Smalley <tyler.smalley@elastic.co>
2020-11-24 08:24:26 -08:00

140 lines
4.5 KiB
TypeScript

/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import path from 'path';
import { ToolingLog } from '@kbn/dev-utils';
import { deleteAll, download, gunzip, untar, Task, Config, Build, Platform, read } from '../lib';
const DOWNLOAD_DIRECTORY = '.native_modules';
interface Package {
name: string;
version: string;
destinationPath: string;
extractMethod: string;
archives: Record<
string,
{
url: string;
sha256: string;
}
>;
}
const packages: Package[] = [
{
name: 're2',
version: '1.15.4',
destinationPath: 'node_modules/re2/build/Release/re2.node',
extractMethod: 'gunzip',
archives: {
'darwin-x64': {
url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/darwin-x64-72.gz',
sha256: '983106049bb86e21b7f823144b2b83e3f1408217401879b3cde0312c803512c9',
},
'linux-x64': {
url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/linux-x64-72.gz',
sha256: '8b6692037f7b0df24dabc9c9b039038d1c3a3110f62121616b406c482169710a',
},
// ARM build is currently done manually as Github Actions used in upstream project
// do not natively support an ARM target.
// From a AWS Graviton instance:
// * checkout the node-re2 project,
// * install Node using the same minor used by Kibana
// * npm install, which will also create a build
// * gzip -c build/Release/re2.node > linux-arm64-72.gz
// * upload to kibana-ci-proxy-cache bucket
'linux-arm64': {
url:
'https://storage.googleapis.com/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.15.4/linux-arm64-72.gz',
sha256: '5942353ec9cf46a39199818d474f7af137cfbb1bc5727047fe22f31f36602a7e',
},
'win32-x64': {
url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/win32-x64-72.gz',
sha256: '0a6991e693577160c3e9a3f196bd2518368c52d920af331a1a183313e0175604',
},
},
},
];
async function getInstalledVersion(config: Config, packageName: string) {
const packageJSONPath = config.resolveFromRepo(
path.join('node_modules', packageName, 'package.json')
);
const json = await read(packageJSONPath);
const packageJSON = JSON.parse(json);
return packageJSON.version;
}
async function patchModule(
config: Config,
log: ToolingLog,
build: Build,
platform: Platform,
pkg: Package
) {
const installedVersion = await getInstalledVersion(config, pkg.name);
if (installedVersion !== pkg.version) {
throw new Error(
`Can't patch ${pkg.name}'s native module, we were expecting version ${pkg.version} and found ${installedVersion}`
);
}
const platformName = platform.getNodeArch();
const archive = pkg.archives[platformName];
const archiveName = path.basename(archive.url);
const downloadPath = config.resolveFromRepo(DOWNLOAD_DIRECTORY, pkg.name, archiveName);
const extractPath = build.resolvePathForPlatform(platform, pkg.destinationPath);
log.debug(`Patching ${pkg.name} binaries from ${archive.url} to ${extractPath}`);
await deleteAll([extractPath], log);
await download({
log,
url: archive.url,
destination: downloadPath,
sha256: archive.sha256,
retries: 3,
});
switch (pkg.extractMethod) {
case 'gunzip':
await gunzip(downloadPath, extractPath);
break;
case 'untar':
await untar(downloadPath, extractPath);
break;
default:
throw new Error(`Extract method of ${pkg.extractMethod} is not supported`);
}
}
export const PatchNativeModules: Task = {
description: 'Patching platform-specific native modules',
async run(config, log, build) {
for (const pkg of packages) {
await Promise.all(
config.getTargetPlatforms().map(async (platform) => {
await patchModule(config, log, build, platform, pkg);
})
);
}
},
};