0

I'm deploying virtual machines with qemu. Installed OS is Debian with linux kernel debian 6.8.11-amd64. The way I deploy a vm is directly with qemu-system command (i.e no vm manager).

In a command fashion, I would like -from the host- to:

  1. Start the VM
  2. Execute a serie of command within the guest (git clone something, configure something, make something, execute something, return success!)
  3. Shutdown the VM

I found that one can exchange with the VM through QMP using specific command,
(https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html#id2)

But I cant find how to do my step 2. It looks like only a specific set of commands are authorized with QMP..

Thanks in advance,

Pierre

2
  • What image are you using to boot the virtual machines?
    – larsks
    Commented May 29 at 19:31
  • the original file is debian-12.2.0-amd64-netinst.iso. The format of the image I then created is qcow2.
    – Pierre
    Commented May 30 at 7:34

1 Answer 1

0

You will need to build a custom filesystem image that includes scripts and/or some other tooling that will run your commands and power off the virtual machine. There are many ways to approach this problem. Here's one possible solution:

  1. Start with an operating system image. For this example, I'm using the debian 12 cloud image.

  2. We'll create a copy-on-write clone of the image to hold our changes. This makes it easy to start over. Here we're creating a 5 GB image; you could adjust the image size as necessary for your workload:

    qemu-img create -f qcow2 -F qcow2 \
      -b debian-12-genericcloud-amd64.qcow2 root.qcow2 5g
    
  3. Now we need to embed some additional information in the image. For this example, we need a netplan file to enable DHCP, and an rc.local script that will perform our clone/build/install/etc actions.

    I have a netplan file called network.yaml that looks like this:

    network:
      version: 2
      renderer: networkd
      ethernets:
        ens3:
          dhcp4: true
    

    And an rc.local file that looks like this:

    #!/bin/sh
    
    set -e
    
    while ! ping -c1 dns.google; do
      echo "waiting for network"
      sleep 1
    done
    
    apt-get -y update
    DEBIAN_FRONTEND=noninteractive apt-get -y install gcc make autoconf automake libtool git autopoint gperf texinfo help2man
    
    mkdir -p /srv/build
    cd /srv/build
    git clone https://git.savannah.gnu.org/git/hello.git
    cd hello
    ./bootstrap
    ./configure --prefix=/usr/local
    make
    make install
    /usr/local/bin/hello
    
    poweroff
    

    We can use the virt-customize command to embed these in the image:

    virt-customize -a root.qcow2 \
      --copy-in network.yaml:/etc/netplan/ \
      --copy-in rc.local:/etc/
    
  4. Now we can use the qemu-system-x86_64 command to boot our image:

    qemu-system-x86_64 -m 1g -enable-kvm \
      -nographic \
      -serial mon:stdio \
      -drive file=root.qcow2,driver=qcow2 \
      -nic user,model=virtio-net-pci
    

    This will run the commands in our rc.local file and power off the vm when complete.

If you need to explicitly report results back to the host, you again have lots of options. You could add a second serial port to your virtual machine (-serial file:status.txt) and write status data there (echo OK > /dev/ttyS1), or you could capture the console output to a file (replace -serial mon:stdio with -serial file:console.txt) and then grep the output when the vm complete, etc.

If you are concerned about the script not completing due to an error, you could wrap your qemu-system-x86_64 command with the timeout command. For example, to ensure the qemu vm exits in under 2 minutes:

timeout 120 qemu-system-x86_64 -m 1g -enable-kvm ...
2
  • Thanks for you complete answer! I will test it during the day!
    – Pierre
    Commented May 30 at 7:36
  • In the end, the trick was to use the rc.local file and write it into the guest with the virt-customize command. Thanks a lot for your help and the completeness of your answer!
    – Pierre
    Commented May 30 at 13:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .