开发者

qemu guest automation

I've not been able to find any documentation stating the existence of an API that can be used to automate things inside of a qemu guest.

开发者_运维百科

For example, I would like to launch a process inside of the guest machine from the host machine. Libvirt does not appear to contain such functionality.


[Note: Automation without using any virtualization API. From my blog post.]

Step 1:

By default, QEMU uses SDL to display the VGA output. So, the first step is make this interaction with QEMU through standard I/O. QEMU provides an option for this.

From QEMU docs:

-nographic Normally, QEMU uses SDL to display the VGA output. With this option, you can totally disable graphical output so that QEMU is a simple command line application. The emulated serial port is redirected on the console. Therefore, you can still use QEMU to debug a Linux kernel with a serial console.

So, all you have to do is invoke QEMU with -nographic.

qemu -nographic -hda guest.disk

Step 2:

Now that you can interact with your guest (or QEMU process) through command line, you have to automate this interaction. The obvious way to do this in python is start the QEMU process (with -nographic) with subprocess module and then communicate with that process. But to my surprise, this just didn’t work out for me. So, I looked for some other way.

Later, I found out that the most awesome tool for this kind of jobs is Expect. It is an automation tool for interactive applications written in TCL.

This guide should help you in getting started with Expect. Here is the script to run a guest with QEMU using Expect.

#!/usr/bin/expect -f

#starts guest vm, run benchmarks, poweroff
set timeout -1

#Assign a variable to the log file
set log     [lindex $argv 0]

#Start the guest VM
spawn qemu -nographic -hda guest.disk

#Login process
expect "login: "
#Enter username
send "user\r"

#Enter Password
expect "Password: "
send "user\r"

#Do whatever you want to do with in the guest VM. ( Run a process and write result to log )

#poweroff the Guest VM
expect "# "
send "shutdown -h now\r"


The QEMU Monitor can interact with guest systems to a limited extent using it's own console. This includes reading registers, controlling the mouse/keyboard, and getting screen dumps. There is a QEMU Monitor Protocol (QMP) that let's you pass JSON commands to and read values from the guest system.


As far as I know, the only way to communicate to the guest is through the network bridge.


I use python with pexpect to interact with spawned VMs using their serial consoles. I generally automate scenarios that have up to 128VMs this way, its reasonably swift. I generally use virt-install to instantiate guests, and use "virsh console (domainname)" using pexpect to get a "handle" to each console, so I can send commands to configure networking, startup tools/utilities/scripts, monitor operation, etc. Pretty sweet in terms of simplicity, and since the scripts are just issuing shell commands, you aren't exposed to APIs that change from version to version, e.g. the serial console will always be there. Sometimes I use qemu directly, (lately I am working with a QEMU that libvirt doesn't support since its too new), in that case I will have the guest console use a telnet port so I can "telnet localhost portnumber" to make a console connection instead of "virsh console (domainname)". Either way, python scripts with the pexpect module for interacting with VMs is great.


PyQemu can theoretically do this. I've used it in the past, although it looks like a stale project now. It provides a python agent (the equivalent of VMWare guest tools) to run on the guest, communicating with the host via serial port. You can get proxies to python modules running in the context of the VM, and any communication with them is marshaled over the serial port. In the following example, AutoIt is being used to automate Notepad:

machine = PyQemu.GetProxy("win2k")

# Wrap the machine object in another proxy representing the 'os'
# module running inside the VM.
os = PyQemu.vm.Module(machine,"os")

# NOTE: This is running on the VM!
os.system("notepad")

# Get an IDispatch object representing the autoit ActiveX control
autoit = PyQemu.vm.Dispatch(machine,"AutoItX3.Control")

# See if a window is active on the VM
state = autoit.WinActive("Untitled -")

Caveat: Due to using the serial port it is far from quick (regardless of serial speed settings), so perhaps best to transfer any bulk data by other means, e.g. Virtual FAT disk image.


You can create a reverse ssh tunnel from guest to host, which will redirect each request to host on specific port to guest. This way will help you to control guest from host.


If you're running Linux in the guest, couldn't you just use ssh/screen to launch remote processes on the guest?

Alternatively, I have seen people write python wrappers that use popen() to grab stdin/stdout and use those to automate some commands (i.e. when you see the login prompt, send the login name to stdin of QEMU.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