如何在厨师中使用sudo for gem命令

时间:2014-02-14 15:12:39

标签: rubygems chef chef-recipe

我正在挑战厨师。我需要root用户的ruby和rubygems以及另一个用户'deploy'

安装ruby和rubygems并为root用户工作(在测试用例中为“vagrant”)。

我使用capistrano创建了一个用户,以便部署我的应用程序

user 'deploy' do
  password '$1$zOC.txvE$ex544C.YpxV.HqNh/2AKQ0'
  home "/home/deploy"
  supports :manage_home => true
  shell "/bin/bash"
end

然后我尝试更改此“部署”用户的宝石来源

execute 'change sources to our gem server' do
  command "gem sources -r http://rubygems.org/ && gem sources -a http://my.gem.server/"
  creates "~/.gemrc"
  user 'deploy'
  cwd "/home/deploy"
end

但是会收到此错误

[2014-02-14T14:38:27+00:00] ERROR: execute[change sources to our gem server] (beesor-cookbook::user line 13) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '1'       
---- Begin output of gem sources -r http://rubygems.org/ && gem sources -a http://my.gem.server/ ----       
STDOUT: source http://rubygems.org/ not present in cache       
STDERR: ERROR:  While executing gem ... (Errno::EACCES)       
    Permission denied - /home/vagrant/.gemrc       
---- End output of gem sources -r http://rubygems.org/ && gem sources -a http://my.gem.server/ ----       
Ran gem sources -r http://rubygems.org/ && gem sources -a http://my.gem.server/ returned 1 

1 个答案:

答案 0 :(得分:2)

这是使用execute资源的问题。您正在以非特权用户身份运行执行资源。但是,您希望关联文件仍由非特权用户拥有,对吧? Stephen建议的代码可以使用,但.gemrc将由root用户拥有。根据Rubygems如何读取它的gemrcs,它可能不喜欢该文件由不同的用户拥有。因此,您需要手动chownchmod execute命令中的文件,或者只使用模板。

如果您在计算机上本地运行该命令,您将看到生成的gemrc如下所示:

---
:sources:
- http://my.gem.server

我建议使用纯template资源:

template '/home/deploy/.gemrc' do
  source 'gemrc.erb'
  user 'deploy'
  group 'deploy'
  mode '0644'
  variables(source: 'http://my.gem.server')
end

然后是相关的erb:

---
:sources:
- <%= @source %>

这也可以扩展为支持多个源端点。此外,因为您正在使用幂等资源:

  • 您在Chef Client运行中获得了很好的差异输出

    你会在输出中看到一个git-style diff,这对调试非常有用

  • 您可以通知其他资源

    如果您需要在模板源更改后安装gem(例如),则可以安全地使用通知。这些通知仅在模板更改时触发:

template '/home/deploy/.gemrc' do
  # ...
  notifies :install, 'gem_package[foo]', :immediately
end

gem_package 'foo' do
  action :nothing
end