bbc / speculate

Automatically generates an RPM Spec file for your Node.js project
Other
66 stars 28 forks source link

Problems with speculate + mock + node-gyp #57

Open njh opened 6 years ago

njh commented 6 years ago

Hi,

I have been trying to build a small application that generates images using node-canvas. canvas uses the Cairo C library to do all the hard work and fortunately it exists as an RPM in CentOS 7.

However when building using mock, I was getting errors that I didn't see when building using outside of a chroot. Annoyingly the error messages weren't very helpful and say things like "This is most likely not a problem with node-gyp" but concealed the actual problem.

This is the command I was running: mock -r epel-7-x86_64 --rebuild --no-clean SRPMS/foo.src.rpm

And this part of the output:

> canvas@2.0.1 install /builddir/build/BUILD/radiovis-slides/node_modules/canvas
> node-pre-gyp install --fallback-to-build

node-pre-gyp WARN Using needle for node-pre-gyp https download 
node-pre-gyp WARN Pre-built binaries not installable for canvas@2.0.1 and node@6.14.3 (node-v48 ABI, glibc) (falling back to source compile with node-gyp) 
node-pre-gyp WARN Hit error getaddrinfo ENOTFOUND github.com github.com:443 
gyp WARN install got an error, rolling back install
gyp ERR! configure error 
gyp ERR! stack Error: This is most likely not a problem with node-gyp or the package itself and
gyp ERR! stack is related to network connectivity. In most cases you are behind a proxy or have bad 
gyp ERR! stack network settings.
gyp ERR! stack     at Request.<anonymous> (/usr/lib/node_modules/npm/node_modules.bundled/node-gyp/lib/install.js:193:21)
gyp ERR! stack     at emitOne (events.js:96:13)
gyp ERR! stack     at Request.emit (events.js:188:7)
gyp ERR! stack     at Request.onRequestError (/usr/lib/node_modules/npm/node_modules.bundled/request/request.js:813:8)
gyp ERR! stack     at emitOne (events.js:96:13)
gyp ERR! stack     at ClientRequest.emit (events.js:188:7)
gyp ERR! stack     at TLSSocket.socketErrorListener (_http_client.js:314:9)
gyp ERR! stack     at emitOne (events.js:96:13)
gyp ERR! stack     at TLSSocket.emit (events.js:188:7)
gyp ERR! stack     at connectErrorNT (net.js:1034:8)
gyp ERR! System Linux 3.10.0-862.9.1.el7.x86_64
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/builddir/build/BUILD/radiovis-slides/node_modules/canvas/build/Release/canvas-prebuilt.node" "--module_name=canvas-prebuilt" "--module_path=/builddir/build/BUILD/radiovis-slides/node_modules/canvas/build/Release" "--napi_version=3" "--node_abi_napi=napi" "--napi_build_version=0" "--node_napi_label=node-v48"
gyp ERR! cwd /builddir/build/BUILD/radiovis-slides/node_modules/canvas
gyp ERR! node -v v6.14.3
gyp ERR! node-gyp -v v3.4.0
gyp ERR! not ok 
Failed to execute '/usr/bin/node /usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/builddir/build/BUILD/radiovis-slides/node_modules/canvas/build/Release/canvas-prebuilt.node --module_name=canvas-prebuilt --module_path=/builddir/build/BUILD/radiovis-slides/node_modules/canvas/build/Release --napi_version=3 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v48' (1)
node-pre-gyp ERR! build error 
node-pre-gyp ERR! stack Error: Failed to execute '/usr/bin/node /usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/builddir/build/BUILD/radiovis-slides/node_modules/canvas/build/Release/canvas-prebuilt.node --module_name=canvas-prebuilt --module_path=/builddir/build/BUILD/radiovis-slides/node_modules/canvas/build/Release --napi_version=3 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v48' (1)
node-pre-gyp ERR! stack     at ChildProcess.<anonymous> (/builddir/build/BUILD/radiovis-slides/node_modules/node-pre-gyp/lib/util/compile.js:83:29)
node-pre-gyp ERR! stack     at emitTwo (events.js:106:13)
node-pre-gyp ERR! stack     at ChildProcess.emit (events.js:191:7)
node-pre-gyp ERR! stack     at maybeClose (internal/child_process.js:920:16)
node-pre-gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:230:5)
node-pre-gyp ERR! System Linux 3.10.0-862.9.1.el7.x86_64
node-pre-gyp ERR! command "/usr/bin/node" "/builddir/build/BUILD/radiovis-slides/node_modules/.bin/node-pre-gyp" "install" "--fallback-to-build"
node-pre-gyp ERR! cwd /builddir/build/BUILD/radiovis-slides/node_modules/canvas
node-pre-gyp ERR! node -v v6.14.3
node-pre-gyp ERR! node-pre-gyp -v v0.11.0
node-pre-gyp ERR! not ok 

