Bagaimana cara memulai dan mematikan mesin VirtualBox secara otomatis?

52

Saya perlu menjalankan sistem perangkat lunak yang dimaksudkan untuk diinstal sebagai alat pada mesin khusus. Untuk menghemat energi, saya berencana menjalankan sistem pada VM VirtualBox sebagai gantinya.

Tuan rumah adalah kotak Linux standar dengan sistem SysV-Init, tamu adalah Linux yang banyak dimodifikasi dan saya lebih suka tidak perlu mengubahnya lebih lanjut. VirtualBox digunakan dalam versi OSE.

Saya sudah menemukan cara memulai VM ketika host melakukan boot ( Edit: ini dilakukan, seperti yang disebutkan Nikhil di bawah, melalui perintah VBoxManager startvm), tetapi bagaimana saya bisa dengan anggun mematikan VM? Setiap skrip yang berjalan pada host harus menunggu sampai tamu benar-benar mati.

Adakah yang bisa menyarankan bagaimana, misalnya, file layanan yang melakukan ini harus terlihat?

jstarek
sumber
dapatkah Anda memberikan skrip startup untuk memulai mesin virtual saat boot
Pemula

Jawaban:

34

Sudahkah Anda mencoba acpipowerbuttondari rangkaian perintah ini?

VBoxManage controlvm        <uuid>|<name>
                            pause|resume|reset|poweroff|savestate|
                            acpipowerbutton|acpisleepbutton|

Edit setelah membaca komentar:

Anda dapat menggunakan acpidatau utilitas lain untuk membuatnya anggun. Juga, dapatkah Anda memberikan informasi lebih lanjut tentang bagaimana Anda mematikan mesin saat ini?

Plain shutdowntidak akan menunggu pekerjaan yang belum selesai, penundaan waktu mungkin terlalu lama.

Saya berasumsi Anda tidak menggunakan window manager jadi coba alat ini .

Baru saja melihat daemon ini . Anda mungkin menemukan itu berguna.

Mavromatis Lozay
sumber
Terima kasih atas balasan Anda dan selamat datang di unix.stackexchange.com! Namun, saya khawatir jawaban Anda juga tidak membahas masalah saya: acpipowerbutton mensimulasikan menekan tombol daya pada mesin nyata, tetapi setelah mengeluarkan perintah ini pada host, VM akan, sekali lagi, membutuhkan waktu untuk dimatikan.
jstarek
4
Tentu. Jadi, Anda harus menulis lingkaran yang memeriksa apakah VM masih berjalan. ACPI adalah metode yang persis sama yang saya gunakan dalam skrip saya untuk ini. vboxmanage list runningvmssampai VM Anda hilang.
Nils
OK, sementara saya pikir saya akan puas dengan bungkus manajemen dalam praktek, +50 kepada Anda untuk menunjuk ke skrip init!
jstarek
16

Daripada mengkodekannya sendiri, pertimbangkan untuk menggunakan Vagrant , yang dibuat untuk instantiate dan mengontrol instance virtualbox. Dokumentasinya sangat bagus dan saya sarankan Anda memeriksanya daripada mencoba untuk membuat sendiri.

Panjang dan pendeknya adalah Anda membuat file kontrol sederhana dan kemudian jalankan vagrant upuntuk memulai instance VirtualBox sebanyak yang Anda inginkan. Anda dapat menggunakan vagrant sshuntuk masuk ke host dan vagrant haltmematikan host (tanpa mengakhiri). vagrant destroyakan menyingkirkan instance.

Ini mendukung penyediaan dengan boneka, Ansible atau Chef dan memungkinkan Anda untuk mengontrol sebagian besar pengaturan konfigurasi VBox yang terbuka.

Aaron Brown
sumber
2
Saya penggemar gelandangan, tetapi dalam hal ini, untuk apa Anda menginginkannya? OP menjalankan sebuah alat, bukan membangun sistem mereka sendiri, jadi ketentuan sepenuhnya kehilangan poin. Dan mengapa pergi dan membuat 'kotak' khusus dari alat, hanya untuk menggunakan gelandangan, ketika Anda pada dasarnya akan melalui proses membangun sistem dengan virtualbox untuk melakukan itu?
mc0e
10

