Skip to content

Initial support for VMs#911

Draft
jonathan-conder wants to merge 16 commits into
mainfrom
feature/vm
Draft

Initial support for VMs#911
jonathan-conder wants to merge 16 commits into
mainfrom
feature/vm

Conversation

@jonathan-conder

Copy link
Copy Markdown
Contributor

Description

(currently vibe coded for the most part, use at your own risk)

Self-review quick check

  • Make decisions that cost a lot to reverse explicit in the PR description.
  • Avoid nested conditions.
  • Delete dead code and redundant comments.
  • Normalise symmetries by sticking to doing identical things identically.
// one way to handle errors
if err := f(); err != nil {
   ...
}

// one way to handle multiple returns
val, err := f()
if err != nil {
   ...
}
...
  • Check that coupled code elements, files, and directories are adjacent. For example, test data is stored as close as possible to a test.
  • Put variable declaration and initialisation together.
  • Divide large expressions into digestable and self-explanatory ones. Use multiple variables if required.
  • Put a blank line between two logically different chunks of code.
  • Follow the style guide for new error messages.

Docs

Procedure:

  • I have checked and added or updated relevant documentation.
  • I have checked and added or updated relevant release notes.
  • I have included the technical author in the review.

Content:

  • Headings and titles accurately describe the content.
  • New and updated pages include correct metadata.
  • Documentation tests are added or updated where applicable (for tutorial/ and how-to/ sections).
  • Documentation follows the style guide.
  • If needed, docs/.coverage.yaml updated, coverage tags added (.. artefact).

Or:

  • I confirm the PR has no implications for documentation.

This is something we decided in order to minimize the maintenance
overhead of supporting multiple different formats. The cost is that
certain operations no longer work:
- Restoring a workshop that currently has an old format
- Resuming a launch or refresh that began with an old format

The first is now a hard error. The second is also a hard error if
resuming with `--continue`. If a change was running while the daemon was
being updated, then we can still end up with weird workshops that mix
two formats. We aim to fix this in the future using a pre-refresh hook.

For daemon downgrades, we'll probably require that all workshops are
removed first, since old daemons can't anticipate what newer workshops
might look like.
It's possible for <NAME>.<PID>.wp to be taken if <PID> matches a
project's basename. It's also possible for *.<NAME>-<PID>.wp to be
taken, but that doesn't mean <NAME>-<PID>.wp is unavailable. Might as
well display it so we can rely on always having a *.wp address.
Now that we remove the NoCloud seed templates, even 20.04 images support
the new-style config options.
The current 6/stable LXD snap has reverted some patches to LXCFS which
caused canonical/lxd#17983, so this workaround
isn't needed. See canonical/lxd-pkg-snap#1236.
With VMs it's difficult to reset the machine-id when taking a snapshot.
On the other hand, on first boot the machine-id is set to the SMBIOS
UUID, which comes from LXD's volatile.uuid config option. We can do that
(in VMs) for subsequent boots by including it in the kernel cmdline.

For containers, we might as well match that behaviour. It's easier
actually, because we can just use metadata templates. This removes the
need to use the MAC address as a DHCP identifier. A workshop will now
keep its machine-id from launch until remove.
In order to move away from reinvoking cloud-init when launching or
refreshing from a snapshot, we need to move the workshop-specific config
to a metadata template (which will be updated on copy, similar to the
hostname).

It's possible to keep using netplan, but it complains that the
instantiated templates have 0644 permissions instead of 0600. The LXD
API doesn't provide a way to change this, and we already use some
(workshop-agnostic) settings that netplan doesn't support, so I decided
to just bypass netplan completely and use systemd-networkd alone.

While testing this, I noticed that the hostname systemd-networkd sends
over DHCP is immaterial, LXD hard codes it using a config file in
/var/snap/lxd/common/lxd/networks/workshopbr0/dnsmasq.hosts/. This
actually leads to annoying journal messages because the FQDN is wrong.
But luckily dnsmasq ignores it and just looks at the first label, i.e.
<WORKSHOP>-<PROJECT>. We can disable this behaviour by setting dns.mode
to "dynamic", but I'm holding off on that for now because some weird
stuff happened to my network after I enabled it. Prime suspect is
NetworkManager thinking it owns the bridge and/or veth devices.
@jonathan-conder jonathan-conder self-assigned this Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant