[libvirt] Qemu guest agent to install RPMs in guest VM from host machine

Hi, I want to be able to install RPM packages (available in host system at some path) to the guest VM and want this facility to be available as a tool. I am thinking of having a gemu guest agent (qemu-ga) running inside guest VM. I did not find any available command ("virsh qemu-agent-command <guest_vm> ...") which can do the same. I am planning to implement a command in qemu guest agent, which I can invoke from virsh like below. "virsh qemu-agent-command vm_01 \ '{"execute":"guest-rpm-install", \ "arguments":{"path":"/usr/local/bin/ABC.rpm"}} I am able to pass arguments from host to guest VM but how am I supposed to pass the whole RPM image from host to guest (which the guest agent can receive and install)? Regards, ~Puneet

On Thu, Jun 12, 2014 at 04:15:01PM +0530, Puneet Bakshi wrote:
Hi,
I want to be able to install RPM packages (available in host system at some path) to the guest VM and want this facility to be available as a tool.
I am thinking of having a gemu guest agent (qemu-ga) running inside guest VM. I did not find any available command ("virsh qemu-agent-command <guest_vm> ...") which can do the same.
I am planning to implement a command in qemu guest agent, which I can invoke from virsh like below.
"virsh qemu-agent-command vm_01 \ '{"execute":"guest-rpm-install", \ "arguments":{"path":"/usr/local/bin/ABC.rpm"}}
I am able to pass arguments from host to guest VM but how am I supposed to pass the whole RPM image from host to guest (which the guest agent can receive and install)?
The general mindset of the QEMU community is to not turn the QEMU guest agent into a general systems management tool. It aims to just restrict itself to the functionality required for core virtualization management tools. So RPM install is out of scope really If you want general systems management facilities, such as RPM installation, then there's countless existing tools for the job that are preferrable to reinventing the wheel. eg func, puppet, chef, ansible, and many many more. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 06/12/2014 07:59 AM, Daniel P. Berrange wrote:
On Thu, Jun 12, 2014 at 04:15:01PM +0530, Puneet Bakshi wrote:
Hi,
I want to be able to install RPM packages (available in host system at some path) to the guest VM and want this facility to be available as a tool.
Libguestfs can already do this for offline guests. I'd suggest looking into using that, rather than waiting for qemu's guest-agent to be taught a new command for manipulating live guests.
The general mindset of the QEMU community is to not turn the QEMU guest agent into a general systems management tool. It aims to just restrict itself to the functionality required for core virtualization management tools. So RPM install is out of scope really
If you want general systems management facilities, such as RPM installation, then there's countless existing tools for the job that are preferrable to reinventing the wheel. eg func, puppet, chef, ansible, and many many more.
There has been talk of adding a generic qemu guest-agent command for spawning an arbitrary command, but no patches so far (in part because libguestfs doing the same functionality for offline guests has been sufficient). -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Thanks for responding. Since I want to work with online guests, unfortunately libguestfs is not an option for me. (Otherwise, I might have used virt-copy-in to copy the files into guest). But, for my understanding, please let me know how such things can be done in QEMU environment. Basically, how can we do following. 1. take some bulky file from host to guest 2. perform some operation on that file 3. get the result of that operation. Thanks in advance. Regards, ~Puneet On Thu, Jun 12, 2014 at 7:35 PM, Eric Blake <eblake@redhat.com> wrote:
On 06/12/2014 07:59 AM, Daniel P. Berrange wrote:
On Thu, Jun 12, 2014 at 04:15:01PM +0530, Puneet Bakshi wrote:
Hi,
I want to be able to install RPM packages (available in host system at some path) to the guest VM and want this facility to be available as a tool.
Libguestfs can already do this for offline guests. I'd suggest looking into using that, rather than waiting for qemu's guest-agent to be taught a new command for manipulating live guests.
The general mindset of the QEMU community is to not turn the QEMU guest agent into a general systems management tool. It aims to just restrict itself to the functionality required for core virtualization management tools. So RPM install is out of scope really
If you want general systems management facilities, such as RPM installation, then there's countless existing tools for the job that are preferrable to reinventing the wheel. eg func, puppet, chef, ansible, and many many more.
There has been talk of adding a generic qemu guest-agent command for spawning an arbitrary command, but no patches so far (in part because libguestfs doing the same functionality for offline guests has been sufficient).
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/12/2014 08:38 AM, Puneet Bakshi wrote:
Thanks for responding.
[Please don't top-post on technical lists]
Since I want to work with online guests, unfortunately libguestfs is not an option for me. (Otherwise, I might have used virt-copy-in to copy the files into guest).
But, for my understanding, please let me know how such things can be done in QEMU environment. Basically, how can we do following.
1. take some bulky file from host to guest
Place the file in a shared filesystem (NFS, gluster, ...) that both the host and guest can see. Depending on whether you use a new enough host and guest kernel, you can even try plan9 9p filesystem passthrough. Or you can use qemu MTP MTP filesystem passthrough (which has the bonus of being supported out-of-the-box for Windows guests): https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg03319.html https://en.wikipedia.org/wiki/Media_Transfer_Protocol although I'm not sure if libvirt needs to be taught to expose that better.
2. perform some operation on that file 3. get the result of that operation.
How would you get a bare-metal machine to perform an operation on a file it just downloads? If you would ssh in to a bare-metal machine, then ssh into your guest. Otherwise, you'll have to submit patches to the qemu list to enhance the guest agent to do what you want before libvirt can even consider adding things to automate yet another way of doing it. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

If I add following channel in guest VM's xml file <channel type='unix'> <source mode='bind' path='/var/lib/libvirt/qemu/f16x86_64.agent'/> <target type='virtio' name='org.qemu.guest_agent.0'/> <alias name='channel0'/> <address type='virtio-serial' controller='0' bus='0' port='1'/> </channel> Would it be possible to use virtio org.qemu.guest_agent.0 for such communication between host and guest? If yes, how can we do it? Regards, ~Puneet On Thu, Jun 12, 2014 at 8:20 PM, Eric Blake <eblake@redhat.com> wrote:
On 06/12/2014 08:38 AM, Puneet Bakshi wrote:
Thanks for responding.
[Please don't top-post on technical lists]
Since I want to work with online guests, unfortunately libguestfs is not
an
option for me. (Otherwise, I might have used virt-copy-in to copy the files into guest).
But, for my understanding, please let me know how such things can be done in QEMU environment. Basically, how can we do following.
1. take some bulky file from host to guest
Place the file in a shared filesystem (NFS, gluster, ...) that both the host and guest can see. Depending on whether you use a new enough host and guest kernel, you can even try plan9 9p filesystem passthrough. Or you can use qemu MTP MTP filesystem passthrough (which has the bonus of being supported out-of-the-box for Windows guests): https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg03319.html https://en.wikipedia.org/wiki/Media_Transfer_Protocol although I'm not sure if libvirt needs to be taught to expose that better.
2. perform some operation on that file 3. get the result of that operation.
How would you get a bare-metal machine to perform an operation on a file it just downloads? If you would ssh in to a bare-metal machine, then ssh into your guest. Otherwise, you'll have to submit patches to the qemu list to enhance the guest agent to do what you want before libvirt can even consider adding things to automate yet another way of doing it.
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/12/2014 09:02 AM, Puneet Bakshi wrote: [once again, please don't top-post]
If I add following channel in guest VM's xml file
<channel type='unix'> <source mode='bind' path='/var/lib/libvirt/qemu/f16x86_64.agent'/> <target type='virtio' name='org.qemu.guest_agent.0'/> <alias name='channel0'/> <address type='virtio-serial' controller='0' bus='0' port='1'/> </channel>
Yes, that's how you set up a guest agent.
Would it be possible to use virtio org.qemu.guest_agent.0 for such communication between host and guest? If yes, how can we do it?
Your FIRST task is to submit a patch to the qemu list to add yet another guest agent command that does what you want. Merely having the guest agent does not mean you can do anything, but only that you can do what has already been coded up in the agent interface. And looking at http://git.qemu.org/?p=qemu.git;a=blob;f=qga/qapi-schema.json I don't yet see a command that does what you seem to want (guest-file-open will let you create/open a file in the guest from the host, but nothing yet lets you create a process in the guest). -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

I understand your point, Eric and Daniel. Let me rephrase my problem statement. Please suggest me how can I address them. I have a project environment where guest VMs are getting created and destroyed based on some (irrelevant) parameters (these guest VMs are instantiated with QEMU guest agent running and with any possible changes in that). There is a module in host which is controlling all this. I need to do following things from within that module. 1. Whenever a new guest VM is created, take (predefined) RPM packages from host to guest VM and install them. 2. Start a script in guest VM (at certain events). 3. Start a process in guest VM (at certain events). I thought to address above issues by having a QEMU guest agent running inside guest VM which has one new command, to which I somehow pass RPMs using "virsh qemu-guest-agent ..." command. In existing qemu-ga code, I saw some examples where they fork() and execle() some stuff. I though I can achieve [2] and [3] using the same way. But, I was getting stuck at [1] in how to transfer files from host to guest and do something with them. I thought I should be able to transfer files using channel like socket/virtio, but was not getting the clue on how to use them. Regards, ~Puneet [PS: What is meant by top-post. I am using gmail and using "reply all". How can I avoid top-post?] On Thu, Jun 12, 2014 at 8:45 PM, Eric Blake <eblake@redhat.com> wrote:
On 06/12/2014 09:02 AM, Puneet Bakshi wrote:
[once again, please don't top-post]
If I add following channel in guest VM's xml file
<channel type='unix'> <source mode='bind' path='/var/lib/libvirt/qemu/f16x86_64.agent'/> <target type='virtio' name='org.qemu.guest_agent.0'/> <alias name='channel0'/> <address type='virtio-serial' controller='0' bus='0' port='1'/> </channel>
Yes, that's how you set up a guest agent.
Would it be possible to use virtio org.qemu.guest_agent.0 for such communication between host and guest? If yes, how can we do it?
Your FIRST task is to submit a patch to the qemu list to add yet another guest agent command that does what you want. Merely having the guest agent does not mean you can do anything, but only that you can do what has already been coded up in the agent interface. And looking at http://git.qemu.org/?p=qemu.git;a=blob;f=qga/qapi-schema.json I don't yet see a command that does what you seem to want (guest-file-open will let you create/open a file in the guest from the host, but nothing yet lets you create a process in the guest).
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 06/12/2014 09:48 AM, Puneet Bakshi wrote:
1. Whenever a new guest VM is created, take (predefined) RPM packages from host to guest VM and install them.
Install them before starting the guest - libguestfs is your friend.
2. Start a script in guest VM (at certain events).
3. Start a process in guest VM (at certain events).
How would you make a bare-metal machine do this? Existing solutions include puppet, chef, ansible, and many more. So why not just install puppet in your guest in step 1, and then for step 2 and 3 connect to your guest via puppet and provision your machine the same way you would provision a bare-metal machine. Then you don't have to worry about extending the guest agent or waiting for new code, when you can already use existing code. But if you INSIST on extending qemu-guest-agent, that discussion belongs first on the qemu list (as owner of the guest agent) and not here (since libvirt can only expose what qemu already provides).
I thought to address above issues by having a QEMU guest agent running inside guest VM which has one new command, to which I somehow pass RPMs using "virsh qemu-guest-agent ..." command.
Note that the 'virsh qemu-guest-agent' command is explicitly unsupported - it exists as a debugging/development aid, and should not be relied on as a stable interface. If you find yourself using a particular guest agent frequently, it's better to turn that into a formal libvirt API (witness how 1.2.5 added the virDomainSetTime command to formalize the previous use of qemu-guest-agent guest-set-time).
In existing qemu-ga code, I saw some examples where they fork() and execle() some stuff. I though I can achieve [2] and [3] using the same way.
Yes, and there has been previous discussion on the qemu list about how to add a guest agent command to fork an arbitrary process in the guest, but it has not yet reached consensus and does not currently have anyone trying to push it through. You'd have to do the legwork yourself on the qemu list to get it added.
But, I was getting stuck at [1] in how to transfer files from host to guest and do something with them. I thought I should be able to transfer files using channel like socket/virtio, but was not getting the clue on how to use them.
How would you transfer files to a bare-metal machine? Via shared filesystem (NFS, gluster, 9p, MTP, ...). So do the same for your guest - set up your host to export a shared filesystem that your guest can then mount. There's no need to shove the file through the guest-agent when you can already access it in the guest via existing file systems.
Regards, ~Puneet [PS: What is meant by top-post. I am using gmail and using "reply all". How can I avoid top-post?]
You manually have to move your cursor to the bottom of the mail before you start typing. (Using non-web-mail agents like mutt or thunderbird can make it easier to automatically avoid top-posting) http://lmgtfy.com/?q=top-posting http://www.caliburn.nl/topposting.html -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (3)
-
Daniel P. Berrange
-
Eric Blake
-
Puneet Bakshi