Saya memiliki aplikasi yang sama dengan Anda, dengan satu perbedaan: Saya perlu me-restart sistem dan memulihkan dari snapshot.

Yang Anda minati adalah mode tanpa kepala .

Saya memiliki beberapa layanan seperti itu sehingga saya menggunakan skrip berikut:

VBox_StopRestoreStart.sh

#!/bin/bash
if [ -z "$1" ]; then
        echo "Usage: $0 VMNAME_or_UUID"
        exit 1
fi
set -x
VBoxManage controlvm  "$1" poweroff  #enforce turnoff
VBoxManage snapshot   "$1" restorecurrent   #retore state
VBoxManage showvminfo "$1" | grep State   #display state to ensure
VBoxHeadless -s       "$1"  #run in headless mode in background

bagaimana saya bisa dengan anggun mematikan VM?

JIKA Anda ingin mematikan VM dengan anggun, Anda memiliki dua opsi, tergantung pada aplikasi Anda:

  • Tiru "tombol mati" atau "tombol tidur" dan siapkan VM untuk bereaksi (untuk menutup dengan anggun)
    • VBoxManage controlvm <uuid>|<VMname> acpipowerbutton
    • VBoxManage controlvm <uuid>|<VMname> acpisleepbutton
  • Simpan status VM untuk memulihkan setelahnya
    • VBoxManage controlvm <uuid>|<VMname> savestate

TIPS: Anda mungkin menemukan berguna:

  • VBoxManage list vms - daftar vms yang tersedia
  • rdesktop IP-ADDR:3389atau rdesktop-vrdp IP-ADDR:3389- ketika Anda ingin GUI (bahkan dari jarak jauh ) saat Anda menjalankan dalam mode tanpa kepala:VBoxHeadless -s <uuid>|<VMname>
  • VBoxManage startvm - mulai dengan GUI untuk debugging lokal

Bab VirtualBox manual terkait: Bab 7. Mesin virtual jarak jauh - Langkah demi langkah: membuat mesin virtual di server tanpa kepala

PS Jika Anda tertarik pada solusi berfitur lengkap yang sudah diterapkan, OpenStack tampaknya pilihan yang menarik.

Grzegorz Wierzowiecki
sumber
10

Melihat dokumentasi manajemen VM VirtualBox di http://www.virtualbox.org/manual/ch08.html

Untuk mendaftarkan VM, gunakan perintah VBoxManage list vms

Untuk memulai VM, gunakan perintah VBoxManage startvm

http://www.virtualbox.org/manual/ch08.html#vboxmanage-controlvm

Untuk mengendalikan VM, gunakan VBoxManage controlvm

controlvmSub - perintah memungkinkan Anda untuk mengubah status mesin virtual yang sedang berjalan. Berikut ini dapat ditentukan:

VBoxManage controlvm <vm> pausesementara menunda mesin virtual, tanpa mengubah statusnya untuk selamanya. Jendela VM akan dicat abu-abu untuk menunjukkan bahwa VM saat ini dijeda. (Ini sama dengan memilih item "Jeda" di menu "Mesin" GUI.)

Gunakan VBoxManage controlvm <vm> resumeuntuk membatalkan perintah jeda sebelumnya. (Ini sama dengan memilih item "Lanjutkan" di menu "Mesin" GUI.)

VBoxManage controlvm <vm> resetmemiliki efek yang sama pada mesin virtual dengan menekan tombol "Reset" pada komputer nyata: reboot dingin dari mesin virtual, yang akan memulai kembali dan boot sistem operasi tamu segera. Keadaan VM tidak disimpan sebelumnya, dan data mungkin hilang. (Ini sama dengan memilih item "Reset" di menu "Mesin" GUI.)

VBoxManage controlvm <vm> poweroffmemiliki efek yang sama pada mesin virtual seperti menarik kabel daya pada komputer sungguhan. Sekali lagi, keadaan VM tidak disimpan sebelumnya, dan data mungkin hilang. (Ini sama dengan memilih item "Tutup" di menu "Mesin" pada GUI atau menekan tombol tutup jendela, dan kemudian memilih "Matikan mesin" dalam dialog.)

Setelah ini, status VM akan "dimatikan".

