Skip to content

Commit

Permalink
fix(core): incorrect temp directory when bundling assets
Browse files Browse the repository at this point in the history
The `os.tmpdir()` built-in doesn't return the real path when the
returned path is a symlink.

Add a `FileSystem.tmpdir` that wraps `os.tmpdir()` in a
`fs.realpathSync()` and caches the result.

Fixes #8465
  • Loading branch information
jogold committed Jun 10, 2020
1 parent 1e78a68 commit 5c3dd47
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
3 changes: 1 addition & 2 deletions packages/@aws-cdk/core/lib/asset-staging.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as cxapi from '@aws-cdk/cx-api';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { AssetHashType, AssetOptions } from './assets';
import { BUNDLING_INPUT_DIR, BUNDLING_OUTPUT_DIR, BundlingOptions } from './bundling';
Expand Down Expand Up @@ -137,7 +136,7 @@ export class AssetStaging extends Construct {

private bundle(options: BundlingOptions): string {
// Create temporary directory for bundling
const bundleDir = fs.mkdtempSync(path.resolve(path.join(os.tmpdir(), 'cdk-asset-bundle-')));
const bundleDir = fs.mkdtempSync(path.resolve(path.join(FileSystem.tmpdir, 'cdk-asset-bundle-')));

// Always mount input and output dir
const volumes = [
Expand Down
14 changes: 14 additions & 0 deletions packages/@aws-cdk/core/lib/fs/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as fs from 'fs';
import * as os from 'os';
import { copyDirectory } from './copy';
import { fingerprint } from './fingerprint';
import { CopyOptions, FingerprintOptions } from './options';
Expand Down Expand Up @@ -43,4 +44,17 @@ export class FileSystem {
public static isEmpty(dir: string): boolean {
return fs.readdirSync(dir).length === 0;
}

/**
* The real path of the system temp directory
*/
public static get tmpdir(): string {
if (FileSystem._tmpdir) {
return FileSystem._tmpdir;
}
FileSystem._tmpdir = fs.realpathSync(os.tmpdir());
return FileSystem._tmpdir;
}

private static _tmpdir?: string;
}
35 changes: 35 additions & 0 deletions packages/@aws-cdk/core/test/fs/test.fs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as fs from 'fs';
import { Test } from 'nodeunit';
import * as os from 'os';
import * as path from 'path';
import * as sinon from 'sinon';
import { FileSystem } from '../../lib/fs';

export = {
'tearDown'(callback: any) {
sinon.restore();
callback();
},

'tmpdir returns a real path and is cached'(test: Test) {
const symlinkTmp = path.join(__dirname, 'fixtures', 'symlinks', 'local-dir-link');
const tmpdirStub = sinon.stub(os, 'tmpdir').returns(symlinkTmp);

test.ok(path.isAbsolute(FileSystem.tmpdir));

const p = path.join(FileSystem.tmpdir, 'tmpdir-test.txt');
fs.writeFileSync(p, 'tmpdir-test');

test.equal(p, fs.realpathSync(p));
test.equal(fs.readFileSync(p, 'utf8'), 'tmpdir-test');

test.ok(tmpdirStub.calledOnce); // cached result

fs.unlinkSync(p);

// @ts-ignore
delete FileSystem._tmpdir; // do not use the wrong cached FileSystem.tmpdir in other tests

test.done();
},
};

0 comments on commit 5c3dd47

Please sign in to comment.