Source code for utilities.nodejs

"""
This module contains all necessary MC Objects for ``utilities.nodejs``.
"""

from pathlib import Path

from linux.ubuntu import UbuntuHost

from firewheel.control.experiment_graph import require_class


[docs] @require_class(UbuntuHost) class NodeJSVM: """ A decorator enabling Node.js functionality on a VM. """ _local_bin_dir = Path("/usr/local/bin") def __init__(self, node_version="18.13.0", symlink=False, offline_npm=True): """ Initialize and install Node.js on a VM. Issues the commands to install Node.js on a virtual machine with the given configuration. The Node.js binaries may be directly installed in the VM's ``/usr/local/bin`` directory, or dropped elsewhere and symlinked. By default, the VM attempts to set the active npm to operate in offline mode. Args: node_version (str, None): The version of Node.js to install on the VM. This must be a valid identifier in the form "Major.minor.patch" (e.g., 18.13.0) and correspond to an available VM resource compatible with this Ubuntu VM. If set to :py:data:`None`, Node will not be installed and the assumption will be made that Node already exists on the virtual machine. symlink (bool): A flag indicating whether to symbolically link the Node.js implementation or install it directly into the ``/usr/local/bin`` directory. This argument is ignored if ``node_version`` is :py:data:`None`. offline_npm (bool): A flag indicating whether to configure npm to run in offline mode. Since VMs in FIREWHEEL experiments typically have no internet access, this defaults to :py:data:`True`. """ self.node_version = node_version self.node_specifier = f"node-v{self.node_version}-linux-x64" self.node_archive = f"{self.node_specifier}.tar.xz" self.node_bin = None self.node_lib = None self.bash_node_prefix = None if self.node_version: self._install_node(symlink) if offline_npm: self._set_offline_npm()
[docs] def _install_node(self, symlink): # Install Node.js on the VM. if symlink: self._install_node_symlinked(Path("/opt")) else: self._install_node_path_update()
[docs] def _install_node_path_update(self): # Install Node by extracting the archive and updating paths self.node_bin = self._local_bin_dir / self.node_specifier / "bin" self.node_lib = self._local_bin_dir / self.node_specifier / "lib/node_modules" self._unpack_node(self._local_bin_dir) profiles = ( "/root/.profile /home/ubuntu/.profile /root/.bashrc /home/ubuntu/.bashrc" ) self.run_executable( -64, "bash", arguments=( f'-c \'echo "export PATH=$PATH:{self.node_bin}" | tee -a {profiles}&& ' f'echo "export NODE_PATH={self.node_lib}" | tee -a {profiles}\' ' ), vm_resource=False, ) self.bash_node_prefix = f"PATH=$PATH:{self.node_bin} NODE_PATH={self.node_lib}"
[docs] def _install_node_symlinked(self, node_dir): # Install Node by extracting the archive and adding symbolic links self._unpack_node(node_dir) node_bin_dir = node_dir / self.node_specifier / "bin" for exe in ("node", "npm", "npx"): exe_path = node_bin_dir / exe link_path = self._local_bin_dir / exe self.run_executable(-99, "ln", f"-sf {exe_path} {link_path}")
[docs] def _unpack_node(self, extract_dir): # Extract and unpack the Node.js archive on the VM self.unpack_tar( -100, self.node_archive, options="-xf", directory=extract_dir, vm_resource=True, )
[docs] def _set_offline_npm(self): # Set npm to run in offline mode self.run_executable(-50, "npm", arguments=["config", "offline", "true"])