Nikhil Mulley
sumber
Perhatikan bahwa pada beberapa sistem, itu vboxmanage(semua huruf kecil).
Arcege
2
Terima kasih atas balasan Anda, tetapi sayangnya, ini tidak membahas masalah saya: Saya harus menutup tamu dengan anggun , yaitu mengeluarkan "shutdown -h now" di dalam tamu dan minta tuan rumah menunggu sampai tamu telah benar-benar menutup. Tak satu pun dari VBoxManage controlvmsub- perintah yang melakukan itu.
jstarek
Anda dapat memastikan bahwa dengan memeriksa kembali semua vms ada di host sebelum host turun. Jika Anda perlu mengontrol host dari dalam tamu, maka virtualbox.org/manual/ch08.html#vboxmanage-guestcontrol tetapi ini mungkin tidak memberi Anda apa yang Anda cari. Anda harus menulis skrip startup seperti /etc/init.d/vboxvms-serviceskrip pada sistem host, yang setelah mulai akan membuat semua vms hidup dan berhenti, akan membuat semua vms turun.
Nikhil Mulley
VBoxManage controlvm savestateadalah kemungkinan lain (setidaknya google memberitahu saya), ini menyimpan status mesin dan mematikannya dengan bersih, tetapi masih tidak ada cara untuk memaksa tuan rumah menunggu.
Baarn
5

Untuk sistem berbasis systemd, Anda bisa mencoba ini.

Langkah # 1: buat file layanan

[Unit]
Description=VBox Virtual Machine %i Service
Requires=systemd-modules-load.service
After=systemd-modules-load.service

[Service]
User=user
Group=vboxusers
ExecStart=/usr/bin/VBoxHeadless -s %i
ExecStop=/usr/bin/VBoxManage controlvm %i savestate

[Install]
WantedBy=multi-user.target

Langkah # 2: Aktifkan file layanan

$ sudo systemctl enable vboxvmservice@vm_name.service

Referensi

Jan Rüegg
sumber
1
Lebih disukai memasukkan jawaban di sini dan secara opsional menyediakan tautan ke informasi yang lebih terperinci. Tautan target menghilang tanpa pemberitahuan, membuat jawaban Anda tidak berharga.
Anthon
Nah, masalahnya adalah saya tidak bisa benar-benar menyalin seluruh file systemd di tautan 1 di sini, atau haruskah saya melakukan ini?
Jan Rüegg
Yah, sayangnya "tautan busuk" adalah masalah besar dalam kasus-kasus itu ... Saya pikir, untuk anak cucu, dua baris berikut menangkap ide dasar di balik Tautan Anda: Menciptakan layanan yang digunakan VBoxHeadless -s %iuntuk memulai dan VBoxManage controlvm %i savestatemenghentikan VM.
jstarek
Sudah mencoba ini di Debian Jessie, tetapi tidak berhasil. Dibuat pengguna dan grup, atur kepemilikan semua file (termasuk / dev / vbox *). Tetapi ketika layanan dimulai, ia tidak dapat menemukan VM, meskipun namanya benar. Akan menggunakan skrip init normal setelah semua.
mivk
3

Bagaimana kalau mengirim perintah melalui ssh dari host ke tamu?

Saya tidak yakin apakah itu berfungsi dan apakah Anda dapat memeriksa status mesin setelahnya atau mendapatkan sesuatu seperti status keluar, tetapi harus turun setidaknya bersih.