npm ERR! Linux 3.10.0-862.9.1.el7.x86_64
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "rebuild"
npm ERR! node v6.14.3
npm ERR! npm  v3.10.10
npm ERR! code ELIFECYCLE
npm ERR! canvas@2.0.1 install: `node-pre-gyp install --fallback-to-build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the canvas@2.0.1 install script 'node-pre-gyp install --fallback-to-build'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the canvas package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-pre-gyp install --fallback-to-build
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs canvas
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls canvas
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /builddir/build/BUILD/radiovis-slides/npm-debug.log

Within the mock environment, it is not possible to access the internet. This is a good thing because it ensures that you should get the identical output, given the same inputs and not be dependant on the outside world changing. But that didn't explain what was actually failing.

By running mock -r epel-7-x86_64 --shell, I was able to inspect the mock build environment and see what is going on. I ran node-gyp manually within the node_modules/canvas directory:

<mock-chroot> sh-4.2# /usr/bin/node /usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/builddir/build/BUILD/radiovis-slides/node_modules/canvas/build/Release/canvas-prebuilt.node --module_name=canvas-prebuilt --module_path=/builddir/build/BUILD/radiovis-slides/node_modules/canvas/build/Release --napi_version=3 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v48
gyp info it worked if it ends with ok
gyp info using node-gyp@3.4.0
gyp info using node@6.14.3 | linux | x64
gyp http GET https://nodejs.org/download/release/v6.14.3/node-v6.14.3-headers.tar.gz
gyp WARN install got an error, rolling back install
gyp ERR! configure error 
gyp ERR! stack Error: This is most likely not a problem with node-gyp or the package itself and
gyp ERR! stack is related to network connectivity. In most cases you are behind a proxy or have bad 
gyp ERR! stack network settings.
gyp ERR! stack     at Request.<anonymous> (/usr/lib/node_modules/npm/node_modules.bundled/node-gyp/lib/install.js:193:21)
gyp ERR! stack     at emitOne (events.js:96:13)
gyp ERR! stack     at Request.emit (events.js:188:7)
gyp ERR! stack     at Request.onRequestError (/usr/lib/node_modules/npm/node_modules.bundled/request/request.js:813:8)
gyp ERR! stack     at emitOne (events.js:96:13)
gyp ERR! stack     at ClientRequest.emit (events.js:188:7)
gyp ERR! stack     at TLSSocket.socketErrorListener (_http_client.js:314:9)
gyp ERR! stack     at emitOne (events.js:96:13)
gyp ERR! stack     at TLSSocket.emit (events.js:188:7)
gyp ERR! stack     at connectErrorNT (net.js:1034:8)
gyp ERR! System Linux 3.10.0-862.9.1.el7.x86_64
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/builddir/build/BUILD/radiovis-slides/node_modules/canvas/build/Release/canvas-prebuilt.node" "--module_name=canvas-prebuilt" "--module_path=/builddir/build/BUILD/radiovis-slides/node_modules/canvas/build/Release" "--napi_version=3" "--node_abi_napi=napi" "--napi_build_version=0" "--node_napi_label=node-v48"
gyp ERR! cwd /builddir/build/BUILD/radiovis-slides/node_modules/canvas
gyp ERR! node -v v6.14.3
gyp ERR! node-gyp -v v3.4.0
gyp ERR! not ok 

So node-gyp is failing because it is trying to download the C headers for the current version of node-js. These same headers are provided by the nodejs-devel RPM and they are installed into /usr/include/node. I guess node-gyp doesn't know that they are there. Or doesn't know that they are the right headers for the current version of node.

I managed to work round the problem by writing a shell script to copy the headers from /usr/include/node to ~/.node-gyp/6.14.3/include/node/

There is a shell script to do this here: https://gist.github.com/njh/189eccddaa5c05dda4608edc5301481f

Mousius commented 6 years ago

The way we get around this is to provide an environment variable to mock which node-gyp receives to do effectively the same thing as your shell script.

We run this as a shell script in our CI server to setup the environment config: echo "config_opts['environment']['npm_config_nodedir'] = '/usr'" >> /etc/mock/site-defaults.cfg

njh commented 6 years ago

Ahh! Thanks Chris!

npm-gyp is so cryptic. How is anyone supposed to know, based on the above error messages, that it is solved by setting npm_config_nodedir to /usr/. I wonder why it doesn't try looking in /usr anyway.

Mousius commented 6 years ago

I think a note in the README would be really helpful, as it's environment specific. It wouldn't necessarily effect everyone trying to build an RPM and you may have headers in different places so I don't want to setup speculate in a way which would break other people.

njh commented 5 years ago

This can be closed when #58 is merged