Fabric: Skrip init sering kali gagal menjalankan daemon mereka

Dibuat pada 19 Agu 2011  ·  19Komentar  ·  Sumber: fabric/fabric

Deskripsi

Saya mendapat banyak laporan tentang ini di IRC, serta komentar di # 350, dan sekarang menjadi utas milis .

Belum ada penyebab yang jelas, dan meskipun telah dilaporkan beberapa kali, saya tidak berharap bahwa ini adalah masalah yang terus-menerus atau kami akan mendengar lebih banyak tentangnya. Dalam beberapa pengujian yang sangat terbatas di pihak saya sejauh ini, saya dapat membuat ulang masalah mungkin 30-50% dari waktu - tetapi dapat direkonstruksi.

Gejala sederhananya adalah skrip bergaya init yang bertanggung jawab untuk memulai daemon dan kemudian segera kembali, akan mengembalikan OK, mengembalikan kode 0 dan pesan status "berhasil" dicetak ke stdout - tetapi tidak akan benar-benar menjalankan daemon yang dimaksud.

Tes pribadi saya dilakukan melalui master terbaru yang menargetkan VM Ubuntu 10.04 (Lucid) dan skrip init paket Apache2.


Awalnya disampaikan oleh Jeff Forcier ( bitprophet ) pada 2011/07/23 di 19:25 EDT

Hubungan

  • Terkait dengan # 350: fabric menutup beberapa perintah jarak jauh (untuk program daemon)
Bug Docs Wart

Komentar yang paling membantu

Baru saja menghadapi masalah ini.
Saya mengalami situasi di mana saya tidak dapat menggunakan tty = False karena saya menjalankan perintah dengan sudo.
Menambahkan >& /dev/null < /dev/null & baik tetapi proses tidak dimulai.

Saya telah memecahkan masalah dengan menambahkan tidur setelah baris eksekusi perintah: nohup java -jar text.jar & sleep 5; exit 0

Semua 19 komentar

Jeff Forcier ( bitprophet ) memposting:


Menggunakan skrip init yang saya uji dan semuanya tampak berjalan dengan cara yang sama (yaitu skenario sukses nyata atau sukses palsu), menyiratkan masalahnya ada di dalam panggilan apachectl yang dibuat skrip itu sendiri.

Mulai berpikir tentang apa penyebabnya pada kita:

  • Karena ini semi-acak, itu membuat saya memikirkan masalah masa lalu dengan subsistem IO yang terganggu kondisi balapan. Namun, saya tidak dapat benar-benar berpikir tentang bagaimana hal itu mungkin dapat mempengaruhi sesuatu di ujung terpencil dengan cara ini, dan kondisi balapan semuanya berbasis lokal.

    • Salah satu cara untuk mengujinya adalah dengan melihat apakah masalah ini muncul dengan Fab 0.9.x dan pty = True (untuk mencocokkan default saat ini di 1.x).

  • Bisa juga hanya terkait pty - Saya tidak ingat ini menjadi masalah sebelum 1.0 dan menyetel pty ke True adalah salah satu perubahan besar dalam perilaku default. Meskipun sekali lagi, saya tidak dapat melihat mengapa menggunakan subsistem request-a-pty SSH akan menyebabkan skrip init berperilaku seperti ini.

    • Tes di sini akan menggunakan ssh -t <hostname> <command> dan melihat apakah itu juga mereproduksi masalah.


pada 2011-07-23 pada 07:45 pm EDT

Jeff Forcier ( bitprophet ) memposting:


apache2ctl itu sendiri juga merupakan pembungkus skrip Bash yang memanggil /usr/sbin/apache2 , yang merupakan tautan simbolis ke biner aktual yang dapat dieksekusi di lokasi pemasangan mpm-worker Apache. Secara khusus, dalam penggunaan normal start disebut /usr/sbin/apache2 -k start . Seperti sebelumnya, apache2ctl tampaknya tidak berperilaku berbeda dalam dua skenario berbeda, re: return value atau bagian mana yang dijalankan.