Baarn
sumber
Pemikiran yang bagus, tetapi ini akan menjamin bahwa VM tamu dapat dijangkau melalui jaringan dari host, minimal port ssh (22).
Nikhil Mulley
Pada dasarnya, ini akan berhasil, alat dapat dihubungi di seluruh LAN melalui entri DNS-nya. Namun, seandainya saya menulis sebuah skrip yang ssh'd ke dalam alat setiap kali tuan rumah turun - itu masih harus memblokir (jeda) sampai tamu telah benar-benar mati. Inilah tepatnya pertanyaan saya: Bagaimana script bisa tahu kapan tamu turun, sehingga dapat menghasilkan kontrol mengalir kembali ke SysV-Init dan tuan rumah dapat terus menutup?
jstarek
1
Komentar Anda mengasumsikan bahwa semuanya akan berjalan lancar pada sistem host dan bukan pada sistem tamu. Bagaimana jika kabel daya dicolokkan pada sistem host? Ini diskusi yang berbeda. SysV-init Anda pada sistem host akan menunggu skrip layanan menghentikan VMs selama skrip layanan memahami logika untuk membuat VM tamu mati dengan cara yang benar (shutdown pada host jarak jauh atau matikan saja melalui antarmuka vbox) dan kemudian hasilkan kembali status keberhasilan atau kegagalan kembali ke konsol atau init.
Nikhil Mulley
1
Mengenai: bagaimana skrip tahu kapan tamu mati, coba cek sederhana apakah vm hidup atau mati dari antarmuka VboxManager dan jika tamu ssh'able. Juga, letakkan beberapa pemantauan pada sistem host yang akan melakukan apakah VM tersedia dari Vboxmanager dan ssh'able pada waktu yang tepat.
Nikhil Mulley
1

Solusi saya: Dalam shellscript ini 'root' adalah invoker, dan 'theuser' adalah pemilik 'thevm'

Saya tahu vms telah berakhir ketika output dari perintah VBoxManage list runningvmsmengembalikan sebuah string kosong.

...
start(){
    su -c "VBoxHeadless --startvm thevm" -s /bin/bash theuser &
    # maybe another vbox command
}

stop(){
    su -c "VBoxManage controlvm thevm acpipowerbutton" -s /bin/bash theuser
    # maybe another vbox command
    while [ "`su -c 'VBoxManage list runningvms' -s /bin/bash theuser`" != "" ]
    do
        echo waiting for VMs to shutdown
        sleep 3
    done
}
...
Jorge Sanchez
sumber
1

Untuk memulai vm:

VBoxManage startvm VMNAME --type headless

Untuk menghentikan vm:

VBoxManage controlvm VMNAME savestate

Daftar semua vm yang berjalan:

VBoxManage list runningvms
RIT
sumber
0

Mungkin ini akan membantu sebagai bagian dari solusi.

VBoxManage list runningvms | tr -s '\" {' '%{' | cut -d '%' -f3  | while read uuid; do
   VBoxManage controlvm $uuid savestate; 
done
pengguna58380
sumber
0

Mengapa Anda tidak login ke tamu Anda dan mematikannya dari sana?

Kecuali Anda memiliki alasan kuat untuk tidak menginstal sshd dan mengakses VM melalui VBox, saya akan menggunakan skrip yang hanya mengeluarkan sebuah ssh shutdown -h now. Sejujurnya, saya akan membuat skrip untuk setiap mesin yang benar-benar mematikannya dan melakukan beberapa pemeriksaan saat melakukannya.

Cukup kemas skrip /etc/init.d/shutdown_vm yang memanggil yang lain dari host, panggilan akan diblokir hingga siap. Proses ini (seperti dijelaskan) menambahkan ketergantungan linux pada tamu tetapi menghilangkan ketergantungan VBox di tuan rumah.

Memotong untuk mengejar: Anda tidak perlu mengakses VBox untuk mematikan mesin, jika Anda memiliki beberapa cara mengaksesnya (yaitu ssh) maka OS akan selalu memiliki beberapa cara untuk itu (menyalakannya, tentu saja berbeda)

estani
sumber
Dua alasan: Pertama, seperti yang dinyatakan dalam pertanyaan awal, saya tidak ingin mengubah OS tamu yang banyak dimodifikasi jika tidak benar-benar diperlukan. Kedua, dan yang lebih penting, ini dimaksudkan untuk memberikan cara yang bersih untuk secara otomatis mematikan semua VM yang berjalan jika tuan rumah dimatikan.
jstarek
@jstarek Tetapi Anda tidak perlu mengubah OS tamu Anda jika Anda tidak mau (99,99% dari waktu Anda memiliki beberapa cara untuk masuk, atau ini pengecualian). Dan persis itulah idenya, jika tuan rumah turun, skrip yang tepat akan dipanggil ketika mengubah runtime dan ini hanya masuk ke tamu dan mematikannya dari "di dalam", yang merupakan apa yang dilakukan gelandangan ... sebelum pergi "brute kekuatan "itu adalah ...
estani