Back to the news overview

LXD 5.7 has been released

21st of October 2022


The LXD team is very excited to announce the release of LXD 5.7!

This is a reasonably light release but comes with some nice smaller additions and a lot of bugfixes.


New features and highlights

ACME / Let's Encrypt support

LXD can now automatically issue its own certificates through any ACME compatible provider which supports HTTP based validatoin.

The most well known such provider is Let's Encrypt.

On the configuration side, this is done through a few new server configuration keys:

  • acme.ca_url
  • acme.domain
  • acme.agree_tos

Most users will just need to set acme.domain and acme.agree_tos to set this up.

On the network front, there are a few requirements to make this work.
The validation will be done through HTTP. This requires the server at acme.domain to publicly listen to BOTH port 80 and port 443. Port 80 needs to be configured to just redirect all traffic to the same URL over HTTPS and port 443 needs to make it to LXD.

Our documentation contains a basic HAProxy configuration to achieve this.


Cloud-init validation

Most cloud-init users will provide it YAML for configuration but until now, LXD would just pass that data straight through to cloud-init without any prior validation.

This is changing now with all three cloud-init configuration keys being validated:

  • cloud-init.user-data
  • cloud-init.vendor-data

For the user and vendor data ones, LXD will only check that it is valid YAML if they are of the #cloud-config type. Other data types will still be let through unchecked.

It's worth noting that LXD doesn't validate the actual Netplan or Cloud-init configuration, instead it currently just validates that the YAML can be properly unpacked. Once cloud-init and netplan have official JSON schemas or similar readily available, we'll be extending those checks to also look at the data itself.

Internal metrics

Up until now, LXD's metrics API was limited to just instance resource usage metrics.

With this release, we're introducting a number of internal metrics too:

  • lxd_go_alloc_bytes_total
  • lxd_go_alloc_bytes
  • lxd_go_buck_hash_sys_bytes
  • lxd_go_frees_total
  • lxd_go_gc_sys_bytes
  • lxd_go_goroutines
  • lxd_go_heap_alloc_bytes
  • lxd_go_heap_idle_bytes
  • lxd_go_heap_inuse_bytes
  • lxd_go_heap_objects
  • lxd_go_heap_released_bytes
  • lxd_go_heap_sys_bytes
  • lxd_go_lookups_total
  • lxd_go_mallocs_total
  • lxd_go_mcache_inuse_bytes
  • lxd_go_mcache_sys_bytes
  • lxd_go_mspan_inuse_bytes
  • lxd_go_mspan_sys_bytes
  • lxd_go_next_gc_bytes
  • lxd_go_other_sys_bytes
  • lxd_go_stack_inuse_bytes
  • lxd_go_stack_sys_bytes
  • lxd_go_sys_bytes
  • lxd_operations_total
  • lxd_uptime_seconds

Those cover a lot of Go's internal memory allocation and Go routine metrics as well as a couple of LXD specific metrics like the daemon uptime and the number of background operations being run.

Cluster join token expiry

Cluster join tokens are pretty powerful as they grant access to LXD's database.
As a result, it makes sense for them to expire after a short while.

Up until now, those would expire when LXD would get restarted, but as that's quite unpredictable, we now have support for an actual expiry date on them too.

Proxy device hotplugging to VM

Proxy devices for virtual machines are limited to just simple NAT.
With that limitation, there was no reason not to allow hotplugging those, making it easy to add additional port redirections for virtual machines.

Complete changelog

Here is a complete list of all changes in this release:

