inability to percolate sudo mode to postInstall

What I Wanted to Do

sudo npm install <module> -g

expectation is for the module to be installed

What Happened Instead

error, if the module’s postInstall script contain UNIX commands that works on the files created by the installer

Reproduction Steps

#cat package.json

{
  "name": "foo",
  "version": "1.0.0",
  "scripts": {
    "postinstall": "node ./index.js"
  }
}

#cat index.js

console.log('hello')

#sudo npm install -g

> foo@1.0.0 postinstall /usr/local/lib/node_modules/foo
> node ./index.js

shell-init: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
path.js:976
      const path = i >= 0 ? args[i] : process.cwd();
                                              ^

Error: EACCES: permission denied, uv_cwd
    at Object.resolve (path.js:976:47)
    at patchProcessObject (internal/bootstrap/pre_execution.js:73:28)
    at prepareMainThreadExecution (internal/bootstrap/pre_execution.js:10:3)
    at internal/main/run_main_module.js:7:1
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! foo@1.0.0 postinstall: `node ./index.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the foo@1.0.0 postinstall script.

Details

The root cause is that the installation happens with admin user, while the postInstall step is carried out through login user, who has less privilege to access the installation location.

How do we solve this? I know two workarounds:

  • remove sudo
  • download the packge, edit the postInstall step and prepend sudo

neither of which are clean.

Platform Info

$ npm --versions
<!-- paste output here -->
{
  foo: '1.0.0',
  npm: '6.12.0',
  ares: '1.15.0',
  brotli: '1.0.7',
  cldr: '35.1',
  icu: '64.2',
  llhttp: '1.1.4',
  modules: '79',
  napi: '5',
  nghttp2: '1.39.2',
  node: '13.0.1',
  openssl: '1.1.1d',
  tz: '2019a',
  unicode: '12.1',
  uv: '1.33.1',
  v8: '7.8.279.17-node.14',
  zlib: '1.2.11'
}

but looks like it is version-agnostic
$ node -p process.platform
<!-- paste output here -->
darwin

but looks like it is platform-agnostic

references: 
https://github.com/nodejs/help/issues/2013
https://github.com/nodejs/help/issues/2041

Have you tried --unsafe-perm? I have not tried it with your reproduction steps yet (thanks), but it is the relevant option: https://docs.npmjs.com/misc/config#unsafe-perm

1 Like

@shadowspawn - thanks, it works! Is it an unsupported option? I cant find it in the help:

#npm install --help

npm install (with no args, in package dir)
npm install [<@scope>/]<pkg>
npm install [<@scope>/]<pkg>@<tag>
npm install [<@scope>/]<pkg>@<version>
npm install [<@scope>/]<pkg>@<version range>
npm install <folder>
npm install <tarball file>
npm install <tarball url>
npm install <git:// url>
npm install <github username>/<github project>

aliases: i, isntall, add
common options: [--save-prod|--save-dev|--save-optional] [--save-exact] [--no-save]

apologies, forget the previous comment, did not read fully! :slight_smile:

1 Like

(There are so many configuration options possible that they are not all listed with each individual command.)

1 Like

understood, and makes sense! thanks.

I have recommended this option to my users in the downstream project who are running real workloads than my tiny recreate, so let us wait to see if this indeed solves their issue. hopefully they will come back in a couple of days!

Thanks again!

1 Like