我正在寻找一种通过 ansible 和 nvm 安装给定版本的节点的方法,nvm 的安装按预期工作,因为如果我与 root 用户连接,我可以执行命令 nvm install 8.11.3 但这是一样的命令不适用于 Ansible,我不明白为什么。
---
- name: Install nvm
git: repo=https://github.com/creationix/nvm.git dest=~/.nvm version=v0.33.11
tags: nvm
- name: Source nvm in ~/.{{ item }}
lineinfile: >
dest=~/.{{ item }}
line="source ~/.nvm/nvm.sh"
create=yes
tags: nvm
with_items:
- bashrc
- profile
- name: Install node and set version
become: yes
become_user: root
shell: nvm install 8.11.3
...
错误日志
TASK [node : Install node and set version] *************************************************************************************
fatal: [51.15.128.164]: FAILED! => {"changed": true, "cmd": "nvm install 8.11.3", "delta": "0:00:00.005883", "end": "2018-12-03 15:05:10.394433", "msg": "non-zero return code", "rc": 127, "start": "2018-12-03 15:05:10.388550", "stderr": "/bin/sh: 1: nvm: not found", "stderr_lines": ["/bin/sh: 1: nvm: not found"], "stdout": "", "stdout_lines": []}
to retry, use: --limit .../.../ansible/stater-debian/playbook.retry
没关系,这是有效的配置
- name: Install node and set version
become: yes
become_user: root
shell: "source /root/.nvm/nvm.sh && nvm install 8.11.3"
args:
executable: /bin/bash
我认为您需要的输出中的线索是:
“/bin/sh:1:nvm:未找到”
要运行命令而不包含该命令的完整路径(即
nvm
而不是 /the/dir/nvm/is/installed/in/nvm
),则包含该命令的目录必须位于运行该命令的 shell 的 $PATH 环境变量中。
在这种情况下,Ansible 生成的 shell 与您运行交互式命令的 shell 相比似乎不存在。更改:
- name: Install node and set version
become: yes
become_user: root
shell: nvm install 8.11.3
到
- name: Install node and set version
become: yes
become_user: root
shell: /full/path/to/nvm install 8.11.3
如果您不知道用什么来代替“/full/path/to”,请尝试:
which nvm
或
find / -name nvm
我只会在这里发帖,因为这样的帖子有数百个。
- name: Install node
become: true
become_user: root
shell: "source /root/.nvm/nvm.sh && nvm install {{ personal_node_version }} && nvm alias default {{ personal_node_version }}"
args:
executable: /bin/bash
为我工作。
这对我在 Ubuntu 20.04 上使用 nvm 版本 0.39.1 有效:
- name: Install NVM
shell: >
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
args:
creates: "/root/.nvm/nvm.sh"
- name: Install Node Versions
shell: ". /root/.bashrc && nvm install {{item}}"
with_items:
- 'v10.24.1'
- 'v16.17.0'
- '--lts'
- 'node'
基于堆栈上找到的所有帖子,并根据我自己的需要进行了一些调整 - 我发现这个解决方案非常适合安装 NVM(简单的部分)和创建一个循环,允许您根据需要插入 1 个或多个版本的 Node
# test if nvm has been installed by the user desired
- stat:
path: /home/yournonrootuser/.nvm
register: nvm_path
- name: Setup NodeVersionManager and install node version
become: yes
# Execute config files such as .profile (Ansible uses non-interactive login shells)
become_flags: -i
become_user: yournonrootuser
block:
- name: Install nvm
shell: >
curl -o- https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
args:
executable: /bin/bash
chdir: "$HOME"
creates: "$HOME/.nvm/nvm.sh"
- name: Setup .profile of yournonrootuser
lineinfile:
path: ~/.profile
# This will make sure Node is on the users PATH
line: source ~/.nvm/nvm.sh
create: yes
become_flags: -i
when: nvm_path.stat.exists == false
# if we got here we already know node version manager is installed
- name: installing node versions using loop
command: sudo -iu yournonrootuser nvm install {{item}}
args:
executable: /bin/bash
chdir: "$HOME"
creates: "$HOME/.nvm/versions/node/v{{item}}"
loop:
- 14.18.3
NodeSource 在 Nodejs 企业发行版方面似乎做得相当不错。我的目标是在 Debian 机器上拥有一个独立的节点版本,无论我是否升级 Debian,该版本都将被锁定主版本。
n
或 nvm
非常适合开发,但为什么我要安装额外的软件包,安装后我再也不会碰这些软件包了?
我宁愿立即部署我需要的节点版本,而且只部署它,而不部署其他任何东西。这是 Debian 上的 Nodejs 18 的示例:
- setup: # gather facts
- name: Upgrade via OS package manager
package: upgrade=full update_cache=yes
- stat: path=/etc/apt/sources.list.d/nodesource.list get_checksum=yes
register: stat_nodesource_list_before
- name: Ensure nodesource repository (Debian)
shell: curl -sL https://deb.nodesource.com/setup_18.x | bash -
when: ansible_facts['os_family'] == "Debian"
changed_when: False
- stat: path=/etc/apt/sources.list.d/nodesource.list get_checksum=yes
register: stat_nodesource_list_after
- debug: msg='nodesource.list has been refreshed'
changed_when: "stat_nodesource_list_before.stat.checksum != stat_nodesource_list_after.stat.checksum"
- name: Ensure dependencies (Debian)
package:
name:
- nodejs
when: ansible_facts['os_family'] == "Debian"
register: package_debian
- fail: msg='Unsupported OS'
when: "package_debian is skipped"
NodeSource 的脚本将始终从
tee
到 nodesource.list
,因此我添加了一些校验和检查,以便有办法告诉文件已更改。该示例已准备好扩展到更多发行版。