Files
ansiblings/packages/nopy-cubes-core/cubes/runtime/nodevm/deploy.py
T

94 lines
3.2 KiB
Python

from pyinfra.operations import server, apt
from pyinfra import host
from pyinfra.facts.server import Which
from pyinfra.api.exceptions import DeployError
VERSION = host.data.VERSION
ALIAS = host.data.ALIAS
GLOBAL_PACKAGES = host.data.GLOBAL_PACKAGES
USER = host.data.USER
SHELL = host.data.SHELL
INSTALL_NVM = "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash"
# Under bash, every entry in `commands` is its own shell, so loading nvm and
# using it have to be one entry. Loading cannot be skipped either: nvm's
# installer appends its hook to ~/.bashrc, and Ubuntu's ~/.bashrc returns at
# line 1 for a non-interactive shell, so under `su -c` the hook never runs.
LOAD_NVM = 'export NVM_DIR="$HOME/.nvm"; . "$NVM_DIR/nvm.sh"'
# The binary only. Oh My Fish is a set of fish functions with no binary and no
# fixed path, so probing for it would be guesswork — and if fish is there while
# omf is not, `omf install nvm` says so itself. Half a guard that is certain
# beats a whole one that is not.
if SHELL == 'fish' and not host.get_fact(Which, 'fish'):
raise DeployError(
f'runtime:nodevm: SHELL is "fish" but fish is not installed for {USER}. '
'Run user:add first, or set SHELL=bash.'
)
if SHELL == 'fish':
shell_executable = '/usr/bin/fish'
# The omf plugin defines `nvm` as a fish function that every login shell
# loads, and activates the `default` alias on load — so `nvm` and `npm` are
# both reachable in any later shell without setup, and NVM_DIR is set for us.
nvm_commands = [
INSTALL_NVM,
'omf install nvm',
f'nvm install {VERSION}',
f'nvm alias {ALIAS} {VERSION}',
]
npm_commands = [f'npm install -g {GLOBAL_PACKAGES}']
else:
shell_executable = '/bin/bash'
nvm_commands = [
INSTALL_NVM,
f'{LOAD_NVM}; nvm install {VERSION}; nvm alias {ALIAS} {VERSION}',
]
npm_commands = [f'{LOAD_NVM}; nvm use {ALIAS}; npm install -g {GLOBAL_PACKAGES}']
apt.packages(
name=f'Install nodejs tools',
no_recommends=True,
packages=[
'build-essential',
'libssl-dev',
'libtool',
'cmake',
'libcairo2-dev',
'libpango1.0-de',
'libpng-dev',
'libgif-dev',
'libjpeg-dev',
'libvips-dev',
'librsvg2-dev',
'libpixman-1-dev',
],
# Every other cube that installs packages refreshes the index first, and
# this one only got away without it while `user:add` ran ahead of it and
# dragged in `apt:essentials`. On a box nobody has updated, the index
# names .deb versions the mirror has already superseded and the fetch
# 404s — the same "assumes a predecessor cube ran" defect as the shell.
update=True,
_sudo = True,
)
server.shell(
name=f'Install nvm and node {VERSION} for {USER}',
commands=nvm_commands,
_sudo=True,
_su_user=USER,
_use_su_login=True,
_shell_executable=shell_executable,
)
server.shell(
name=f'Install global packages for {USER}',
commands=npm_commands,
_sudo=True,
_su_user=USER,
_use_su_login=True,
_shell_executable=shell_executable,
)