如何让 Chef 客户端使用与 NVM 一起安装的用户特定的 nodejs 版本?
How to make Chef client use user specific nodejs version installed with NVM?
我使用 nvm cookbook 来安装 nvm 和 4.3.1 版本 Node.js。
include_recipe 'nvm'
nvm_install node['analyzer_agent']['nodejs']['version'] do
user node['analyzer_agent']['user']['name']
group node['analyzer_agent']['user']['group']
from_source false
alias_as_default true
action :create
end
当我通过 SSH 与用户(在本例中为 analyzer_agent)连接到服务器时,一切都按预期进行。我的默认 nodej.js 版本是 4.3.1,当我手动尝试使用 npm install pm2 -g
安装 pm2 时,它运行良好。
但是,当我尝试从我的配方全局安装 pm2 模块时:
execute "Install PM2" do
cwd "/home/#{node['analyzer_agent']['user']['name']}"
user node['analyzer_agent']['user']['name']
group node['analyzer_agent']['group']
environment "HOME"=> "/home/#{node['analyzer_agent']['user']['name']}", "USER"=>node['analyzer_agent']['user']['name']
command "npm install pm2 -g"
not_if { File.exists?("pm2") }
end
我收到以下错误:
================================================================================
Error executing action `run` on resource 'execute[Install PM2]'
================================================================================
Mixlib::ShellOut::ShellCommandFailed
------------------------------------
Expected process to exit with [0], but received '243'
---- Begin output of npm install pm2 -g ----
STDOUT:
STDERR: npm ERR! tar.unpack untar error /home/analyzer_agent/.npm/pm2/1.0.2/package.tgz
npm ERR! Linux 3.13.0-79-generic
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "pm2" "-g"
npm ERR! node v0.12.5
npm ERR! npm v2.11.2
npm ERR! path /usr/local/lib/node_modules/pm2
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! Error: EACCES, mkdir '/usr/local/lib/node_modules/pm2'
npm ERR! at Error (native)
npm ERR! { [Error: EACCES, mkdir '/usr/local/lib/node_modules/pm2']
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! path: '/usr/local/lib/node_modules/pm2',
npm ERR! fstream_type: 'Directory',
npm ERR! fstream_path: '/usr/local/lib/node_modules/pm2',
npm ERR! fstream_class: 'DirWriter',
npm ERR! fstream_stack:
npm ERR! [ '/usr/local/lib/node_modules/npm/node_modules/fstream/lib/dir-writer.js:35:25',
npm ERR! '/usr/local/lib/node_modules/npm/node_modules/mkdirp/index.js:47:53',
npm ERR! 'FSReqWrap.oncomplete (fs.js:95:15)' ] }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
npm ERR! Please include the following file with any support request:
npm ERR! /home/analyzer_agent/npm-debug.log
---- End output of npm install pm2 -g ----
Ran npm install pm2 -g returned 243
Resource Declaration:
---------------------
# In /var/chef/runs/f3450c3b-d2cc-4f04-a504-436cee5c488b/local-mode-cache/cache/cookbooks/analyzer_agent/recipes/nvm_nodejs.rb
13: execute "Install PM2" do
14: cwd "/home/#{node['analyzer_agent']['user']['name']}"
15: user node['analyzer_agent']['user']['name']
16: group node['analyzer_agent']['group']
17: environment "HOME"=> "/home/#{node['analyzer_agent']['user']['name']}", "USER"=>node['analyzer_agent']['user']['name']
18: command "npm install pm2 -g"
19: not_if { File.exists?("pm2") }
20: end
Compiled Resource:
------------------
# Declared in /var/chef/runs/f3450c3b-d2cc-4f04-a504-436cee5c488b/local-mode-cache/cache/cookbooks/analyzer_agent/recipes/nvm_nodejs.rb:13:in `from_file'
execute("Install PM2") do
action [:run]
retries 0
retry_delay 2
default_guard_interpreter :execute
command "npm install pm2 -g"
backup 5
cwd "/home/analyzer_agent"
environment {"HOME"=>"/home/analyzer_agent", "USER"=>"analyzer_agent"}
returns 0
user "analyzer_agent"
declared_type :execute
cookbook_name "analyzer_agent"
recipe_name "nvm_nodejs"
not_if { #code block }
end
据我所知,在 execute
中使用 environment
设置 HOME 和 USER 应该可以解决问题。但我没有任何机会。 Chef 客户端仅使用已编译的 nodejs。不是nvm安装的那个。
可能出了什么问题?
(顺便说一句,在同一台服务器上但与另一个用户一起,我从源代码编译了 node.js 并全局安装了 pm2。我认为它可能与我的问题有关,但是,如果它是这样的,为什么我在新用户帐户中手动安装 pm2 时它不会造成任何伤害?)
npm install -g
是全局安装,这意味着您需要权限才能写入安装了 Node/NPM 的全局文件夹(在本例中为 /usr/local/bin
)。您可能不想使用 -g
,因为它仅适用于人类,不适用于工具。
我相信在 OpsWorks 中,您还可以通过在应用的说明书中创建一个新文件来覆盖安装的 Node 版本:attributes/customize.rb
。那么:
normal[:opsworks_nodejs][:version] = '4.4.0'
这应该下载正确版本的节点,而不是使用节点 0.10...因此内置的 OpsWorks 应用程序 runner/monitor (monit) 应该可以工作,而不必安装 PM2。
我使用 nvm cookbook 来安装 nvm 和 4.3.1 版本 Node.js。
include_recipe 'nvm'
nvm_install node['analyzer_agent']['nodejs']['version'] do
user node['analyzer_agent']['user']['name']
group node['analyzer_agent']['user']['group']
from_source false
alias_as_default true
action :create
end
当我通过 SSH 与用户(在本例中为 analyzer_agent)连接到服务器时,一切都按预期进行。我的默认 nodej.js 版本是 4.3.1,当我手动尝试使用 npm install pm2 -g
安装 pm2 时,它运行良好。
但是,当我尝试从我的配方全局安装 pm2 模块时:
execute "Install PM2" do
cwd "/home/#{node['analyzer_agent']['user']['name']}"
user node['analyzer_agent']['user']['name']
group node['analyzer_agent']['group']
environment "HOME"=> "/home/#{node['analyzer_agent']['user']['name']}", "USER"=>node['analyzer_agent']['user']['name']
command "npm install pm2 -g"
not_if { File.exists?("pm2") }
end
我收到以下错误:
================================================================================
Error executing action `run` on resource 'execute[Install PM2]'
================================================================================
Mixlib::ShellOut::ShellCommandFailed
------------------------------------
Expected process to exit with [0], but received '243'
---- Begin output of npm install pm2 -g ----
STDOUT:
STDERR: npm ERR! tar.unpack untar error /home/analyzer_agent/.npm/pm2/1.0.2/package.tgz
npm ERR! Linux 3.13.0-79-generic
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "pm2" "-g"
npm ERR! node v0.12.5
npm ERR! npm v2.11.2
npm ERR! path /usr/local/lib/node_modules/pm2
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! Error: EACCES, mkdir '/usr/local/lib/node_modules/pm2'
npm ERR! at Error (native)
npm ERR! { [Error: EACCES, mkdir '/usr/local/lib/node_modules/pm2']
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! path: '/usr/local/lib/node_modules/pm2',
npm ERR! fstream_type: 'Directory',
npm ERR! fstream_path: '/usr/local/lib/node_modules/pm2',
npm ERR! fstream_class: 'DirWriter',
npm ERR! fstream_stack:
npm ERR! [ '/usr/local/lib/node_modules/npm/node_modules/fstream/lib/dir-writer.js:35:25',
npm ERR! '/usr/local/lib/node_modules/npm/node_modules/mkdirp/index.js:47:53',
npm ERR! 'FSReqWrap.oncomplete (fs.js:95:15)' ] }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
npm ERR! Please include the following file with any support request:
npm ERR! /home/analyzer_agent/npm-debug.log
---- End output of npm install pm2 -g ----
Ran npm install pm2 -g returned 243
Resource Declaration:
---------------------
# In /var/chef/runs/f3450c3b-d2cc-4f04-a504-436cee5c488b/local-mode-cache/cache/cookbooks/analyzer_agent/recipes/nvm_nodejs.rb
13: execute "Install PM2" do
14: cwd "/home/#{node['analyzer_agent']['user']['name']}"
15: user node['analyzer_agent']['user']['name']
16: group node['analyzer_agent']['group']
17: environment "HOME"=> "/home/#{node['analyzer_agent']['user']['name']}", "USER"=>node['analyzer_agent']['user']['name']
18: command "npm install pm2 -g"
19: not_if { File.exists?("pm2") }
20: end
Compiled Resource:
------------------
# Declared in /var/chef/runs/f3450c3b-d2cc-4f04-a504-436cee5c488b/local-mode-cache/cache/cookbooks/analyzer_agent/recipes/nvm_nodejs.rb:13:in `from_file'
execute("Install PM2") do
action [:run]
retries 0
retry_delay 2
default_guard_interpreter :execute
command "npm install pm2 -g"
backup 5
cwd "/home/analyzer_agent"
environment {"HOME"=>"/home/analyzer_agent", "USER"=>"analyzer_agent"}
returns 0
user "analyzer_agent"
declared_type :execute
cookbook_name "analyzer_agent"
recipe_name "nvm_nodejs"
not_if { #code block }
end
据我所知,在 execute
中使用 environment
设置 HOME 和 USER 应该可以解决问题。但我没有任何机会。 Chef 客户端仅使用已编译的 nodejs。不是nvm安装的那个。
可能出了什么问题?
(顺便说一句,在同一台服务器上但与另一个用户一起,我从源代码编译了 node.js 并全局安装了 pm2。我认为它可能与我的问题有关,但是,如果它是这样的,为什么我在新用户帐户中手动安装 pm2 时它不会造成任何伤害?)
npm install -g
是全局安装,这意味着您需要权限才能写入安装了 Node/NPM 的全局文件夹(在本例中为 /usr/local/bin
)。您可能不想使用 -g
,因为它仅适用于人类,不适用于工具。
我相信在 OpsWorks 中,您还可以通过在应用的说明书中创建一个新文件来覆盖安装的 Node 版本:attributes/customize.rb
。那么:
normal[:opsworks_nodejs][:version] = '4.4.0'
这应该下载正确版本的节点,而不是使用节点 0.10...因此内置的 OpsWorks 应用程序 runner/monitor (monit) 应该可以工作,而不必安装 PM2。