I believe the following elements in combination may be responsible for triggering a kind of fork bomb on our CI server, in which processes running phantomjs --version were spawned until all memory was consumed and the server crashed. See attached screenshot:
Here's some snippets from our Dockerfile which set up an environment to trigger the issue:
FROM ubuntu:14.04
ENV PHANTOM_JS="phantomjs-2.1.1-linux-x86_64"
RUN wget https://github.com/Medium/phantomjs/releases/download/v2.1.1/$PHANTOM_JS.tar.bz2 \
&& tar xvjf $PHANTOM_JS.tar.bz2 \
&& mv $PHANTOM_JS /usr/local/share \
&& ln -sf /usr/local/share/$PHANTOM_JS/bin/phantomjs /usr/local/bin
ENV NODE_VERSION 4.2.6
RUN wget "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& wget "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
RUN gpg --homedir /root --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
&& grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c -
RUN tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \
&& rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs;
ENV YARN_VERSION 0.24.5
ENV PHANTOM_VERSION 2.1.13
# These installs happen as root, but use /home/jenkins/.yarn to avoid permissions problem
# with storing files under /root, which is not only accessible by root.
# Ref: https://github.com/yarnpkg/yarn/issues/1194#issuecomment-261379289
ENV HOME /home/jenkins
RUN npm install yarn@$YARN_VERSION --global \
&& yarn global add node-gyp phantomjs-prebuilt@$PHANTOM_VERSION
In that environment yarn install --force for project would trigger the issue. I presume the key part was the presence of phantom-render-stream in our package.json, which in turn depends on phantomjs-prebuilt.
From reviewing the output of yarn install --force --verbose, the problem doesn't seem to block the installation, but continues to run wild in the background like a bull in a china shop.
Background
At first, we weren't pre-installing /usr/local/bin/phantomjs manually, but we using yarn global add phantomjs-prebuilt. However, we found this didn't install it in the "global" place that we wanted. Rather, it put the binary into /home/jenkins/.yarn-config. This broke things when we rsync'ed the project the production servers which expected a working reference to /usr/local/bin.
That's when we added the step to manually install phantomjs into /usr/local/bin, which added the final piece to trigger the issue. Our solution was to remove the yarn global add phantomjs-prebuilt step, which wasn't needed anymore.
That screenshot again
Let's look at that screenshot again. There's some interesting stuff in there:
First, see the issue definitely originates in install.js.
Also note that every call to phantomjs --version is not the same. The third one starts with /usr/bin/env, the others do not. (Why?).
We also see that these processes seem to never exit. The number only goes up until the server crashes.
Finally, we also see an infinite-depth of child processes attemped to be created but also a stream of sibling processes being created as well.
Conclusions?
Don't use yarn global add phantomjs-prebuilt.
I took a peek at the source code, and nothing jumped out at me right away.
Maybe there are some kew calls that need a .fin call to clean up some resources?
Maybe there are potential bad interactions when phantomjs-prebuilt is installed both globally and locally?
Maybe yarn's method of "global" package installation plays a role?
I'm not sure what's reasonable to be done about this, the case seemed "interesting" so I thought I would report it.
Fun times.
I believe the following elements in combination may be responsible for triggering a kind of fork bomb on our CI server, in which processes running
phantomjs --version
were spawned until all memory was consumed and the server crashed. See attached screenshot:Here's some snippets from our Dockerfile which set up an environment to trigger the issue:
In that environment
yarn install --force
for project would trigger the issue. I presume the key part was the presence ofphantom-render-stream
in our package.json, which in turn depends onphantomjs-prebuilt
.From reviewing the output of
yarn install --force --verbose
, the problem doesn't seem to block the installation, but continues to run wild in the background like a bull in a china shop.Background
At first, we weren't pre-installing /usr/local/bin/phantomjs manually, but we using
yarn global add phantomjs-prebuilt
. However, we found this didn't install it in the "global" place that we wanted. Rather, it put the binary into/home/jenkins/.yarn-config
. This broke things when we rsync'ed the project the production servers which expected a working reference to/usr/local/bin
.That's when we added the step to manually install
phantomjs
into/usr/local/bin
, which added the final piece to trigger the issue. Our solution was to remove theyarn global add phantomjs-prebuilt
step, which wasn't needed anymore.That screenshot again
Let's look at that screenshot again. There's some interesting stuff in there:
First, see the issue definitely originates in
install.js
. Also note that every call tophantomjs --version
is not the same. The third one starts with/usr/bin/env
, the others do not. (Why?). We also see that these processes seem to never exit. The number only goes up until the server crashes. Finally, we also see an infinite-depth of child processes attemped to be created but also a stream of sibling processes being created as well.Conclusions?
Don't use
yarn global add phantomjs-prebuilt
.I took a peek at the source code, and nothing jumped out at me right away.
Maybe there are some
kew
calls that need a.fin
call to clean up some resources?Maybe there are potential bad interactions when
phantomjs-prebuilt
is installed both globally and locally?Maybe yarn's method of "global" package installation plays a role?
I'm not sure what's reasonable to be done about this, the case seemed "interesting" so I thought I would report it.