Skip to content

Commit

Permalink
fix(core): incorrect temp directory when bundling assets (aws#8469)
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.

Add a `FileSystem.mkdtemp()` to create temp directories in
the system temp directory.

Fixes aws#8465


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
jogold authored Jun 10, 2020
1 parent de5e406 commit 9dc2e04
Show file tree
Hide file tree
Showing 3 changed files with 74 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 = FileSystem.mkdtemp('cdk-asset-bundle-');

// Always mount input and output dir
const volumes = [
Expand Down
25 changes: 25 additions & 0 deletions packages/@aws-cdk/core/lib/fs/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { copyDirectory } from './copy';
import { fingerprint } from './fingerprint';
import { CopyOptions, FingerprintOptions } from './options';
Expand Down Expand Up @@ -43,4 +45,27 @@ 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;
}

/**
* Creates a unique temporary directory in the **system temp directory**.
*
* @param prefix A prefix for the directory name. Six random characters
* will be generated and appended behind this prefix.
*/
public static mkdtemp(prefix: string): string {
return fs.mkdtempSync(path.join(FileSystem.tmpdir, prefix));
}

private static _tmpdir?: string;
}
48 changes: 48 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,48 @@
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) {
// Create symlink that points to /tmp
const symlinkTmp = path.join(__dirname, 'tmp-link');
fs.symlinkSync(os.tmpdir(), symlinkTmp);

// Now stub os.tmpdir() to return this link instead of /tmp
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);
fs.unlinkSync(symlinkTmp);

test.done();
},

'mkdtemp creates a temporary directory in the system temp'(test: Test) {
const tmpdir = FileSystem.mkdtemp('cdk-mkdtemp-');

test.equal(path.dirname(tmpdir), FileSystem.tmpdir);
test.ok(fs.existsSync(tmpdir));

fs.rmdirSync(tmpdir);

test.done();
},
};

0 comments on commit 9dc2e04

Please sign in to comment.