Gilles: Gilles: What would it mean exactly to set the expiry variable to the given example string “1M 2H 3d 4w 5m 6y”?

If you put that string verbatime, then the snapshots will expire in about 6.5 years.

You would normally put something like “2d” (expire when 2 days old), or “12H 1w” (expire when 1 week 12 hours old).

Gilles: Gilles: How many (and which) snapshots will continuously be available if let such a configuration run indefinitely?

It’s not clear when a snapshot gets created, what name it will get. And ain’t nobody has time to read the source. 8-].

Let’s do it live.

$ snap info lxd name: lxd summary: System container manager and API publisher: Canonical✓ contact: https://github.com/lxc/lxd/issues license: unset description: | LXD is a system container manager. With LXD you can run hundreds of containers of a variety of Linux distributions, apply resource limits, pass in directories, USB devices or GPUs and setup any network and storage you want. Pre-made images are available for Ubuntu, Alpine Linux, ArchLinux, CentOS, Debian, Fedora, Gentoo, OpenSUSE and more. LXD is network aware and all interactions go through a simple REST API, making it possible to remotely interact with containers on remote systems, copying and moving them as you wish. Want to go big? LXD also has built-in clustering support, letting you turn dozens of servers into one big LXD server. LXD containers are lightweight, secure by default and a great alternative to running Linux virtual machines. Supported options for the LXD snap (snap set lxd [<key>=<value>...]): - criu.enable: Enable experimental live-migration support [default=false] - daemon.debug: Increases logging to debug level [default=false] - daemon.group: Group of users that can interact with LXD [default=lxd] - ceph.builtin: Use snap-specific ceph configuration [default=false] - openvswitch.builtin: Run a snap-specific OVS daemon [default=false] LXD documentation can be found at: https://lxd.readthedocs.io commands: - lxd.benchmark - lxd.buginfo - lxd.check-kernel - lxd.lxc - lxd - lxd.migrate services: lxd.activate: oneshot, enabled, inactive lxd.daemon: simple, enabled, active snap-id: J60k4JY0HppjwOjW8dZdYc8obXKxujRu tracking: stable refresh-date: 22 days ago, at 14:06 UTC channels: stable: 3.9 2019-01-18 (9919) 54MB - candidate: 3.10 2019-02-08 (10059) 54MB - beta: ↑ edge: git-fe0844d 2019-02-08 (10071) 54MB - 3.0/stable: 3.0.3 2018-11-26 (9663) 53MB - 3.0/candidate: 3.0.3 2019-01-19 (9942) 53MB - 3.0/beta: ↑ 3.0/edge: git-18c9b88 2019-01-19 (9940) 53MB - 2.0/stable: 2.0.11 2018-07-30 (8023) 28MB - 2.0/candidate: 2.0.11 2018-07-27 (8023) 28MB - 2.0/beta: ↑ 2.0/edge: git-c7c4cc8 2018-10-19 (9257) 26MB - installed: 3.9 (9919) 54MB -

We are running on the stable channel that has LXD 3.9 but LXD 3.10 is on the candidate channel.

Let’s switch to the candidate channel and refresh in order to get LXD 3.10 installed. Also, make a mental note to switch back to the stable channel by Monday when LXD 3.10 makes it into the stable channel.

$ snap switch lxd --channel=candidate "lxd" switched to the "candidate" channel $ snap refresh Download snap "lxd" (10059) from channel "candidate" | Stop snap "lxd" services \ Copy snap "lxd" data / Setup snap "lxd" (10059) security profiles / Start snap "lxd" (10059) services \ lxd (candidate) 3.10 from Canonical✓ refreshed $

Sanity check now:

$ lxd --version 3.10 $ lxc --version 3.10

Nice, we are good to go.

First, let’s test with getting LXD to automatically create snapshots.

Here is the documentation,

snapshot_scheduling This adds support for snapshot scheduling. It introduces three new configuration keys: snapshots.schedule, snapshots.schedule.stopped, and snapshots.pattern. Snapshots can be created automatically up to every minute.

It says that the timer resolution in one minute. That is, we can schedule at least every minute or more. Not less than one minute.

