Newer
Older
# _____ _ _
# | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
# | __| _| -_| -_| . | . | | . | . | | -_|
# |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
#
# nodejs functions
#
# License
# =======
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# For reasons unknown we initially have to upgrade to an intermediate version
# before getting to the version we want
VARIANTS='mesh'
# change these versions at your peril. Things will often crash if you don't
# have specifically the correct versions
# This file keeps track of the apps needing nodejs
# so that it can be removed if tere are no apps which need it
NODEJS_INSTALLED_APPS_FILE=$HOME/.nodejs-apps
if [[ "$ARCHITECTURE" == 'arm'* ]]; then
if [[ "$ARCHITECTURE" == *"aarch"* ]]; then
if [[ "$ARCHITECTURE" == 'x86_64' || $ARCHITECTURE == 'amd64' ]]; then
function nodejs_fix_cpu_detection {
# fix for failing cpu detection during image build with qemu, see https://github.com/npm/npm/issues/19265
if [ -f "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js"
if [ -f "$rootdir/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js"
fi
if [ -f "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js"
fi
if [ -f "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js"
if [ -f "$rootdir/.npm-global/lib/node_modules/npm/node_modules/node-gyp/lib/build.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/.npm-global/lib/node_modules/npm/node_modules/node-gyp/lib/build.js"
fi
if [ -f "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js"
fi
#$mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g worker-farm@1.6.0 --save
function nodejs_setup_repo {
if [ -f "$rootdir/etc/apt/sources.list.d/nodesource.list" ]; then
return
echo $'Setting up nodejs debian repos'
# shellcheck disable=SC2086
$mesh_install_nodejs_prefix $INSTALL_PACKAGES wget curl g++ m4 libtool automake
# shellcheck disable=SC2086
$mesh_install_nodejs_prefix $INSTALL_PACKAGES libxext-dev libxtst-dev libxkbfile-dev
# shellcheck disable=SC2086
$mesh_install_nodejs_prefix $INSTALL_PACKAGES apt-transport-https
$mesh_install_nodejs_prefix wget https://deb.nodesource.com/gpgkey/nodesource.gpg.key -O /root/node.gpg.key
if [ ! -f "$rootdir/root/node.gpg.key" ]; then
echo $'Unable to obtain gpg key for nodejs repo'
NODE_UPGRADE=
exit 63
fi
$mesh_install_nodejs_prefix apt-key add /root/node.gpg.key
echo "deb https://deb.nodesource.com/node_8.x stretch main" > "$rootdir/etc/apt/sources.list.d/nodesource.list"
echo "deb-src https://deb.nodesource.com/node_8.x stretch main" >> "$rootdir/etc/apt/sources.list.d/nodesource.list"
echo $'nodejs repos added'
}
function nodejs_install_debian_package {
if [ $NODE_UPGRADE ]; then
return
echo $'Removing any previous nodejs installations'
# shellcheck disable=SC2086
$mesh_install_nodejs_prefix $PACKAGE_UNHOLD nodejs
# shellcheck disable=SC2086
$mesh_install_nodejs_prefix $UPDATE_PACKAGES
# shellcheck disable=SC2086
$mesh_install_nodejs_prefix $REMOVE_PACKAGES_PURGE nodejs
echo $'Removing any previous nodejs binaries and modules'
if [ -d "$rootdir/usr/local/lib/node_modules" ]; then
rm -rf "$rootdir/usr/local/lib/node_modules"
if [ -f "$rootdir/usr/local/bin/node" ]; then
rm "$rootdir/usr/local/bin/node"
fi
rm "$rootdir/usr/bin/node"
fi
if [ -f "$rootdir/usr/bin/nodejs" ]; then
rm "$rootdir/usr/bin/nodejs"
echo $'Installing nodejs from debian package'
# shellcheck disable=SC2086
$mesh_install_nodejs_prefix $INSTALL_PACKAGES nodejs
# shellcheck disable=SC2086
$mesh_install_nodejs_prefix $PACKAGE_HOLD nodejs
$mesh_install_nodejs_prefix npm config set unsafe-perm true
if [ $NODE_UPGRADE ]; then
echo $"Installing npm ${NPM_VERSION}"
npm install -g npm@${NPM_VERSION} --save
else
echo $"Installing npm ${NPM_VERSION} on ${NPM_ARCH}"
$mesh_install_nodejs_prefix npm install --arch=${NPM_ARCH} -g npm@${NPM_VERSION} --save
fi
# NOTE: trying to copy here breaks the build
#if [ -f "$rootdir/.npm-global/bin/npm" ]; then
# cp "$rootdir/.npm-global/bin/npm" "$rootdir/usr/local/bin/npm"
# cp "$rootdir/.npm-global/bin/npm" "$rootdir/usr/bin/npm"
#fi
cp "$rootdir/usr/bin/npm" "$rootdir/root/npm"
$mesh_install_nodejs_prefix ln -s /root/.npm-global/lib/node_modules /usr/local/bin/node_modules
}
function nodejs_install_npm_secondary {
if [ "$rootdir" ]; then
return
fi
# deliberate second install of npm
echo $"Installing npm ${NPM_VERSION}"
$mesh_install_nodejs_prefix npm install -g npm@${NPM_VERSION} --save
if [ -f "$rootdir/root/.npm-global/lib/node_modules/npm/bin/npm" ]; then
cp "$rootdir/root/.npm-global/lib/node_modules/npm/bin/npm" "$rootdir/usr/local/bin/npm"
cp "$rootdir/root/.npm-global/lib/node_modules/npm/bin/npm" "$rootdir/usr/bin/npm"
fi
if [ -f "$rootdir/usr/local/bin/npm" ]; then
cp "$rootdir/usr/local/bin/npm" "$rootdir/usr/bin/npm"
fi
cp "$rootdir/usr/bin/npm" "$rootdir/root/npm"
}
# update from the old debian nodejs version
echo $"Installing n ${NODEJS_N_VERSION} on ${NPM_ARCH}"
}
function nodejs_install_from_n {
# Don't do this if we're building an image,
# because cpu detection faults occur.
# This condition may no longer be needed in future once the bug is fixed
if [ "$rootdir" ]; then
return
echo $"Installing nodejs ${NODEJS_VERSION} via n"
if [ -f "$rootdir/usr/local/bin/node" ]; then
cp "$rootdir/usr/local/bin/node" "$rootdir/usr/bin/node"
fi
cp "$rootdir/root/npm" "$rootdir/usr/bin/npm"
cp "$rootdir/root/npm" "$rootdir/usr/local/bin/npm"
}
function nodejs_check_versions {
if [ "$rootdir" ]; then
return
echo $'Checking that correct nodejs and npm versions were installed'
# check the version numbers
cat <<EOF > "$rootdir/usr/bin/test_nodejs_install"
#!/bin/bash
node_version=\$(node -v)
if [[ "\$node_version" != "v${NODEJS_VERSION}" ]]; then
echo $"nodejs version expected to be ${NODEJS_VERSION} but found \$node_version"
exit 1
fi
npm_version=\$(npm -v)
echo $"npm version expected to be ${NPM_VERSION} but found \$npm_version"
exit 2
fi
EOF
chmod +x "$rootdir/usr/bin/test_nodejs_install"
echo $"nodejs version numbers did not match. Architecture is $NPM_ARCH."
NODE_UPGRADE=
exit 76
fi
rm "$rootdir/usr/bin/test_nodejs_install"
}
function nodejs_check_install_succeeded {
# rename node command, so there isn't confusion between 'node' and 'nodejs'
if [ -f "$rootdir/usr/bin/nodejs" ]; then
cp "$rootdir/usr/bin/nodejs" "$rootdir/usr/bin/node"
fi
if [ -f "$rootdir/usr/bin/node" ]; then
cp "$rootdir/usr/bin/node" "$rootdir/usr/local/bin/node"
fi
# Check that the node command exists
if [ ! -f "${rootdir}/usr/bin/node" ]; then
if [ ! -f "${rootdir}/usr/local/bin/node" ]; then
if [ ! -f "${rootdir}/usr/bin/nodejs" ]; then
echo $'nodejs was not installed'
NODE_UPGRADE=
exit 63
fi
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
if [ ! -f "$rootdir/usr/bin/node" ]; then
echo $'/usr/bin/node not found'
NODE_UPGRADE=
exit 72
fi
}
function mesh_install_nodejs {
mesh_install_nodejs_prefix=
if [ "$rootdir" ]; then
mesh_install_nodejs_prefix="chroot $rootdir"
fi
nodejs_setup_repo
nodejs_install_debian_package
nodejs_check_install_succeeded
nodejs_install_npm
nodejs_install_n
nodejs_install_from_n
nodejs_install_npm_secondary
if [ -f "$rootdir/usr/bin/node" ]; then
cp "$rootdir/usr/bin/node" "$rootdir/usr/local/bin/node"
fi
nodejs_check_versions
NODE_UPGRADE=
function nodejs_upgrade {
if [ ! -f /etc/apt/sources.list.d/nodesource.list ]; then
return
fi
nodejs_setup_global_modules
if grep -q "node_8.x" /etc/apt/sources.list.d/nodesource.list; then
CURR_NODE_VERSION=$(node --version)
if [[ "$CURR_NODE_VERSION" == "v${NODEJS_VERSION}" ]]; then
return
fi
fi
fi
if [ -f /usr/local/bin/node ]; then
CURR_NODE_VERSION=$(node --version)
if [[ "$CURR_NODE_VERSION" == "v${NODEJS_VERSION}" ]]; then
return
fi
NODE_UPGRADE=1
function mesh_setup_npm {
cat <<EOF > "$rootdir/usr/bin/install_npm_global"
#!/bin/bash
if [ ! -d ~/.npm-global ]; then
mkdir ~/.npm-global
fi
npm config set prefix '~/.npm-global'
if [[ "$PATH" != *'~/.npm-global/bin'* ]]; then
export PATH=~/.npm-global/bin:$PATH
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
fi
export NPM_CONFIG_PREFIX=~/.npm-global
echo 'export NPM_CONFIG_PREFIX=~/.npm-global' >> ~/.bashrc
source ~/.profile
EOF
chroot "$rootdir" /bin/chmod +x /usr/bin/install_npm_global
chroot "$rootdir" /usr/bin/install_npm_global
rm "$rootdir/usr/bin/install_npm_global"
}
function nodejs_setup_global_modules {
return
fi
if [ ! -d "$rootdir/root/.npm-global" ]; then
mkdir "$rootdir/root/.npm-global"
$mesh_install_nodejs_prefix npm config set prefix '/root/.npm-global'
if ! grep -q "PATH=/root/.npm-global/bin" "$rootdir/root/.bashrc"; then
echo "PATH=/root/.npm-global/bin:\$PATH" >> "$rootdir/root/.bashrc"
if ! grep -q "NPM_CONFIG_PREFIX=" "$rootdir/root/.bashrc"; then
echo "export NPM_CONFIG_PREFIX=/root/.npm-global" >> "$rootdir/root/.bashrc"
fi
if [ ! "$rootdir" ]; then
$mesh_install_nodejs_prefix export PATH=/root/.npm-global/bin:$PATH
$mesh_install_nodejs_prefix export NPM_CONFIG_PREFIX=/root/.npm-global
fi
if [ ! -f "$NODEJS_INSTALLED_APPS_FILE" ]; then
sed -i "/install_${1}/d" "$NODEJS_INSTALLED_APPS_FILE"
if ! grep -q "install_" "$NODEJS_INSTALLED_APPS_FILE"; then
if [ -f /usr/bin/nodejs ]; then
rm /usr/bin/nodejs
fi
if [ -f /usr/local/bin/node ]; then
rm /usr/local/bin/node
fi
if [ -f /usr/bin/node ]; then
rm /usr/bin/node
fi
if [ -d /usr/lib/node_modules ]; then
rm -rf /usr/lib/node_modules
fi
$PACKAGE_HOLD nodejs
CURR_NODE_VERSION=$(node --version)
CURR_NPM_VERSION=$(npm --version)
CURR_N_VERSION=$(n --version)
if [[ "$CURR_NPM_VERSION" != "$NPM_VERSION" ]]; then
fi
if [[ "$CURR_N_VERSION" != "$NODEJS_N_VERSION" ]]; then
npm upgrade -g n@${NODEJS_N_VERSION} --save
fi
if [ -f /usr/local/bin/npm ]; then
cp /usr/local/bin/npm /usr/bin/npm
fi
if [ -f /usr/local/bin/node ]; then
cp /usr/local/bin/node /usr/bin/nodejs
cp /usr/local/bin/node /usr/bin/node
fi
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
upgrade_nodejs
return
fi
CURR_NODE_VERSION=$(node --version)
CURR_NPM_VERSION=$(npm --version)
CURR_N_VERSION=$(n --version)
if [[ "$CURR_NPM_VERSION" != "$NPM_VERSION" ]]; then
echo $"Expected npm version $NPM_VERSION but actually have $CURR_NPM_VERSION"
fi
if [[ "$CURR_N_VERSION" != "$NODEJS_N_VERSION" ]]; then
echo $"Expected n version $NODEJS_N_VERSION but actually have $CURR_N_VERSION"
fi
if [[ "$CURR_NODE_VERSION" != "v${NODEJS_VERSION}" ]]; then
echo $"Expected node version $NODEJS_VERSION but actually have $CURR_NODE_VERSION"
if [ "$1" ]; then
if ! grep -q "install_${1}" "$NODEJS_INSTALLED_APPS_FILE"; then
echo "install_${1}" >> "$NODEJS_INSTALLED_APPS_FILE"
}
# NOTE: deliberately there is no "exit 0"