Issue with nodejs plugin when using base keyword

I am having issues with running snapcraft with the nodejs plugin with the base keyword. When running in a VM, npm seems to have permissions issues when running node-gyp and other shell commands. I’ve tested out these commands in the VM shell by running --debug, and they work fine for me, so I am not sure why this isn’t working. Does anyone have any advice here?

> websocket@1.0.28 install /root/parts/projs-node/build/node_modules/websocket
> (node-gyp rebuild 2> builderror.log) || (exit 0)

sh: 1: cannot create builderror.log: Permission denied
sh: 1: node-gyp: Permission denied

> nodegit@0.23.1 install /root/parts/projs-node/build/node_modules/nodegit
> node lifecycleScripts/preinstall && node lifecycleScripts/install

sh: 1: node: Permission denied
npm WARN nodemon-webpack-plugin@3.0.2 requires a peer of webpack@^2 || ^3 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.8 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.8: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn
npm ERR! nodegit@0.23.1 install: `node lifecycleScripts/preinstall && node lifecycleScripts/install`
npm ERR! spawn ENOENT
npm ERR! 
npm ERR! Failed at the nodegit@0.23.1 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2019-04-25T04_47_03_084Z-debug.log
Failed to run '/root/parts/projs-node/npm/bin/npm install --prod' for 'projs-node': Exited with code 1.
Verify that the part is using the correct parameters and try again.
Run the same command again with --debug to shell into the environment if you wish to introspect this failure.
An error occurred when trying to execute 'sudo -i env SNAPCRAFT_HAS_TTY=True snapcraft snap' with 'multipass': returned exit code 2.

Can we see more output please?

Snapcraft log: https://pastebin.com/3RjtGXa0
npm log: https://pastebin.com/gnpzFYa7

@sergiusens do you have any idea what’s going on here?

Your issue lies with nodegit:

> node lifecycleScripts/preinstall && node lifecycleScripts/install
 
sh: 1: node: Permission denied

and:

16981 verbose lifecycle nodegit@0.23.1~install: CWD: /root/parts/roshubd/build/node_modules/nodegit
16982 silly lifecycle nodegit@0.23.1~install: Args: [ '-c',
16982 silly lifecycle   'node lifecycleScripts/preinstall && node lifecycleScripts/install' ]
16983 info lifecycle nodegit@0.23.1~install: Failed to exec install script

Specifically it is trying to execute node which is failing with a permission denied error.

It needs npm config set unsafe-perm true in override-pull(probably).
See https://geedew.com/What-does-unsafe-perm-in-npm-actually-do/

It might also be because node is a wrapper script and has the wrong permissions set?

It is mainly because npm drops the root uid/gid for the scripts to prevent them from messing up your system. That makes sense in general, just not in a multipass container where the whole build etc. is run as root.

Adding this to override-pull does not work, since npm isn’t available at that point yet
Adding export npm_config_unsafe_perm=true did not help either

I’d say try adding it to .npmrc. See https://docs.npmjs.com/misc/config
I haven’t successfully used the nodejs plugin so far, but I can confirm that unsafe-perm works in practice (https://github.com/ppd1990/gopass-ui-snap/blob/master/snap/snapcraft.yaml).

Ah. If I remember correctly, the default package manager is yarn. So maybe the config is to be set differently there.

That is true, but the docs say npm afaik. Could that be updated as well?

https://snapcraft.io/docs/nodejs-plugin says npm. https://github.com/snapcore/snapcraft/blob/master/snapcraft/plugins/nodejs.py says yarn. So yes, that is misleading.

Edit: Fixed doc

3 Likes

Hey, it just so happened I was doing something else with nodejs snapcraft just now and I was having the same issue, and this fixed it. Thanks!

Bump, this issue still exists. I am working around this by not using npm plugin and manually shipping node in my snap somehow.

Try:

build-environment:
  npm_config_unsafe_perm: true
  SUDO_UID: 0
  SUDO_GID: 0
  SUDO_USER: root

The topic above alread touches on npm_config_unsafe_perm, which is entirely necessarily, but there’s is a similar problem with node where build scripts call out to external binaries such as git, they fork a new process and attempt to drop permissions to a lower priviledged user causing errors. The SUDO_ variables work around this issue.