Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: More resillient global and cache folder determination #4325

Merged
merged 15 commits into from
Sep 7, 2017
Merged

Conversation

BYK
Copy link
Member

@BYK BYK commented Sep 6, 2017

Summary

Fixes #4320 and fixes #4323. We were using fs.access when selecting
the global prefix folder automatically and expecting only an EACCES error.
This caused issues on Heroku where one of our first tries had threw an
EROFS error.

This patch also adds $DESTIR support back, which was removed in #3721,
probably inadvertently.

Test plan

Existing cache folder fallback tests should be enough for now. We should
move the core of those tests for the newly added fs.getFirstWriteableFolder
method.

**Summary**

Fixes #4320 and fixes #4323. We were using `fs.access` when selecting
the global prefix folder automatically which only checks for permissions
but not actual writeability. This caused issues on Heroku where one of
our first tries had the correct permissions but was on a read-only
file system.

**Test plan**

Existing cache folder fallback tests should be enough for now. We should
move the core of those tests for the newly added `fs.getFirstWriteableFolder`
method.
@BYK BYK requested a review from arcanis September 6, 2017 14:45
@BYK BYK added this to Awaiting Review in Yarn 1.0 Sep 6, 2017
src/constants.js Outdated
@@ -82,7 +82,7 @@ function getYarnBinPath(): string {
export const NODE_MODULES_FOLDER = 'node_modules';
export const NODE_PACKAGE_JSON = 'package.json';

export const POSIX_GLOBAL_PREFIX = '/usr/local';
export const POSIX_GLOBAL_PREFIX = `${process.env.DESTIR || ''}/usr/local`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(DESTIR instead of DESTDIR)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

darn

src/util/fs.js Outdated
const result: FolderQueryResult = {
skipped: [],
folder: null,
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we just return a raw string? The list of skipped directories can be deduced relatively easily by the caller anyway.

Copy link
Member Author

@BYK BYK Sep 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I also attach the error, in case that matters. May be it is EACCESS, may be it is EROFS or may be it is something else?

Also deducing the list would require another traversal of the entire list until the selected folder is found which is a bit unnecessary.

src/config.js Outdated
}
const cacheFolderQuery = await fs.getFirstWriteableFolder(preferredCacheFolders);
for (const failedFolder of cacheFolderQuery.skipped) {
this.reporter.warn(this.reporter.lang('cacheFolderSkipped', failedFolder));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

failedFolder is not a string, so the display will probably be wrong. I think you meant failedFolder.folder? The variable name would probably be better as skippedEntry btw, so that it would be skippedEntry.folder

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup to both, good catch!

@buildsize
Copy link

buildsize bot commented Sep 6, 2017

This change will increase the build size from 9.51 MB to 9.51 MB, an increase of 5.92 KB (0%)

File name Previous Size New Size Change
yarn-[version].noarch.rpm 819.13 KB 819.42 KB 295 bytes (0%)
yarn-[version].js 3.62 MB 3.62 MB 2.51 KB (0%)
yarn-legacy-[version].js 3.67 MB 3.67 MB 2.53 KB (0%)
yarn-v[version].tar.gz 823.22 KB 823.58 KB 366 bytes (0%)
yarn_[version]all.deb 626.07 KB 626.3 KB 238 bytes (0%)

@BYK BYK changed the title Fix: Make sure global prefix folder is writeable when selecting it Fix: More resillient global and cache folder determination Sep 6, 2017
throw err;
}
const binFolders = potentialPrefixFolders.map(prefix => path.join(prefix, 'bin'));
const prefixFolderQueryResult = await fs.getFirstSuitableFolder(binFolders);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the problem with this code:
We only need write permissions when doing yarn global add which is usually called with sudo or similar. That said if we change our permission checks depending on usage, then we may end up using two different global folders based on how yarn is called (with sudo and without) which would make running yarn global add useless.

I think we should just check R_OK and X_OK here but doing that caused some failing tests (which can be fixed, I'm sure). This would also be a breaking change. That said I'm almost certain that POSIX_GLOBAL_PREFIX/bin won't be writeable to yarn by default. What do you think?

@arcanis arcanis merged commit 03a16d0 into master Sep 7, 2017
@cpojer cpojer moved this from Awaiting Review to Done in Yarn 1.0 Sep 7, 2017
@thomaswrenn
Copy link

thomaswrenn commented Sep 7, 2017

Can v1.0.1 be published to npm?

We're having the heroku issue on our build systems.

@BYK BYK deleted the erofs branch September 8, 2017 04:59
@BYK
Copy link
Member Author

BYK commented Sep 8, 2017

@thomaswrenn should be on npm right now?

joaolucasl pushed a commit to joaolucasl/yarn that referenced this pull request Oct 27, 2017
)

* Fix: Make sure global prefix folder is writeable when selecting it

**Summary**

Fixes yarnpkg#4320 and fixes yarnpkg#4323. We were using `fs.access` when selecting
the global prefix folder automatically which only checks for permissions
but not actual writeability. This caused issues on Heroku where one of
our first tries had the correct permissions but was on a read-only
file system.

**Test plan**

Existing cache folder fallback tests should be enough for now. We should
move the core of those tests for the newly added `fs.getFirstWriteableFolder`
method.

* Fix wrong error message template used from getGlobalPrefix

* Better error message

* Add process.execPath as a last resort

* Add back $DESTDIR support removed from yarnpkg#3721

* Fix DESTDIR typo

* Fix skippedFolder error

* don't use rimraf to remove a file

* Don't use process.execPath

* Defer write checks for global prefix

* flow type

* Just warn when a proper global folder cannot be found, instead of failing

* Add TODO about inconsistent npm-registry code

* Keep the old behavior

* Update fs.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

Chore: consolidate writeable directory finding logic Failing build on Heroku with 1.0.0
3 participants