Apa cara yang benar untuk mengulang resep Chef (solo)?


8

Bisakah seseorang tolong jelaskan bagaimana cara kerja chef? Itu adalah pertanyaan yang cukup luas, jadi untuk mempersempitnya saya punya resep yang sangat sederhana ini yang melingkupi daftar pengguna dan membuat masing-masing jika mereka belum ada. Tidak bekerja.

Dari apa yang saya tahu loop tampaknya terjadi seperti yang saya harapkan. Setelah loop telah menyelesaikan perintah bash saya untuk membuat setiap pengguna dieksekusi, satu kali untuk setiap iterasi dalam loop. Namun, ketika perintah bash dieksekusi mereka hanya tampaknya memiliki nilai pengguna dari iterasi loop pertama.

Apa cara yang benar untuk menulis resep yang mengulang data variabel yang mirip dengan contoh ini?

Ini resepnya:

node[:users].each do |user|
  puts "in loop for #{user['username']}"
  bash "create_user" do
    user "root"
    code do
      puts "running 'useradd' for #{user['username']}"
      "useradd #{user['username']}"
    end
    not_if do
      puts "checking /etc/passwd for #{user['username']}"
      "cat /etc/passwd | grep #{user['username']}"
    end
  end
end

Saya menguji ini menggunakan Vagrant dengan pengaturan berikut:

Vagrant::Config.run do |config|
  config.vm.box = "precise32"
  config.vm.box_url = "http://files.vagrantup.com/precise32.box"
  config.vm.provision :chef_solo do |chef|
    chef.add_recipe "sample"
    chef.json = {
      :users => [
        {:username => 'testA'},
        {:username => 'testB'},
        {:username => 'testC'},
        {:username => 'testD'},
        {:username => 'testE'},
      ],
    }
  end
end

Pesan-pesan yang dihasilkan oleh pernyataan menempatkan dalam resep terlihat seperti ini:

2013-03-08T01:03:46+00:00] INFO: Start handlers complete.
in loop for testA

in loop for testB

in loop for testC

in loop for testD

in loop for testE

[2013-03-08T01:03:46+00:00] INFO: Processing bash[create_user] action run (sample::default line 5)
checking /etc/passwd for testA

[2013-03-08T01:03:46+00:00] INFO: Processing bash[create_user] action run (sample::default line 5)
checking /etc/passwd for testA

[2013-03-08T01:03:46+00:00] INFO: Processing bash[create_user] action run (sample::default line 5)
checking /etc/passwd for testA

[2013-03-08T01:03:46+00:00] INFO: Processing bash[create_user] action run (sample::default line 5)
checking /etc/passwd for testA

[2013-03-08T01:03:46+00:00] INFO: Processing bash[create_user] action run (sample::default line 5)
checking /etc/passwd for testA

[2013-03-08T01:03:46+00:00] INFO: Chef Run complete in 0.026071 seconds

Jawaban:


5

buat nama skrip Anda unik ...

bash "create_user_#{user}" do

FWIW, saya telah menggunakan https://github.com/fnichol/chef-user beberapa kali yang memungkinkan Anda membuat / menghapus pengguna berdasarkan atribut dan databags.


Itu tampak sangat sederhana, terima kasih! Resep pengguna yang dibuat hanyalah sebuah contoh yang saya gunakan untuk memahami mengapa loop saya tidak bekerja di resep lain. Terima kasih lagi!
Matthew J Morrison

10

Perilaku yang Anda lihat dapat dijelaskan dengan memahami perbedaan antara dua tahap kunci dalam menjalankan klien Chef: kompilasi, dan konvergensi.

Selama fase "kompilasi", klien Chef menjalankan kode dalam resep Anda untuk membangun koleksi sumber daya . Ini adalah daftar Sumber Daya yang telah Anda katakan kepada Chef untuk dikelola di sistem Anda, bersama dengan status target mereka. Misalnya, sumber daya Direktori untuk mengatakan bahwa /tmp/fooharus ada, dan dimiliki oleh root:

directory "/tmp/foo" do
  owner "root"
end

Selama fase "konvergen", klien Chef menggunakan penyedia untuk memuat status saat ini dari setiap sumber daya, lalu membandingkannya dengan status target. Jika berbeda, Chef akan memperbarui sistem. Untuk sumber daya Direktori kami, Chef akan membuat direktori jika tidak ada, dan mengubah pemiliknya menjadi "root" jika perlu.

Sumber daya diidentifikasi secara unik berdasarkan nama dan jenisnya - Direktori kami akan menjadi directory[/tmp/foo]. Hal-hal aneh akan terjadi ketika Anda memiliki dua sumber daya dengan nama yang sama tetapi atribut yang berbeda - yang menjelaskan masalah Anda, dan itu dapat diperbaiki menggunakan jawaban Darrin Holst:

node[:users].each do |user|
  puts "in loop for #{user['username']}"
  bash "create_user_#{user}" do
    user "root"
    code do
      puts "running 'useradd' for #{user['username']}"
      "useradd #{user['username']}"
    end
    not_if do
      puts "checking /etc/passwd for #{user['username']}"
      "cat /etc/passwd | grep #{user['username']}"
    end
  end
end

Namun, dalam kasus khusus ini, Anda akan mendapat manfaat dari menggunakan sumber daya Pengguna Chef. Berikut ini adalah pengganti resep Anda (tanpa pesan debug):

node[:users].each do |u|
  user u['username'] do
    action :create
  end
end

Mengapa ini lebih baik daripada satu set sumber daya bash?

  1. Sumber daya pengguna bekerja dengan cara yang sama di berbagai platform - resep yang sama akan bekerja pada sistem operasi yang menggunakan sesuatu selain "useradd" untuk membuat pengguna.
  2. Penyedia yang bertanggung jawab untuk ini tahu bagaimana memeriksa apakah pengguna sudah ada, jadi Anda tidak perlu not_if.
  3. Penyedia yang sama juga dapat digunakan untuk menghapus pengguna, mengunci atau membuka kunci kata sandi mereka, dan memperbarui atribut lainnya pada akun pengguna yang ada.

Tetapi alasan terbaik untuk menggunakan sumber daya yang tepat adalah karena itu lebih jelas mengomunikasikan maksud Anda. Tujuan Anda mungkin bukan untuk menjalankan banyak perintah shell - itu untuk memastikan bahwa beberapa pengguna hadir di sistem Anda. Perintah yang digunakan untuk melakukan itu hanyalah detail implementasi.

Penyedia merangkum detail-detail itu, membuat kami bebas untuk fokus mendeskripsikan apa yang kami inginkan.


1
Terima kasih, ini menjelaskan beberapa hal. Resep kreasi pengguna hanyalah contoh yang bisa saya mainkan untuk lebih memahami mengapa loop yang saya miliki di tempat lain tidak berfungsi seperti yang saya harapkan.
Matthew J Morrison
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.