[build] Remove default timestamp fix, assert timestamps are valid (#138345)

* [build] Remove default timestamp fix, assert timestamps are valid

* text

* fix date

* remove test
This commit is contained in:
Jonathan Budzenski 2022-08-09 15:24:36 -04:00 committed by GitHub
parent 8eaef36aa3
commit ddc89841a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 74 additions and 54 deletions

View file

@ -108,8 +108,9 @@ export async function buildDistributables(log: ToolingLog, options: BuildOptions
await run(Tasks.CleanExtraBinScripts);
await run(Tasks.CleanNodeBuilds);
await run(Tasks.PathLength);
await run(Tasks.UuidVerification);
await run(Tasks.AssertFileTime);
await run(Tasks.AssertPathLength);
await run(Tasks.AssertNoUUID);
}
/**

View file

@ -7,11 +7,13 @@
*/
import fs from 'fs';
import Fsp from 'fs/promises';
import { createHash } from 'crypto';
import { pipeline, Writable } from 'stream';
import { Writable } from 'stream';
import { pipeline } from 'stream/promises';
import { resolve, dirname, isAbsolute, sep } from 'path';
import { createGunzip } from 'zlib';
import { inspect, promisify } from 'util';
import { inspect } from 'util';
import archiver from 'archiver';
import vfs from 'vinyl-fs';
@ -21,15 +23,6 @@ import deleteEmpty from 'delete-empty';
import tar, { ExtractOptions } from 'tar';
import { ToolingLog } from '@kbn/tooling-log';
const pipelineAsync = promisify(pipeline);
const mkdirAsync = promisify(fs.mkdir);
const writeFileAsync = promisify(fs.writeFile);
const readFileAsync = promisify(fs.readFile);
const readdirAsync = promisify(fs.readdir);
const utimesAsync = promisify(fs.utimes);
const copyFileAsync = promisify(fs.copyFile);
const statAsync = promisify(fs.stat);
export function assertAbsolute(path: string) {
if (!isAbsolute(path)) {
throw new TypeError(
@ -57,23 +50,23 @@ function longInspect(value: any) {
export async function mkdirp(path: string) {
assertAbsolute(path);
await mkdirAsync(path, { recursive: true });
await Fsp.mkdir(path, { recursive: true });
}
export async function write(path: string, contents: string) {
assertAbsolute(path);
await mkdirp(dirname(path));
await writeFileAsync(path, contents);
await Fsp.writeFile(path, contents);
}
export async function read(path: string) {
assertAbsolute(path);
return await readFileAsync(path, 'utf8');
return await Fsp.readFile(path, 'utf8');
}
export async function getChildPaths(path: string) {
assertAbsolute(path);
const childNames = await readdirAsync(path);
const childNames = await Fsp.readdir(path);
return childNames.map((name) => resolve(path, name));
}
@ -141,13 +134,9 @@ export async function copy(source: string, destination: string, options: CopyOpt
assertAbsolute(destination);
// ensure source exists before creating destination directory and copying source
await statAsync(source);
await Fsp.stat(source);
await mkdirp(dirname(destination));
return await copyFileAsync(
source,
destination,
options.clone ? fs.constants.COPYFILE_FICLONE : 0
);
return await Fsp.copyFile(source, destination, options.clone ? fs.constants.COPYFILE_FICLONE : 0);
}
interface CopyAllOptions {
@ -161,12 +150,12 @@ export async function copyAll(
destination: string,
options: CopyAllOptions = {}
) {
const { select = ['**/*'], dot = false, time = new Date() } = options;
const { select = ['**/*'], dot = false, time } = options;
assertAbsolute(sourceDir);
assertAbsolute(destination);
await pipelineAsync(
await pipeline(
vfs.src(select, {
buffer: false,
cwd: sourceDir,
@ -178,8 +167,8 @@ export async function copyAll(
// we must update access and modified file times after the file copy
// has completed, otherwise the copy action can effect modify times.
if (Boolean(time)) {
await pipelineAsync(
if (time) {
await pipeline(
vfs.src(select, {
buffer: false,
cwd: destination,
@ -189,7 +178,7 @@ export async function copyAll(
new Writable({
objectMode: true,
write(file: File, _, cb) {
utimesAsync(file.path, time, time).then(() => cb(), cb);
Fsp.utimes(file.path, time, time).then(() => cb(), cb);
},
})
);
@ -219,9 +208,9 @@ export async function untar(
assertAbsolute(source);
assertAbsolute(destination);
await mkdirAsync(destination, { recursive: true });
await Fsp.mkdir(destination, { recursive: true });
await pipelineAsync(
await pipeline(
fs.createReadStream(source),
createGunzip(),
tar.extract({
@ -235,13 +224,9 @@ export async function gunzip(source: string, destination: string) {
assertAbsolute(source);
assertAbsolute(destination);
await mkdirAsync(dirname(destination), { recursive: true });
await Fsp.mkdir(dirname(destination), { recursive: true });
await pipelineAsync(
fs.createReadStream(source),
createGunzip(),
fs.createWriteStream(destination)
);
await pipeline(fs.createReadStream(source), createGunzip(), fs.createWriteStream(destination));
}
interface CompressTarOptions {

View file

@ -244,20 +244,6 @@ describe('copyAll()', () => {
expect(Math.abs(fooDir.atimeMs - time.getTime())).toBeLessThan(oneDay);
expect(Math.abs(barTxt.mtimeMs - time.getTime())).toBeLessThan(oneDay);
});
it('defaults atime and mtime to now', async () => {
const destination = resolve(TMP, 'a/b/c/d/e/f');
await copyAll(FIXTURES, destination);
const barTxt = statSync(resolve(destination, 'foo_dir/bar.txt'));
const fooDir = statSync(resolve(destination, 'foo_dir'));
// precision is platform specific
const now = new Date();
const oneDay = 86400000;
expect(Math.abs(barTxt.atimeMs - now.getTime())).toBeLessThan(oneDay);
expect(Math.abs(fooDir.atimeMs - now.getTime())).toBeLessThan(oneDay);
expect(Math.abs(barTxt.mtimeMs - now.getTime())).toBeLessThan(oneDay);
});
});
describe('getFileHash()', () => {

View file

@ -0,0 +1,47 @@
/*
* 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 { resolve } from 'path';
import { statSync } from 'fs';
import { tap, filter, map, toArray } from 'rxjs/operators';
import { scan$, Task } from '../lib';
export const AssertFileTime: Task = {
description: 'Checking for files dated before 1980',
async run(config, log, build) {
const buildRoot = build.resolvePath();
await scan$(buildRoot)
.pipe(
map((path) => resolve(buildRoot, path)),
filter((file) => {
const { atimeMs, mtimeMs, ctimeMs } = statSync(file);
// tarred files with timestamps before 1970 throw errors
// zipped files with timestamps before 1980 throw errors
// round up to 1981 to avoid timezones
const invalidDate = new Date(1981, 0, 1).getTime();
return invalidDate > atimeMs || invalidDate > mtimeMs || invalidDate > ctimeMs;
}),
toArray(),
tap((invalidDates) => {
if (!invalidDates.length) {
return;
}
throw new Error(
'Archive errors occur with file times before 1980. The following files have errors:' +
'\n - ' +
invalidDates.join('\n - ')
);
})
)
.toPromise();
},
};

View file

@ -8,7 +8,7 @@
import { read, Task } from '../lib';
export const UuidVerification: Task = {
export const AssertNoUUID: Task = {
description: 'Verify that no UUID file is baked into the build',
async run(config, log, build) {

View file

@ -12,7 +12,7 @@ import { tap, filter, map, toArray } from 'rxjs/operators';
import { scan$, Task } from '../lib';
export const PathLength: Task = {
export const AssertPathLength: Task = {
description: 'Checking Windows for paths > 200 characters',
async run(config, log, build) {

View file

@ -28,10 +28,11 @@ export * from './notice_file_task';
export * from './os_packages';
export * from './package_json';
export * from './patch_native_modules_task';
export * from './path_length_task';
export * from './assert_file_time';
export * from './assert_no_uuid';
export * from './assert_path_length';
export * from './replace_favicon';
export * from './transpile_babel_task';
export * from './uuid_verification_task';
export * from './verify_env_task';
export * from './write_sha_sums_task';
export * from './fetch_agent_versions_list';