一次關掉全部 Vagrant 開出來的 VM 們

Vagrant 真的是建立開發環境的好幫手,Vagrantfile 的設計也讓切換各個 VM 設定更加的方便,不過這個做法有個壞處,你必須要進到有 Vagrantfile 所在資料夾時才能操作那個 VM,這表示一件事情:「你不能知道到底還有那些 VM 是開着的,甚至是一次把它們通通都關掉。」

外國網友 Julien Phalip 寫了一隻 scriptpoweroff.py 來做這件事情:

#!/usr/bin/env python

# filename: poweroff.py

import argparse
import re
import os
import subprocess

try:
    import json
except ImportError:
    import simplejson as json


def get_running_vms():
    """
    Returns the list of ids for the VMs currently running in VirtualBox.
    """
    output = subprocess.Popen(['VBoxManage', 'list', 'runningvms'], stdout=subprocess.PIPE).communicate()[0]
    vms = []
    if output is not None:
        lines = output.split('\n')
        for line in lines:
            pattern = re.compile(r'.*{(.*)}')
            match = pattern.match(line)
            if match:
                vms.append(match.group(1))
    return vms


def poweroff_vm(vm_id):
    """
    Issues a 'poweroff' command to VirtualBox for the given VM.
    """
    print "Powering off VM: %s..." % vm_id
    subprocess.call(['VBoxManage', 'controlvm', vm_id, 'poweroff'])


def find_machines_dir():
    """
    Walks up from the current path untils it finds a '.vagrant/machines/' directory.
    """
    path = os.getcwd()
    while path != '/':
        machines_dir = os.path.join(path, '.vagrant/machines/')
        if os.path.isdir(machines_dir):
            return machines_dir
        # Try one level up

        path = os.path.abspath(os.path.join(path, os.pardir))

def find_vm_ids(machines_dir):
    """
    Returns all the VM id files found under the given .vagrant/machines/ directory.
    """
    matches = []
    for root, dirnames, filenames in os.walk(machines_dir):
        for filename in filenames:
            if filename == 'id':
                matches.append(os.path.join(root, filename))
    return matches


# Parse the command's arguments

parser = argparse.ArgumentParser()
parser.add_argument('--all', action='store_true')
args = parser.parse_args()

running_vms = get_running_vms()

if args.all:
    if len(running_vms):
        print "%s VM(s) currently running..." % len(running_vms)
        for vm in running_vms:
            poweroff_vm(vm)
    else:
        print "No VMs are currently running."
else:
    machines_dir = find_machines_dir()
    if machines_dir:
        for vm_id in find_vm_ids(machines_dir):
            vm_id = open(vm_id).read()
            if vm_id in running_vms:
                poweroff_vm(vm_id)
            else:
                print "VM %s is already powered off." % vm_id
    else:
        print "Cannot find any '.vagrant/machines/' directory..."

如果你想要關掉所有開啓中的 Vagrant VMs,你只要下:

./poweroff.py --all

你也可以把它放到 $PATH 底下就可以常常用了,至少我是這樣做的:P

其實 Julien Phalip 寫這隻 script 還有另外一個用意,就是原本他並不知道有 --force 這個選項可以來 halt VM,所以另外一個用途是強制停止 VM 運行。

原作者 blog:這裏

comments powered by Disqus