dinghy: npm throws Operation not permitted

Using dinghy, when I try to npm install something, it complains:

npm ERR! Error: EPERM, chown '/shared/node_modules/gulp/package.json'
npm ERR!  { [Error: EPERM, chown '/shared/node_modules/gulp/package.json']
npm ERR!   errno: 50,
npm ERR!   code: 'EPERM',
npm ERR!   path: '/shared/node_modules/gulp/package.json',
npm ERR!   fstream_finish_call: 'chown',
npm ERR!   fstream_type: 'File',
npm ERR!   fstream_path: '/shared/node_modules/gulp/package.json',
npm ERR!   fstream_class: 'FileWriter',
npm ERR!   fstream_stack: 
npm ERR!    [ '/usr/lib/nodejs/fstream/lib/writer.js:305:19',
npm ERR!      '/usr/lib/nodejs/graceful-fs/polyfills.js:143:7',
npm ERR!      'Object.oncomplete (evalmachine.<anonymous>:107:15)' ] }
npm ERR! 
npm ERR! Please try running this command again as root/Administrator.

npm ERR! System Linux 3.18.11-tinycore64
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "install" "gulp"
npm ERR! cwd /shared
npm ERR! node -v v0.10.29
npm ERR! npm -v 1.4.21
npm ERR! path /shared/node_modules/gulp/package.json
npm ERR! fstream_path /shared/node_modules/gulp/package.json
npm ERR! fstream_type File
npm ERR! fstream_class FileWriter
npm ERR! fstream_finish_call chown
npm ERR! code EPERM
npm ERR! errno 50
npm ERR! stack Error: EPERM, chown '/shared/node_modules/gulp/package.json'
npm ERR! fstream_stack /usr/lib/nodejs/fstream/lib/writer.js:305:19
npm ERR! fstream_stack /usr/lib/nodejs/graceful-fs/polyfills.js:143:7
npm ERR! fstream_stack Object.oncomplete (evalmachine.<anonymous>:107:15)
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /shared/npm-debug.log
npm ERR! not ok code 0

It used to work well on boot2docker, even when using nfs.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 17 (2 by maintainers)

Commits related to this issue

Most upvoted comments

There’s a comment here: https://github.com/npm/npm/issues/3565#issuecomment-202473011 showing a nice way to overcome that - you can make chmod do nothing by using LD_PRELOAD.

You can do it for the entire container in Dockerfile. First make sure you’ve gcc installed, and then add:

RUN echo "int chown() { return 0; }" > preload.c && gcc -shared -o /libpreload.so preload.c && rm preload.c
ENV LD_PRELOAD=/libpreload.so

This simply makes chmod think it actually did something and succeed, so npm is all happy and confident it did a good job.

You can also do it just for one command - just call npm install this way (again, you need gcc):

echo "int chown() { return 0; }" > preload.c && gcc -shared -o preload.so preload.c && LD_PRELOAD=$PWD/preload.so npm install && rm preload.c preload.so

This is driving me nuts. In our dev environments, my team mounts their home folder to /root due to needing access to the NPM login token, AWS credentials, shared NPM cache, etc stored there. This worked well with docker implementations where root took ownership of new files (we’ve used dlite with success in the past, but lack of maintenance is making that one tough to use now). Under dinghy’s model of setting root to use the executing user/group’s access levels, I get this every time I NPM install, even if I delete ~/.npm first:

npm ERR! Error: EPERM: operation not permitted, chown '/root/.npm/_locks'
npm ERR!     at Error (native)
npm ERR!  { Error: EPERM: operation not permitted, chown '/root/.npm/_locks'
npm ERR!     at Error (native)
npm ERR!   errno: -1,
npm ERR!   code: 'EPERM',
npm ERR!   syscall: 'chown',
npm ERR!   path: '/root/.npm/_locks' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
npm ERR! Linux 4.4.17-boot2docker
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install" "-g" "node-gyp"
npm ERR! node v6.3.1
npm ERR! npm  v3.10.5
npm ERR! path npm-debug.log.737059936
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall open

So I did a code-dive and discovered the :custom_nfs_export_options preference. “Eureka!” I thought. So I popped open my system’s /etc/exports and grabbed this line that dlite injected: /Users -network 192.168.64.0 -mask 255.255.255.0 -alldirs -maproot=root:wheel and converted that to what it looked like dinghy’s bundled NFS needed. I ended up with these prefs:

---
:preferences:
  :proxy_disabled: false
  :fsevents_disabled: false
  :create:
    provider: xhyve
  :custom_nfs_export_options: rw,alldirs,maproot=root:wheel

After a dinghy restart, I confirmed that my machine-nfs-exports-dinghy file had the appropriate settings. Hurrah!

…but my in-container npm install still failed. I got the same error as before, and this one:

npm ERR! Error: EACCES: permission denied, open 'npm-debug.log.737059936'
npm ERR!     at Error (native)
npm ERR!  { Error: EACCES: permission denied, open 'npm-debug.log.737059936'
npm ERR!     at Error (native)
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'open',
npm ERR!   path: 'npm-debug.log.737059936' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

I really, really do not want to do the chown hack mentioned above if there’s an nfs configuration that can restore the old functionality. Any idea why my solution didn’t take care of this?

EDIT: Neeeevermind. Rather than maproot=root:wheel, I did anonuid=0,anongid=0. Worked like a charm. I don’t get the dinghy fanciness of keeping everything under my local user’s ownership, but at least my native npm modules build now.

@ryanmt Turns out it was an issue with maproot. Dinghy does not map the root to 0 which causes some issues when trying to run any privileged command when trying to use that command on Volumes mounted with NFS.