$ lxc launch ubuntu:18.04 mycontainer $ lxc config set mycontainer snapshots.schedule "1 0 0 0 0 0" Error: Invalid config: Schedule must be of the form: <minute> <hour> <day-of-month> <month> <day-of-week> $ lxc config set mycontainer snapshots.schedule "* * * * *"

The above schedule means that it should create a snapshot every minute.

See https://crontab.guru/every-1-minute on how to specify different crontab-style schedules.

Meanwhile, a few minutes have passed.

$ lxc info mycontainer ... Snapshots: snap0 (taken at 2019/02/08 22:32 UTC) (stateless) snap1 (taken at 2019/02/08 22:33 UTC) (stateless) snap2 (taken at 2019/02/08 22:34 UTC) (stateless) snap3 (taken at 2019/02/08 22:35 UTC) (stateless)

So, we got per-minute creation of snapshots. The default pattern snapshots.pattern is apparently snap%d .

Let’s try now to set a name pattern for the snapshots. If you do not put a *%d in the pattern, then you get the first snapshot named as the pattern, then the next is your pattern string + -0 , and so on.

$ lxc config set mycontainer snapshots.pattern "mysnapshot-%d" $ lxc info mycontainer ... Snapshots: snap0 (taken at 2019/02/08 22:32 UTC) (stateless) snap1 (taken at 2019/02/08 22:33 UTC) (stateless) snap2 (taken at 2019/02/08 22:34 UTC) (stateless) snap3 (taken at 2019/02/08 22:35 UTC) (stateless) snap4 (taken at 2019/02/08 22:36 UTC) (stateless) snap5 (taken at 2019/02/08 22:37 UTC) (stateless) snap6 (taken at 2019/02/08 22:38 UTC) (stateless) snap7 (taken at 2019/02/08 22:39 UTC) (stateless) snap8 (taken at 2019/02/08 22:40 UTC) (stateless) snap9 (taken at 2019/02/08 22:41 UTC) (stateless) snap10 (taken at 2019/02/08 22:42 UTC) (stateless) snap11 (taken at 2019/02/08 22:43 UTC) (stateless) mysnapshot-0 (taken at 2019/02/08 22:44 UTC) (stateless) mysnapshot-1 (taken at 2019/02/08 22:45 UTC) (stateless) $

A snapshot does not get overwritten, if it exists, LXD moves on to the next number.

Let’s do the expiry now. When a snapshot gets 3 minutes old, it should expire.

$ lxc config set mycontainer snapshots.expiry "3M" $

Let’s wait for a new container to get created. Then,

$ lxc config show mycontainer/mysnapshot-11 architecture: x86_64 config: image.architecture: amd64 image.description: ubuntu 18.04 LTS amd64 (release) (20190131) image.label: release image.os: ubuntu image.release: bionic image.serial: "20190131" image.version: "18.04" snapshots.expiry: 3M snapshots.pattern: mysnapshot-%d snapshots.schedule: '* * * * *' volatile.base_image: b7c4dbea897f09f29474c8597c511b57c3b9c0d6f98dc42f257c64e76fea8c92 volatile.eth0.hwaddr: 00:16:3e:08:69:5c volatile.idmap.base: "0" volatile.idmap.next: '[{"Isuid":true,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]' volatile.last_state.idmap: '[{"Isuid":true,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]' volatile.last_state.power: RUNNING devices: {} ephemeral: false profiles: - default expires_at: 0001-01-01T00:00:00Z

So, something is wrong and the expires_at is set to the default NULL value (never expire).

I did peek in the source code and did not manage to figure out what’s going on.

Here’s the source (lxd/container_snapshot.go):

expiry, err := shared.GetSnapshotExpiry(time.Now(), c.LocalConfig()["snapshots.expiry"]) if err != nil { return BadRequest(err) } snapshot := func(op *operation) error { args := db.ContainerArgs{ Project: c.Project(), Architecture: c.Architecture(), Config: c.LocalConfig(), Ctype: db.CTypeSnapshot, Devices: c.LocalDevices(), Ephemeral: c.IsEphemeral(), Name: fullName, Profiles: c.Profiles(), Stateful: req.Stateful, ExpiryDate: expiry, }