Hey all,
I would appreciate your feedback on the document below, as well as any tips you might have!
Thanks
See also: Blueprint
This document explains how to create and use custom blueprints. With this approach, users can control the initialisation process to run Multipass instances for their needs.
The result should enable the user to spin up various instances with different toolsets.
Step 1: Create a minimal viable blueprint
The first step is to create a local catalogue of blueprints.
mkdir ~/blueprints
touch ~/blueprints/custom.yaml
Edit custom.yaml
with the following content:
description: My custom VM configuration
version: latest
runs-on:
- amd64
instances:
custom:
image: 22.04
limits:
min-cpu: 4
min-mem: 4G
min-disk: 20G
timeout: 1800
cloud-init:
vendor-data: |
package_update: true
To use this new blueprint, run:
multipass launch file://blueprints/custom.yaml # only from ~
This command will create an instance named custom
based on Ubuntu 22.04 LTS, with 4 CPU cores, 4 GB of memory and 20 GB of disk space.
See more:
multipass launch
Step 2: Define the toolset to use
In this part, we will create a blueprint with a Python development toolset. We will need:
- git
- pyenv for managing Python versions
- pipx for managing Python-related tools
First, either rename custom.yaml
to python.yaml
or create a new file with the previous content. Then, add the following content to the vendor-data
section:
# previous content
cloud-init:
vendor-data: |
package_update: true
packages:
- build-essential
- libssl-dev
- zlib1g-dev
- libbz2-dev
- libreadline-dev
- libsqlite3-dev
- curl
- libncursesw5-dev
- xz-utils
- tk-dev
- libxml2-dev
- libxmlsec1-dev
- libffi-dev
- liblzma-dev
- git
- pipx
runcmd:
- |
sudo -u ubuntu bash -c "$(curl -fsSL https://pyenv.run)"
sudo -u ubuntu /home/ubuntu/.pyenv/bin/pyenv init 2>> /home/ubuntu/.bashrc
sudo -u ubuntu /home/ubuntu/.pyenv/bin/pyenv install 3.10.13
sudo -u ubuntu echo 3.10.13 > /home/ubuntu/.pyenv/version
sudo -u ubuntu pipx ensurepath
sudo -u ubuntu pipx install black
sudo -u ubuntu pipx install tox
sudo -u ubuntu pipx install ruff
sudo -u ubuntu pipx install pyright
This packages
list comes from pyenv’s recommended build environment.
The runcmd
subsection accomplishes the following:
- installing
pyenv
, adding it to the PATH and making Python 3.10.13 the default version - using
pipx
to install several quality of code tools in their own environment
Let’s inspect this blueprint to validate that we got everything we planned.
multipass launch file://blueprints/python.yaml
multipass shell python
python -V
Python 3.10.13
pipx list
venvs are in /home/ubuntu/.local/pipx/venvs
apps are exposed on your $PATH at /home/ubuntu/.local/bin
package black 24.2.0, installed using Python 3.10.12
- black
- blackd
package pyright 1.1.351, installed using Python 3.10.12
- pyright
- pyright-langserver
- pyright-python
- pyright-python-langserver
package ruff 0.2.2, installed using Python 3.10.12
- ruff
package tox 4.13.0, installed using Python 3.10.12
- tox
We might want to automate some checks by adding a health-check
section to python.yaml
.
# previous content
cloud-init:
vendor-data: |
# ...
health-check: |
set -e
python -V
pipx list
Step 3: Improve user experience
This configuration works as expected, but there is room for improvement. First, we will automate mounting a directory to exchange files between the host and the guest VM.
Add workspace: true
to the python
section in the python.yaml
file:
description: My custom Python VM configuration
version: latest
runs-on:
- amd64
instances:
python:
image: 22.04
workspace: true
limits:
min-cpu: 4
min-mem: 4G
min-disk: 20G
# ...
A ~/multipass/python
folder will be created on the host and mounted in the VM upon instantiation.
One limit of our blueprint is that it will use the same default name for all instances, which is not allowed by Multipass. Using the full path to the blueprint is cumbersome as well. We can address both issues by creating a new shell alias.
alias vm_py="multipass launch file:///home/user/blueprints/python.yaml -n"
Using vm_py
now requires a distinct name for the new VM, and can still accept other multipass launch
parameters.
Conclusion
You have now created a personal catalogue of custom blueprints. They are available as easily as vm_py
, vm_rust
, etc. as long as the proper aliases are created. Further refinements could be made: how about replacing the alias by a bash function that instantiates the VM, then transfers files over to the VM (think dot files, vim configuration, not-sensitive credentials)?