Classic confinement for wal-g

Hi.

WAL-G is a tool to backup databases and archive database write ahead to cloud storage, providing Point in Time Recovery. It is stable for PostgreSQL and with beta support for MySQL, MariaDB, MongoDB, and Redis. My snap only builds for PostgreSQL at the moment. It is the successor to wal-e, which is already snapped. And similarly to wal-e, requires classic confinement. The tool is invoked by PostgreSQL when WAL files need to be shipped off the server, and these are located at an arbitrary location on the filesystem. WAL-G is also used to backup and restore the PostgreSQL database files themselves. By default this is all under /var/lib/postgresql in a standard Debian install, but it is very common for this to be changed to multiple other disk partitions for performance and scaling reasons.

Hi @stub :slight_smile:

It is true that wal-e was granted classic confinement, but that was granted more than 3.5 years ago before lots of snapd improvements and before many of our review processes were in place, so we should not consider wal-e’s classic granting for this request.

You stated: “The tool is invoked by PostgreSQL when WAL files need to be shipped off the server, and these are located at an arbitrary location on the filesystem. WAL-G is also used to backup and restore the PostgreSQL database files themselves. By default this is all under /var/lib/postgresql in a standard Debian install, but it is very common for this to be changed to multiple other disk partitions for performance and scaling reasons.

Typically, access to arbitrary files on the system is not a supported use case for classic, but let’s discuss wal-g’s needs in more detail.

  • the tool is invoked by PostgreSQL when WAL files need to be shipped off the server” - postgresql would be able to launch the snap, and wal-g could plugs ‘network’ to ship files off the server
  • these are located at an arbitrary location on the filesystem” - normally we would recommend that the snap plugs ‘home’ and ‘removable-media’, but in wal-g’s case, I suspect home is uninteresting. ‘removable-media’ allows access to both /media and /mnt though, so that is potentially interesting. Does wal-g need only read access? If so, I suspect the system-backup interface would work very well for you since it gives read access to all of the host filesystem, via /var/lib/snapd/hostfs (with a few exceptions like /dev, /proc and /sys).
  • WAL-G is also used to backup and restore the PostgreSQL database files themselves” - as mentioned, ‘system-backup’ should be able to be used for backup, but you’d need to use something like ‘system-files’ for restore. You mentioned that /var/lib/postgresql is the default location, so you could use system-files with write: [ /var/lib/snapd/hostfs/var/lib/postgresql ]. What are other typical locations (eg, from best practices, upstream documentation, etc) that should also be considered? Do WAL files always have a particular extension?

WAL-G needs both read and write access. For log shipping, on the primary server it reads them, and on standby servers it is writing them. For database backups, read when making backups and write when restoring them.

For PostgreSQL, WAL files do not have file extensions. Neither do the database files. I don’t know about the other databases (which the snap does not currently support).

There are no upstream best practices, as this is platform dependent. /var/lib/postgresql is just the Debian default, and really only suitable for toy databases that fit on the root filesystem. Internally, we tend to use subdirectories under external mounts /srv, /srv2 etc. So the Juju charm for example replaces /var/lib/postgresql/$ver/main with a symlink to /srv/pgdata/main, where the main database files are stored on the Juju provided mount. But locking down these paths would not be useful, even we limited use to Juju charm deployments that I know will follow these conventions, as during manual disaster recovery we will be restoring to wherever we happen to have available disk space. And again, I have no idea about the other databases that WAL-G supports.

Whilst wal-g may be used in various ways such that strict confinement would be difficult, would it be possible for the wal-g snap to establish certain use-case patterns such that strict confinement would be achievable - ie. would it make sense to advise users to bind-mount their databases folders under say /var/snap/wal-g/common so that it has the required access without any additional access required?

A bind mount would be technically possible, but would involve a fairly invasive reconfiguration and downtime of the PostgreSQL database to make it feed the correct paths to WAL-G. The snap distribution would be the worst option (over say a deb package in a PPA, or running ‘go install’).

This is an interesting point and an area of improvement for snaps on server installations. We currently have removable-media for /media and /mnt, but nothing for /srv, let alone arbitrary accesses. We have /var/lib/snapd/hostfs so, in theory, we could allow system-files to /var/lib/snapd/hostfs, but that is really no different than allowing classic.

We could introduce an interface or a methodology that allows access to user-defined locations in hostfs so that the admin could tell snapd to expand the access for a particular snap. It is easy to imagine that the future prompting word could be utilized for this sort of thing as well.

Since we granted classic for wal-e to this publisher and the publisher is vetted and the requirements are understood, we could grant classic in this case, but, as mentioned, access to arbitrary files on the system is not a supported use case for classic. @pedronis, would you like to weigh in?

Before we say yes or no though, let’s explore the system-files approach. Eg, can you use:

plugs:
  hostfs-var-lib-postgresql:
    interface: system-files
    write:
    - /var/lib/snapd/hostfs/var/lib/postgresql
  hostfs-srv:
    interface: system-files
    write:
    - /var/lib/snapd/hostfs/srv
    - /var/lib/snapd/hostfs/srv0
    - /var/lib/snapd/hostfs/srv1
    - /var/lib/snapd/hostfs/srv2
    - /var/lib/snapd/hostfs/srv3
    - /var/lib/snapd/hostfs/srv4
    - /var/lib/snapd/hostfs/srv5
    - /var/lib/snapd/hostfs/srv6
    - /var/lib/snapd/hostfs/srv7

In this manner, users can configure wal-g like so:

$ sudo snap connect wal-g:hostfs-var-lib-postgresql

or

$ sudo snap connect wal-g:hostfs-srv

and you can update the snap for additional use cases as needed. This provides meaningful isolation with a path forward for new use cases.

@stub Can you please comment regarding @jdstrand’s suggestion above?

The user being able to specify post-install an arbitrary list of paths a confined snap can write too would solve my use cases. Me being able to specify a fixed list of paths at snap build time does not.

I think the requirements are understood, but I’d like to hear @pedronis opinion as well. Thanks for being patient while we work through the best path forward.

This has been in my queue, but I don’t think I’ll get to it before next week.

Hello @pedronis. Did you have time to review this request?

As @jdstrand mentioned in the future, also because of prompting support that we want to have, we will need ways to open and record accesses that don’t correspond directly to the static information in a snap’s plugs. These mechanisms will need to be transparent so somehow these accesses will have to be associated with plugs or slots somehow, unless we introduce new concepts. But none of this is available right now.

So in the interim I think we can grant classic, with the understanding that when such mechanisms are available we would very much prefer for the snap to go back to strict and using the mechanisms with a configuration step of some kind to set up the needed accesses.

Yeah, it occurred to me that this sort of thing is very much like prompting (it could be thought of as precaching the prompt db).

The requirements are understood. @stub indicated that some method of adjusting policy would be great if it were available. I’ve vetted the publisher. Granting classic. This is now live.

@stub - thank you for your patience!