Skip to main content

No project description provided

Project description

Minivirt

VMs should be easy.

Discord

Minivirt is a lightweight QEMU manager that provides a Docker-like user experience. The default image is based on Alpine Linux, which is tiny and fast: 50MB compressed disk image, boots to SSH in second(s).

Installation

  1. Install QEMU and other dependencies.

    • MacOS: brew install qemu socat
    • Debian: apt install qemu-kvm qemu-utils qemu-efi-aarch64 socat
    • Alpine: apk add py3-pip qemu qemu-system-x86_64 qemu-img socat tar
  2. Install Minivirt and run a checkup.

    pip3 install minivirt --pre
    miv doctor
    
  3. Pull an image and start a VM.

    miv remote add default https://f003.backblazeb2.com/file/minivirt
    miv pull default alpine-{arch} alpine  # {arch} is automatically replaced with your architecture.
    miv run alpine
    

The miv run command will create an ephemeral VM and open an SSH session into it. When you exit the session, the VM is destroyed.

Persistent VMs

The images and VMs are stored in ~/.cache/minivirt/.

Create a VM with the create command:

miv create alpine myvm

Start the VM with the terminal attached to its serial console:

miv start myvm

Gracefully stop the VM by sending an ACPI poweroff:

miv stop myvm

Destroy the VM to remove its disk image and other resources:

miv destroy myvm

Inspect the VMs:

miv ps
miv ps -a  # also shows stopped VMs

Graphics

Start the VM in the background and connect a display to it:

miv create alpine myvm
miv start myvm --daemon --display

Log in as root, and run:

setup-xorg-base
apk add xfce4 xfce4-terminal dbus
startx

To make the screen bigger, right-click on the desktop, hover on Applications, then Settings, and click Display. Select another resolution like "1440x900" and click "apply".

Images

Minivirt maintains a database of images identified by their SHA256 checksum. They may have any number of tags.

Show images in the database:

% miv images
5446f671 1.4G ubuntu-22.04
84200bbd 115M alpine-3.15
8ad24d9f 1.4G ubuntu-20.04
c86a9115 114M alpine alpine-3.16

Commit a VM as an image:

miv commit myvm myimage

Save the image as a TAR archive:

miv save myimage | gzip -1 > ~/myimage.tgz

Later, load the image:

zcat ~/myimage.tgz | miv load myimage

To make sure the images and VMs are consistent, run a database check:

miv fsck

To remove an image, first untag it. This only removes the tag, not the image itself.

miv untag myimage

The image is removed during prune:

miv prune

Image repositories

Add a remote repository:

miv remote add default https://f003.backblazeb2.com/file/minivirt

Pull an image. {arch} will be interpolated to the machine architecture.

miv pull default alpine-{arch} alpine

To host an image repository, you need an S3-compatible object store (e.g. AWS S3, Backblaze B2). Set the following environment variables:

  • AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY: authentication credentials.
  • AWS_ENDPOINT_URL (optional): if the object store is not hosted on the AWS public cloud, this should point to the appropriate endpoint.

The bucket name is taken from the last part of the remote's URL, e.g. minivirt for the default repository.

Run miv push to upload an image:

miv push default alpine-3.16 alpine-3.16-aarch64

Development

  1. Create a virtualenv so you don't interfere with gobally-installed packages:

    python3 -m venv .venv
    source .venv/bin/activate
    
  2. Install the repo in edit mode and development dependencies:

    pip3 install -e .
    pip3 install pytest
    
  3. Run the test suite:

    pytest
    pytest --runslow  # if you're not in a hurry
    

Recipes

Minivirt can build images from recipes, which are YAML files, with a syntax inspired by Github Actions workflows. The recipes directory contains some examples.

miv build recipes/alpine-3.16.yaml --tag alpine-3.16 -v

The -v flag directs the output of the build (serial console or SSH) to stdout.

Python API

Minivirt is written in Python and offers a straightforward API:

from minivirt.cli import db

alpine = db.get_image('alpine')
myvm = VM.create(db, 'myvm', image=alpine, memory=512)
with myvm.run(wait_for_ssh=30):
    print(myvm.ssh('uname -a', capture=True))

GitHub Actions self-hosted runners

Minivirt comes with a server that launches GitHub Actions runners when a workflow job is queued. Each runner is ephemeral and runs in its own VM.

  1. Install extra dependencies:

    pip install -e minivirt[githubactions]
    
  2. Build an actions runner image:

    miv build recipes/alpine-3.15.yaml --tag alpine-3.15 -v
    miv build recipes/ci-alpine.yaml --tag ci-alpine -v
    miv build recipes/githubactions-alpine.yaml --tag githubactions-alpine -v
    
  3. Run the server. To interact with the GitHub API, it needs a GitHub PAT, and runs git credentials fill to retrieve it. It uses ngrok to listen for webhook events; to avoid the ngrok session timing out, set a token in the NGROK_AUTH_TOKEN environment variable.

    miv -v githubactions serve githubactions-alpine {repo}
    

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

minivirt-0.1b1.tar.gz (22.3 kB view hashes)

Uploaded Source

Built Distribution

minivirt-0.1b1-py3-none-any.whl (23.3 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page