Full commit list
  • doc: split the "doc" target into setup and building
  • doc: set up linkcheck and exceptions
  • doc: fix links that the link checker regards as broken
  • lxd-agent: Only unblock systemd once /dev/lxd/sock is started
  • doc: add linkchecker to the GitHub actions
  • doc: update IRC link
  • lxd/apparmor/instance: allow reading /proc/pid/cpuset
  • tests: Respect LXD_SHIFTFS_DISABLE
  • doc/metrics: add lxd_cpu_effective_total to the list of metrics
  • lxd/cgroup/abstraction: Update GetIOStats to be more flexible
  • lxd/events: Ensure internal listener is only running once
  • lxd/cluster/config: Set default values for loki config keys
  • docs: Added snap version directory for global remotes
  • test: Fix manual shifting protection tests by disabling kernel shifting
  • lxd/apparmor: apparmor profile for qemu-img
  • lxd: Replace readyChan with waitReady canceller
  • lxd: Improve comments
  • lxd/api: Don't serve API requests that cause volume mounts until daemon is fully started
  • lxd/daemon: Don't wrap line
  • lxd/daemon: Move Ready function into init function
  • lxd/storage/s3/miniod/miniod: Expose minio start up error to client
  • lxd: Only load all instances once during init()
  • lxd/instance/drivers/driver/qemu: Dont offer VM support if /dev/vsock is missing
  • lxd/device/proxy: Allows hot plugging proxy device (in nat mode) for VMs
  • doc/header: update to new menu style for
  • shared/validate: Add IsCloudInitUserData and IsYAML
  • shared/instance: Validate cloud-init config keys
  • Allow forwarded traffic to the lxd bridge for proxy nat devices
  • lxd/network/network/utils: Exports UsedByInstanceDevices
  • lxd/network/driver/ovn: UsedByInstanceDevices usage
  • lxd/device/nic/ovn: Add duplicate static address check
  • lxd/network/driver/ovn: Adds parseRouterIntPortIPv4Net and parseRouterIntPortIPv6Net functions
  • lxd/network/driver/ovn: Fix typo in Leases
  • lxd/network/driver/ovn: Use isInUseByDevice in Leases
  • Add client.Operation.WaitContext
  • Use WaitContext in client.operation.Wait
  • lxd/storage_volumes: Fix API documentation
  • lxd/instance_backup: Fix bad swagger data
  • lxd/instance_snapshot: Fix bad swagger data
  • doc/rest-api: Refresh swagger YAML
  • lxd/migration: update proto bindings
  • lxd: use go-criu/crit for dump statistics
  • lxd/migration: remove stats protobuf definitions
  • doc/server: update Loki config
  • lxd/storage/drivers/driver/zfs: Don't fail Mount if policy cannot be applied to existing datasets
  • lxd/network/openvswitch/ovn: Update LogicalSwitchPortSetDNS to accept IPs for DNS records directly
  • lxd/network/driver/ovn: Updated client.LogicalSwitchPortSetDNS usage
  • lxd/network/driver/ovn: Renames InstanceDevicePortSetup and InstanceDevicePortDelete
  • lxd/device/nic/ovn: InstanceDevicePortStart and InstanceDevicePortStop usage
  • lxd/network/driver/ovn: Adds getDHCPv4Reservations function
  • lxd/network/driver/ovn: Build DHCPv4 reservation list during setup
  • lxd/network/openvswitch/ovn: Adds LogicalSwitchDHCPv4RevervationsSet and logicalSwitchParseExcludeIPs functions
  • lxd/network/openvswitch/ovn: Adds LogicalSwitchDHCPv4RevervationsGet function
  • lxd/network/openvswitch/ovn: Updates LogicalSwitchPortDeleteDNS and logicalSwitchPortDeleteDNSAppendArgs to optionally clear DNS names but leave entry
  • lxd/network/driver/ovn: Updates client.LogicalSwitchPortDeleteDNS usage
  • lxd/network/openvswitch/ovn: Check for non-empty DNS UUID in LogicalSwitchPortCleanup
  • lxd/network/driver/ovn: Adds InstanceDevicePortAdd and InstanceDevicePortRemove functions
  • lxd/device/nic/ovn: Wire up InstanceDevicePortAdd and InstanceDevicePortRemove
  • lxd/network/driver/ovn: Ensures DHCPv4 reservation exists if needed in InstanceDevicePortStart
  • doc/header: use color variables to support dark theme
  • client: move from io/ioutil to io and os packages
  • lxc: move from io/ioutil to io and os packages
  • lxc-to-lxd: move from io/ioutil to io and os packages
  • lxd/apparmor: move from io/ioutil to io and os packages
  • lxd/archive: move from io/ioutil to io and os packages
  • lxd/backup: move from io/ioutil to io and os packages
  • lxd/cgroup: move from io/ioutil to io and os packages
  • lxd/cluster: move from io/ioutil to io and os packages
  • lxd/db: move from io/ioutil to io and os packages
  • lxd/device: move from io/ioutil to io and os packages
  • lxd/dnsmasq: move from io/ioutil to io and os packages
  • lxd/endpoints: move from io/ioutil to io and os packages
  • lxd/instance/drivers: move from io/ioutil to io and os packages
  • lxd/migration: move from io/ioutil to io and os packages
  • lxd/network: move from io/ioutil to io and os packages
  • lxd/resources: move from io/ioutil to io and os packages
  • lxd/rsync: move from io/ioutil to io and os packages
  • lxd/seccomp: move from io/ioutil to io and os packages
  • lxd/storage/drivers: move from io/ioutil to io and os packages
  • lxd/storage: move from io/ioutil to io and os packages
  • lxd/sys: move from io/ioutil to io and os packages
  • lxd/template: move from io/ioutil to io and os packages
  • lxd/util: move from io/ioutil to io and os packages
  • lxd: move from io/ioutil to io and os packages
  • lxd-agent: move from io/ioutil to io and os packages
  • lxd-benchmark/benchmark: move from io/ioutil to io and os packages
  • lxd-migrate: move from io/ioutil to io and os packages
  • lxd-user: move from io/ioutil to io and os packages
  • shared: move from io/ioutil to io and os packages
  • test: move from io/ioutil to io and os packages
  • scripts/bash/lxd-client: Add missing network sub-commands
  • lxd/storage/drivers/driver/zfs: Fix incorrect mount dataset policy error check
  • lxd/apparmor/qemuimg: Fix QemuImg when using symlinks
  • lxd/storage/utils: Fix error in ImageUnpack
  • lxd/apparmor/qemuimg: Fix qemuImgProfileTpl policy to support snap
  • doc/linting: fix failures about indentation for unordered lists
  • lxd/vsock: Add ContextID()
  • lxd-agent: Restart server on CID change
  • lxd-agent: Fix imports
  • lxd/instance/drivers/driver/qemu: comment typo
  • lxd-agent: Fix filesystem metrics
  • lxd/endpoints: Unexport clusterAddress to avoid confusion
  • lxd/state/state: Add LocalConfig to State
  • lxd/daemon: Add localConfig to Daemon struct
  • lxd/api/1.0: Update daemon localConfig variable on config update
  • lxd/api/cluster: Update daemon localConfig when it changes in DB
  • lxd/cluster: Use state.LocalConfig.ClusterAddress()
  • lxd/cluster: Update tests to populate state.LocalConfig
  • lxd: Use d.State().LocalConfig.ClusterAddress
  • lxd/node/config/test: Remove use of node.ClusterAddress
  • lxd/patches: Remove use of node.ClusterAddress
  • lxd/cluster/gateway: Adds state to Gateway
  • lxd/cluster/heartbeat: g.state().LocalConfig.ClusterAddress() usage
  • lxd/daemon: Pass State to gateway
  • lxd/api/cluster: d.State().LocalConfig.ClusterAddress() usage
  • lxd/node/config: Removes unused ClusterAddress function
  • lxd/cluster: Removed serverCert from NewGateway as can be accessed from state
  • lxd/daemon: NewGateway usage
  • lxd/instance/instance/utils: Update ValidDevices signature
  • lxd/instance/drivers/load: Updates validDevices to accept local and expanded config
  • lxd/profiles: instance.ValidDevices usage
  • lxd/instance/drivers: instance.ValidDevices usage
  • lxd/instance/drivers: Handle device.ErrUnsupportedDevType when loading device
  • lxd/cluster/heartbeat: Ensure state.LocalConfig is available in heartbeat
  • lxd/api/1.0: s.LocalConfig.HTTPSAddress usage
  • lxd/api/cluster: Consistent naming of local config variables in clusterPutBootstrap
  • lxd/instances/put: Use local cluster address for local cluster member identification in instancesPut
  • lxd/network/driver/bridge: Use local cluster address for local cluster member identification in HandleHeartbeat
  • lxd/cluster: Consistent naming of local config variables
  • lxd/daemon: Consistent naming of local config variables
  • lxd/api/cluster: s.LocalConfig.HTTPSAddress usage
  • lxd/certificates: d.State().LocalConfig.HTTPSAddress() usage
  • lxd/main/activateifneeded: Remove usage of node.HTTPSAddress
  • lxd/node/config/test: Remove usage of HTTPAddress
  • lxd/node/config: Remove HTTPSAddress function
  • lxd/init: Remove unnecessary duplicate network load request in initDataNodeApply
  • lxd/api/cluster: Fixes clusterCertificatePut to use tx.GetNodes to get all members
  • lxd: Allow API paths without version
  • lxd/cluster/config: Add ACME config keys
  • lxd/cluster: Use consistent members terminology when using tx.GetNodes
  • lxd/api/cluster: Use consistent members terminology when using tx.GetNodes
  • lxd/db/db: Use consistent members terminology when using tx.GetNodes
  • lxd/instances/put: Use consistent members terminology when using tx.GetNodes
  • lxd/network/driver/ovn: Use consistent members terminology when using tx.GetNodes
  • lxd: Use consistent members terminology when using tx.GetNodes
  • lxd/api/internal: Only use backup file to instantiate instance if DB not available
  • lxd/instance/operationlock: Adds ActionDelete constant
  • lxd/instance/drivers: Create operation lock in Delete
  • client/lxd/images: Updates CreateImage to stream files from disk to server
  • lxd/instance/drivers/driver/common: Sort snapshots by ID if creation datetime matches
  • lxd/instance/exec: Use cancel.Canceller instead of context
  • lxd/instance/exec: Fix comment typo
  • lxd/instance/exec: Convert attachedChildIsDead channel to cancel.Canceller
  • shared/netutils/network/linux: Update WebsocketExecMirror to support the channel returned from context.Done()
  • lxd/events/connections: Use time.NewTicker in Reader
  • lxd/migrate: Don't shadow error in Connect
  • client/lxd: Set TCP timeout options in rawWebsocket
  • lxd/instance/exec: Adds TCP and application level keepalives and timeouts to each websocket
  • client/lxd/instances: Don't modify err in rawSFTPConn when getting underlying TCP connection
  • doc/storage: add video links
  • Update gomod
  • lxd/db/operationtype: Add RenewServerCertificate
  • lxd/network/driver/bridge: Don't set BridgeVLANSetDefaultPVID on network start
  • lxd/device/nic/bridged: Only remove non-zero default PVID in setupNativeBridgePortVLANs
  • lxd/ip/link: Simplify self/master options in bridge vlan management functions
  • lxd/device/nic/bridged: link.BridgeVLANDelete and link.BridgeVLANAdd usage
  • lxd/acme: Add acme package
  • shared/cert: Add function to get CertInfo from bytes
  • lxd: Add updateClusterCertificate function
  • lxd: Add ACME support
  • lxd/api: Add ACME endpoint
  • lxd: Run server certificate renewal on config change
  • api: Add acme extension
  • doc: Add acme config keys
  • test: Add test for certificate reversion in clusters
  • doc: Add ACME
  • doc/authentication: add http-{301,403} backends to HAProxy example
  • shared/version: Fix regression in useragent string
  • lxd/db/warningtype: Add UnableToUpdateClusterCertificate
  • lxc/file: Fix symlink following in cmdFilePull
  • lxd/metrics: Add internal metrics
  • lxd: Add internal metrics
  • lxd: Add warning if cluster certificate cannot be updated
  • test: Check warning of cluster certificate test
  • doc/server: alpha sort the config namespace list
  • doc/server: add network and storage to the config namespace list
  • api: Add internal_metrics API extension
  • .sphinx: Add goroutines and uptime to wordlist
  • doc/clustering: create new structure
  • doc/clustering: move content into new pages
  • doc/clustering: move content out of old page
  • doc/clustering: reorder content in About clustering
  • doc/clustering: whitespace changes
  • lxd/main/interactive: Remove user facing "node" references
  • lxd-agent/exec: Improve support for detect fork exec errors
  • lxd/instance/drivers/driver/common: Adds ErrExecCommandNotFound and ErrExecCommandNotExecutable constants
  • lxd/instance/drivers/driver/lxc/cmd: Updates Wait to convert special exit statuses into errors
  • lxd/instance/drivers/driver/qemu/cmd: Updates Wait to convert special exit statuses into errors
  • lxd/instance/exec: Improve logging
  • lxd/exec: Set to exit status even on error in cmdExec.Run
  • lxd/main: Exit with custom exit status even on error
  • lxd/instance/exec: Ensure that non-interactive commands still return status code on error in instanceExecPost
  • lxd/list: Fixes filtering of raw input in showInstances
  • lxc/list: Rename container references to instance references
  • doc/api-extensions: /1.0 doesn't accept a trailing "/"
  • doc/clustering: clean up "About clustering"
  • doc/clustering: clean up "How to form a cluster"
  • doc/clustering: clean up "How to manage a cluster"
  • doc/clustering: clean up "How to recover a cluster"
  • doc/clustering: clean up "How to manage instances in a cluster"
  • doc/clustering: clean up "How to configure storage"
  • doc/clustering: clean up "Cluster member configuration"
  • doc/clustering: clean up "How to configure networks"
  • doc/clustering: clean up "How to set up cluster groups"
  • doc: Update metrics
  • doc/explanation: Fix reference to metrics page
  • lxd/device/nic: Adds nicCheckDNSNameConflict function
  • lxd/device/nic: Adds case insensitive instance name conflict check for bridged and ovn NICs
  • test: Fix bridged NIC tests to accomodate duplicate instance name detection
  • doc/rest-api: Add missing Ready state
  • doc: add a link to the development process YouTube video
  • lxd/main/init/interactive: Export cluster token decode helper
  • Rename GetSnapshotExpiry to GetExpiry
  • shared/util: Allow seconds in GetExpiry
  • lxd/cluster/config: Add cluster.join_token_expiry
  • lxd: Add expiry date to cluster join token
  • lxd: Check expiry date of cluster join token
  • lxd/db/operationtype: Add RemoveExpiredClusterJoinTokens
  • lxd: Add cluster task to remove expired cluster join tokens
  • doc: Add cluster.join_token_expiry
  • shared/api: Add expiry date to ClusterMemberJoinToken
  • lxc: Show expiry date in lxc cluster list-tokens
  • api: Add cluster_join_token_expiry API extension
  • i18n: Update translations
  • test/suites: Test cluster token expiry
  • lxd/cluster/config: Add core.remote_token_expiry
  • doc: Add core.remote_token_expiry
  • lxd: Add expiry date to remote token meta data
  • lxd: Check expiry date of remote add tokens
  • shared/api: Add expiry date to CertificateAddToken
  • lxc: Show expiry date in lxc config trust list-tokens
  • test/suites: Test remote token expiry
  • api: Add remote_token_expiry API extension
  • i18n: Update translations from weblate
  • gomod: Update dependencies
  • lxd/instance/drivers/driver/qemu: Remove incorrect comment about handle caching in getAgentClient
  • lxd/instance/drivers/driver/qemu: Do not attempt to mount & unmount in generateAgentCert
  • lxd/instance/drivers/driver/qemu: Make sure instance is running before trying file operations in FileSFTPConn

Try it for yourself

This new LXD release is already available for you to try on our demo service.


The release tarballs can be found on our download page.

Binary builds are also available for:

  • Linux: snap install lxd
  • MacOS: brew install lxc
  • Windows: choco install lxc