/usr/sbin/apache2 's docs relatif terbatas (bahkan di situs Apache), hanya menyatakan bahwa Anda harus menggunakan apachectl untuk mengatur env vars (yang akurat - menjalankan apache2 dengan sendirinya cukup membantu jelas dengan kesalahan tentang vars tersebut yang tidak disetel.)

Memeriksa keluaran env tepat sebelum apache2ctl pemanggilan apache2 hanya menghasilkan beberapa item: pengguna, grup, lokasi pidfile dan bahasa. Ini tidak berubah antara situasi sukses dan kegagalan. Saya agak berharap akan ada sesuatu di berbagai sumber dan pengaturan lingkungan di bungkusnya yang kadang-kadang akan berubah, tetapi tidak.


Sejauh ini hal ini tidak berguna. Saatnya menguji ide di atas (pty, ssh) untuk melihat perubahan apa yang ada.


pada 2011-07-23 pukul 08:46 EDT

Jeff Forcier ( bitprophet ) memposting:


Dengan pty=False , tampaknya bekerja jauh lebih baik (seperti yang tersirat oleh komentar Max di # 350). Dengan pengaturan True default, saya melihat kegagalan kira-kira 5/10 kali, terkadang beberapa lebih atau kurang. Dengan False, saya baru saja menjalankannya sekitar 15 kali berturut-turut tanpa kegagalan. Bukan ahli statistik, tapi menurut saya itu cukup bagus.

Menjalankan ssh secara manual menghasilkan hasil yang serupa: ssh -t <host> sudo /etc/init.d/apache2 start akan secara diam-diam gagal menjalankan Apache sekitar 50% dari waktu. Hal yang sama dengan -T (force no pty) dan itu dimulai 100% dari waktu.

Jadi ini bukan salah Fabric; Ini adalah sesuatu yang lebih dalam di mana skrip init ini berperilaku buruk saat pseudo-tty gaya SSH sedang dimainkan.


Akan menggali lebih dalam demi rasa ingin tahu, tetapi sepertinya "solusi" di sini adalah FAQ baru yang menyatakan untuk menggunakan pty=False ketika masalah ini ditemui.


pada 2011-07-23 pukul 08:59 pm EDT

Jeff Forcier ( bitprophet ) memposting:


Ya, sayangnya tidak menemukan apa pun yang menjelaskan perilaku ini. Mengingat temuan di atas, saya pikir FAQ sudah pasti merupakan cara yang tepat.


pada 2011-07-23 di 10:35 pm EDT

Hugo Garza (hiro2k) memposting:


Ughh Saya baru saja mengalami ini kemarin, saya berharap saya melihat bug ini, untungnya saya mencoba mengatur pty = False dan itu berhasil juga. Terima kasih atas penjelasannya, setidaknya itu bukan kesalahan kain. Sekarang Anda benar-benar membuat saya bertanya-tanya mengapa ini gagal.


pada 2011-08-02 pada 01:27 pm EDT

Apakah Anda yakin ini bukan hanya masalah skrip bash juga? Maksud saya dengan utas milis saya. Itu hanya skrip bash yang memulai java dan weblogic.

FWIW, saya mendapatkan perilaku mengerikan ini di hampir setiap mesin Ubuntu yang saya jalankan di EC2.

Ini juga dapat direproduksi dengan tugas yang diluncurkan melalui layar terpisah screen -d -m someBackgroundTask .

Saya harus menyebutkan bahwa biasanya pty=False menyelesaikan masalah, tetapi saya telah melihat contoh di mana bukan itu masalahnya.

@yuvadm - dalam kasus di mana pty = False tidak menyelesaikan masalah, apakah masalah masih dapat dibuat ulang dengan menggunakan perintah ssh biasa (seperti yang disebutkan di atas)? Sejauh yang saya lihat, ini adalah masalah SSH dan bukan Fabric, tetapi akan lebih baik untuk mengetahui apakah ada situasi yang tidak sesuai.

Itu sudut pandang yang menarik untuk diperiksa, saya akan kembali kepada Anda yang satu itu ...

Saya telah mereproduksi masalah ini. Klien adalah Ubuntu 10.04.3 LTS, server adalah "Ubuntu 8.04.4 LTS (server)".
Klien SSH adalah "OpenSSH_5.3p1 Debian-3ubuntu7, OpenSSL 0.9.8k 25 Mar 2009", server ssh adalah "OpenSSH_4.7p1 Debian-8ubuntu1, OpenSSL 0.9.8g 19 Okt 2007". Kain adalah "1.3.3 final".

Masalahnya adalah di sana 100% dengan pty = True, dan menghilang dengan pty = False.

Menghubungkan ke server lain, masalahnya tidak selalu ada saat pty = True.

Dalam kasus saya, untuk pengujian, saya menjalankan perintah yang sangat sederhana: "nohup sleep 100> / tmp / xxx 2> & 1

Saya telah digigit oleh ini, hanya di EC2 seperti yang terlihat (saya belum melihatnya di Linode saya, tapi saya tidak 100% yakin). Pengaturan pty = False sepertinya bisa memperbaikinya.

Baru saja menghadapi masalah ini.
Saya mengalami situasi di mana saya tidak dapat menggunakan tty = False karena saya menjalankan perintah dengan sudo.
Menambahkan >& /dev/null < /dev/null & baik tetapi proses tidak dimulai.

Saya telah memecahkan masalah dengan menambahkan tidur setelah baris eksekusi perintah: nohup java -jar text.jar & sleep 5; exit 0

Terima kasih spodgruskiy,

Kiat Anda berhasil untuk saya.
Saya telah mencoba menulis fab tp memulai cluster strom dengan perintah berikut.

  1. jalankan ('nohup ./bin/storm nimbus> & / dev / null </ dev / null &', pty = False)
  2. jalankan ('nohup ./bin/storm nimbus> & / dev / null </ dev / null &')
  3. run ("screen -d -m './bin/storm nimbus'", pty = False)
  4. jalankan ("|| screen -d -m './bin/storm nimbus'")

Tapi tidak ada yang berhasil, nimbus tidak dimulai sama sekali. Saya tidak mengerti apa yang terjadi.
Terima kasih.

1 untuk trik tidur

dibutuhkan untuk bekerja pada sistem dengan persyaratan

sudo ('start service; sleep .5') dan semuanya baik-baik saja!

Jika Anda menggunakan 'sudo ()' dan sistem jarak jauh telah mengaktifkan RequireTty untuk akses sudo, Anda dapat menggunakan 'set -m; layananstart 'untuk mencegah SIGHUP dikirim ke proses yang dimulai oleh skrip init.

Lihat http://stackoverflow.com/a/14866774 untuk penjelasan lebih rinci tentang bash interaktif versus non-interaktif dan bagaimana hal itu mempengaruhi kontrol pekerjaan.

Saya penasaran, apa masalah ssh di sini?

pty = false bekerja untukku

Ini sebenarnya bukan masalah SSH, ini lebih merupakan perilaku halus di sekitar mode non-interaktif / interaktif BASH dan propagasi sinyal untuk memproses grup.

Berikut ini didasarkan pada http://stackoverflow.com/questions/14679178/why-does-ssh-wait-for-my-subshells-without-t-and-kill-them-with-t/14866774#14866774 dan http: //www.itp.uzh.ch/~dpotter/howto/daemonize , dengan beberapa asumsi tidak sepenuhnya divalidasi, tetapi pengujian tentang cara kerjanya tampaknya mengkonfirmasi.

pty / tty = salah

Bash shell yang diluncurkan terhubung ke stdout / stderr / stdin dari proses yang dimulai dan terus berjalan hingga tidak ada yang terpasang ke soket dan turunannya telah keluar. Proses deamon yang baik akan memastikan ia tidak menunggu anak-anaknya keluar, bercabang ke proses anak dan kemudian keluar. Ketika dalam mode ini tidak ada SIGHUP yang akan dikirim ke proses anak oleh SSH. Saya yakin ini akan berfungsi dengan benar untuk sebagian besar skrip yang menjalankan proses yang menangani deamonizing itu sendiri dan tidak perlu di-background. Di mana skrip init menggunakan '&' untuk latar belakang suatu proses maka kemungkinan besar masalah utamanya adalah apakah proses latar belakang pernah mencoba membaca dari stdin karena itu akan memicu SIGHUP jika sesi telah dihentikan.

pty / tty = true *

Jika skrip init latar belakang proses dimulai, shell BASH induk akan mengembalikan kode keluar ke koneksi SSH, yang pada gilirannya akan terlihat segera keluar karena tidak menunggu proses anak untuk dihentikan dan tidak diblokir pada stdout / stderr / stdin. Ini akan menyebabkan SIGHUP dikirim ke grup proses shell bash induk, yang karena kontrol pekerjaan dinonaktifkan dalam mode non-interaktif di bash, akan menyertakan proses turunan yang baru saja diluncurkan. Di mana proses daemon secara eksplisit memulai sesi proses baru saat bercabang atau dalam proses bercabang maka itu atau anak-anaknya tidak akan menerima SIGHUP dari proses induk BASH yang keluar. Perhatikan ini berbeda dari pekerjaan yang ditangguhkan yang akan melihat SIGTERM.

Saya menduga masalah seputar ini yang hanya berfungsi kadang-kadang ada hubungannya dengan kondisi balapan yang ringan. Jika Anda melihat pendekatan standar untuk deamonizing - http://www.itp.uzh.ch/~dpotter/howto/daemonize , Anda akan melihat bahwa dalam kode sesi baru dibuat oleh proses bercabang yang mungkin tidak dijalankan sebelum orang tua keluar, sehingga menghasilkan perilaku berhasil / gagal acak yang disebutkan di atas. Pernyataan tidur akan memberikan cukup waktu bagi proses bercabang untuk membuat sesi baru, itulah mengapa ini berfungsi untuk beberapa kasus.

pty / tty = true dan kontrol pekerjaan diaktifkan secara eksplisit di bash

SSH tidak akan terhubung ke stdout / stderr / stdin dari bash shell atau proses turunan apa pun yang diluncurkan, yang berarti SSH akan keluar segera setelah shell bash induk mulai selesai menjalankan perintah yang diminta. Dalam kasus ini, dengan kontrol pekerjaan diaktifkan secara eksplisit, proses apa pun yang diluncurkan oleh bash shell dengan '&' di latar belakangnya akan ditempatkan ke sesi terpisah segera dan tidak akan menerima sinyal SIGHUP saat proses induk ke sesi BASH keluar ( Koneksi SSH dalam kasus ini).

Apa yang perlu diperbaiki

Saya pikir solusinya hanya perlu disebutkan secara eksplisit dalam dokumentasi operasi run / sudo sebagai kasus khusus saat bekerja dengan proses / layanan latar belakang. Pada dasarnya gunakan 'pty = false', atau jika tidak memungkinkan, aktifkan kontrol pekerjaan secara eksplisit sebagai perintah pertama, dan perilakunya akan benar.

Seperti yang saya sebutkan di sini fabrickit (pembungkus libs kain) https://github.com/HyukjinKwon/fabrickit/commit/cceb8bfb8f960a3ac41b24c64b8358bd6e7a0366

Anda dapat dengan mudah memulai program sebagai daemon tanpa konfigurasi atau pengaturan tertentu.
Bagaimanapun ini adalah semacam eksekusi Shell dan oleh karena itu harus ada cara untuk melakukan apa yang bisa dilakukan Shell.

Coba ini:

run("sh -c '((nohup %s > /dev/null 2> /dev/null) & )'" % cmd, pty=False)

Saya mencoba ini dan berfungsi dengan baik bahkan tidak menerapkan pemrograman tambahan untuk dijalankan sebagai daemon (bahkan hanya program yang menulis 'Halo' dalam beberapa saat loop berfungsi dengan baik).

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

shadyabhi picture shadyabhi  ·  5Komentar

jamesob picture jamesob  ·  3Komentar

SamuelMarks picture SamuelMarks  ·  3Komentar

yuvadm picture yuvadm  ·  5Komentar

Grazfather picture Grazfather  ·  4Komentar