らくがきちょう

なんとなく

pyvmomi を使って Python スクリプトで仮想マシンをシャットダウンする

pyvmomi に同梱されているサンプルスクリプトには仮想マシンを再起動する reboot_vm.py というものがあるのですが、単純に「電源オフ」や「シャットダウン」というスクリプトは(少なくても現時点では)見当たらないようです。 指定日時に仮想マシンを電源オフする scheduled_poweroff.py というサンプルはあるのですが…

そこで reboot_vm.py に「指定した仮想マシンをシャットダウンする」スクリプトを書いてみました。 ファイル名は shutdown_guest_vm.py としました。

ポイント 1

ベースにしている reboot_vm.py も同様ですが、Python のバージョンとの兼ね合いで、自己証明書を利用している vCenter へ接続する際にエラーとなってしまいます。 そこで、証明書の妥当性検証を無効にする為、スクリプト冒頭に以下を追記しています。

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

ポイント 2

ほぼサンプルスクリプトのままですが、仮想マシンに対する処理が ResetVM_Task()(再起動)と書かれていたものを ShutdownGuest() に変更しました。

変更前(reboot_vm.py での処理)

TASK = VM.ResetVM_Task()

変更後(shutdown_guest_vm.py での処理)

TASK = VM.ShutdownGuest()

スクリプト全体(shutdown_guest_vm.py

#!/usr/bin/env python
#
# Written by Michael Rice
# Github: https://github.com/michaelrice
# Website: https://michaelrice.github.io/
# Blog: http://www.errr-online.com/
#
# This code is released under the terms of the Apache 2
# http://www.apache.org/licenses/LICENSE-2.0.html
#
# Example script to reboot a VirtualMachine

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

import atexit

from pyVim import connect

from tools import cli
from tools import tasks


def setup_args():
    """Adds additional ARGS to allow the vm name or uuid to
    be set.
    """
    parser = cli.build_arg_parser()
    # using j here because -u is used for user
    parser.add_argument('-j', '--uuid',
                        help='UUID of the VirtualMachine you want to reboot.')
    parser.add_argument('-n', '--name',
                        help='DNS Name of the VirtualMachine you want to '
                             'reboot.')
    parser.add_argument('-i', '--ip',
                        help='IP Address of the VirtualMachine you want to '
                             'reboot')

    my_args = parser.parse_args()

    return cli.prompt_for_password(my_args)


ARGS = setup_args()
SI = None
try:
    SI = connect.SmartConnect(host=ARGS.host,
                              user=ARGS.user,
                              pwd=ARGS.password,
                              port=ARGS.port)
    atexit.register(connect.Disconnect, SI)
except IOError as ex:
    pass

if not SI:
    raise SystemExit("Unable to connect to host with supplied info.")
VM = None
if ARGS.uuid:
    VM = SI.content.searchIndex.FindByUuid(None, ARGS.uuid,
                                           True,
                                           True)
elif ARGS.name:
    VM = SI.content.searchIndex.FindByDnsName(None, ARGS.name,
                                              True)
elif ARGS.ip:
    VM = SI.content.searchIndex.FindByIp(None, ARGS.ip, True)

if VM is None:
    raise SystemExit("Unable to locate VirtualMachine.")

print("Found: {0}".format(VM.name))
print("The current powerState is: {0}".format(VM.runtime.powerState))
TASK = VM.ShutdownGuest()
#tasks.wait_for_tasks(SI, [TASK])
print("its done.")

使い方

実行例は以下の通りです。

python shutdown_guest_vm.py -s [ADDRESS] -u [USERNAME] -p [PASSWORD] --uuid [UUID]

参考

reboot_vm.py

#!/usr/bin/env python
#
# Written by Michael Rice
# Github: https://github.com/michaelrice
# Website: https://michaelrice.github.io/
# Blog: http://www.errr-online.com/
#
# This code is released under the terms of the Apache 2
# http://www.apache.org/licenses/LICENSE-2.0.html
#
# Example script to reboot a VirtualMachine

import atexit

from pyVim import connect

from tools import cli
from tools import tasks


def setup_args():
    """Adds additional ARGS to allow the vm name or uuid to
    be set.
    """
    parser = cli.build_arg_parser()
    # using j here because -u is used for user
    parser.add_argument('-j', '--uuid',
                        help='UUID of the VirtualMachine you want to reboot.')
    parser.add_argument('-n', '--name',
                        help='DNS Name of the VirtualMachine you want to '
                             'reboot.')
    parser.add_argument('-i', '--ip',
                        help='IP Address of the VirtualMachine you want to '
                             'reboot')

    my_args = parser.parse_args()

    return cli.prompt_for_password(my_args)


ARGS = setup_args()
SI = None
try:
    SI = connect.SmartConnect(host=ARGS.host,
                              user=ARGS.user,
                              pwd=ARGS.password,
                              port=ARGS.port)
    atexit.register(connect.Disconnect, SI)
except IOError as ex:
    pass

if not SI:
    raise SystemExit("Unable to connect to host with supplied info.")
VM = None
if ARGS.uuid:
    VM = SI.content.searchIndex.FindByUuid(None, ARGS.uuid,
                                           True,
                                           True)
elif ARGS.name:
    VM = SI.content.searchIndex.FindByDnsName(None, ARGS.name,
                                              True)
elif ARGS.ip:
    VM = SI.content.searchIndex.FindByIp(None, ARGS.ip, True)

if VM is None:
    raise SystemExit("Unable to locate VirtualMachine.")

print("Found: {0}".format(VM.name))
print("The current powerState is: {0}".format(VM.runtime.powerState))
TASK = VM.ResetVM_Task()
tasks.wait_for_tasks(SI, [TASK])
print("its done.")