-
Notifications
You must be signed in to change notification settings - Fork 8k
/
patch_native_modules_task.ts
129 lines (117 loc) · 4.16 KB
/
patch_native_modules_task.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* 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 { 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.16.0',
destinationPath: 'node_modules/re2/build/Release/re2.node',
extractMethod: 'gunzip',
archives: {
'darwin-x64': {
url: 'https://github.com/uhop/node-re2/releases/download/1.16.0/darwin-x64-93.gz',
sha256: 'a267c6202d86d08170eb4a833acf81d83660ce33e8981fcd5b7f6e0310961d56',
},
'linux-x64': {
url: 'https://github.com/uhop/node-re2/releases/download/1.16.0/linux-x64-93.gz',
sha256: 'e0ca5d6527fe7ec0fe98b6960c47b66a5bb2823c3bebb3bf4ed4d58eed3d23c5',
},
// 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
// * git submodule update --init --recursive to download re2
// * npm install, which will also create a build
// * gzip -c build/Release/re2.node > linux-arm64-83.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.16.0/linux-arm64-93.gz',
sha256: '7a786e0b75985e5aafdefa9af55cad8e85e69a3326f16d8c63d21d6b5b3bff1b',
},
'win32-x64': {
url: 'https://github.com/uhop/node-re2/releases/download/1.16.0/win32-x64-93.gz',
sha256: '37245ceb59a086b5e7e9de8746a3cdf148c383be9ae2580f92baea90d0d39947',
},
},
},
];
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);
})
);
}
},
};