For example, I'm running a Linux guest, and I want to do something like this in my init script just after boot:
savevm-somehow
run-lengthy-benchmark
I know how to use the monitor from the host, but it is hard to stop at the correct point to do the savevm: I could GDB step debug until there and then connect to the monitor, but that would be annoying.
In theory you could tell QEMU to put its monitor on a TCP port, and then also tell QEMU's networking to forward that port to the guest, and then from the guest connect to the forwarded port. I would worry about the possibility of deadlocks in this setup, though...
An approach I've used in the past is to script the QEMU monitor prompt using expect. There's an example here:
https://translatedcode.wordpress.com/2015/07/06/tricks-for-debugging-qemu-savevm-snapshots/
which uses a hardcoded delay time, but you ought to also be able to get expect to look at the serial port output to decide when to send the commands.
Related
I have a bare qemu or kvm virtual machine and would like to observe or wait for the event that the virtual machine has booted in a reliable way.
This is a generic question that may not have a generic answer. If it helps you may assume a subset of the following:
The VM is running Debian GNU/Linux.
The actual question is whether the contained ssh server is reachable. It is exported via user networking and a hostfwd.
Remarks:
reliable means that it is suitable for continous integration testing. It should fail in less than 0.1% of cases.
Running ssh -o ConnectionAttempts=30 sometimes produces a failure even though ssh would work afterwards.
I have been looking around to see if there is some simple, stand-alone(ish) agent/server setup that would allow a ping to be launched from a host with an agent on it. When I say "ping," I mean via icmp echo and/or tcp port check. I have Windows, Linux, and AIX systems that would get such an agent.
I would like to set up a central server with authentication that can issue pings from any device that has one of these agents. The primary use would be VPN testing, so that traffic can be initiated from a device that I don't necessarily have access to.
It seems that some monitoring software has this (e.g., Zabbix) but I don't want to go through the pain of installing a whole big piece of software like that just to get this functionality.
Almost all our AIX and Linux systems have perl installed, so that could be a nice option if I had to write my own. I would rather find something "tried-and-true" though...
I didn't realize that we already had SaltStack installed on almost all our servers (I'm a network guy, not a server guy). Once I talked to one of the server administrators, he showed me how this could be done using Salt.
Where does hudson CI get user to run the cmd.exe ?
I'm trying to start and stop some remote services on various slaves and special credentials that are different than what hudson is using are needed. I can't find a place to override the user. I've tried running the server as various users, but it doesn't change anything.
Any other ideas?
Since you want to start and stop the services on the remote machine you need to login with these credentials on the remote machine, since I haven't found a way to start and stop a service on remote machine.
There are different ways to do that. You can create a slave that runs on the remote machines with the correct credentials. You can even create more than one slave for the same machine without any issues, than you can use different credentials for the same machine. These can then fire up the net stop and net start command.
You can also use the SSH plugin. This allows you to configure pre- and post-build ssh scripts. You 'just' need and ssh server on the windows machine. The password for the connection will be stored encrypted.
Use a commad line tool. So far I haven't found a Windows on board tool to have a scripted login to the remote machine. I would use plink for that task. plink is the scripted version of putty. Putty supports different connection types. So you can also use the build in telnet service (not recommended since telnet does not encrypt the connection). Disadvantage is that you will have the password unencrypted in the job configuration.
We had a similar problem, and I resorted to using PsExec. To my advantage, our machines exist on a separate LAN, within 2 firewalls, so I was OK with unencrypted passwords floating around. I had also explored SSH w/ Putty, which seemed to work, but not straightforward.
If someone can help with single line runas command, that could work too.
You don't say how your slaves are connected to Hudson, but I'll assume it's through the "hudson slave" service, since that's probably the most popular way to connect Windows slaves.
If so, the CMD.EXE is run with the same permissions as the user running the service. This can be checked by:
1. run services.msc
2. double-click hudson-slave service
3. go to Log On tab
By default, the slave service runs as "LocalSystem", which is the most powerful account on the system. It should be able to do whatever you need it to do. (i.e. start/stop services)
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.
A process is connecting to a certain ip or domain, but I do not know what it is. The process can't connect to the server. How do I find and change it?
TCPView and netstat work best for connections already established, which isn't the original poster's position.
A better tool for this task is a packet sniffer, which can observe the connection attempt. I recommend Wireshark, which is available for all major platforms.
Details:
Install, then start Wireshark
Press Ctrl-K to start capturing
Select the network interface that you expect the program to use
Type "tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn" in the Capture Filter box (no quotes)
Start the capture, go make your program try to connect, and then stop the capture.
If you do the last step fast enough on a machine without a lot of other network activity, you will have only one captured packet. Otherwise, you'll have to dig through a list to find the one you want. This packet will show the TCP port the program is trying to use.
Type netstat at the cmd prompt to see what ports are being used by active processes. Aside from that, you can't change the port being used by the proc to connect (unless you built the app obviously)
TCPView is a nice little utility that will show you all the open connections and endpoints on the local machine.
If the program is connecting using a DNS name (e.g., example.com), you can use the hosts file (c:\windows\system32\drivers\etc\hosts) to make that name map to a different IP address.
If you mean redirect the connection programmatically, that is a lot more complicated. You're not writing malware, are you?