Skip to content

Commit

Permalink
feat: add zfs-service to zfs extension (unmount, encryption)
Browse files Browse the repository at this point in the history
This patch adds a new service to the zfs extension (`zfs-service`) that
handles pool import and unmount. These operations are tied to the
service lifecycle: the service imports all pools when it starts, waits
for an exit signal, then unmounts all pools before exiting.

As a subtle additional benefit, the service passes the `-l` flag to
`zpool-import`[^1], which instructs it to request encryption keys for
all encrypted datasets. Using the zfs `keylocation`[^2] property and
Talos secure boot and TPM disk encryption, a ZFS encryption key file can
be safely stored on the EPHEMERAL partition to import encrypted datasets
at boot. Alternatively, a key can be stored on an https server.

[^1]: https://openzfs.github.io/openzfs-docs/man/master/8/zpool-import.8.html
[^2]: https://openzfs.github.io/openzfs-docs/man/master/7/zfsprops.7.html#keylocation

Signed-off-by: Jean-Francois Roy <[email protected]>
Signed-off-by: Noel Georgi <[email protected]>
  • Loading branch information
jfroy authored and frezbo committed Nov 6, 2024
1 parent 966aaed commit b276718
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 13 deletions.
2 changes: 1 addition & 1 deletion storage/zfs/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
version: "$VERSION"
author: Andrei Kvapil, Aenix
description: |
This system extension provides kernel module driver for ZFS built against a specific Talos version.
This system extension provides the ZFS kernel module, the ZFS utilities, and a service to import all ZFS pools on start and unmount all pools on stop.
compatibility:
talos:
version: ">= v1.6.0"
9 changes: 4 additions & 5 deletions storage/zfs/pkg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,18 @@ dependencies:
- stage: libtirpc-zfs
- stage: zlib-zfs
- stage: zfs-tools
- stage: zfs-service
steps:
- prepare:
- |
sed -i 's#$VERSION#{{ .VERSION }}#' /pkg/manifest.yaml
- install:
- |
mkdir -p /rootfs/lib/modules /rootfs/usr/local/lib/containers/zpool-importer
cp -R /lib/modules/* /rootfs/lib/modules
mkdir -p /rootfs/lib/modules
cp -R /lib/modules/* /rootfs/lib/modules/
- |
mkdir -p /rootfs/usr/local/etc/containers
cp /pkg/zpool-importer.yaml /rootfs/usr/local/etc/containers/zpool-importer.yaml
cp /pkg/zfs-service.yaml /rootfs/usr/local/etc/containers/
test:
- |
mkdir -p /extensions-validator-rootfs
Expand Down
18 changes: 11 additions & 7 deletions storage/zfs/zpool-importer.yaml → storage/zfs/zfs-service.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
name: zpool-importer
name: zfs-service
depends:
- service: udevd
- service: cri
- path: /dev/zfs
container:
security:
rootfsPropagation: shared
entrypoint: /usr/local/sbin/zpool
args:
- import
- -fa
entrypoint: /zfs-service
mounts:
# ld-musl-x86_64.so.1
- source: /lib
Expand Down Expand Up @@ -44,11 +39,20 @@ container:
- rshared
- rbind
- rw
- source: /run
destination: /run
type: bind
options:
- rshared
- rbind
- rw
- source: /var
destination: /var
type: bind
options:
- rshared
- rbind
- rw
security:
rootfsPropagation: shared
restart: untilSuccess
5 changes: 5 additions & 0 deletions storage/zfs/zfs-service/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module zfs-service

go 1.22

require golang.org/x/sys v0.24.0
2 changes: 2 additions & 0 deletions storage/zfs/zfs-service/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
34 changes: 34 additions & 0 deletions storage/zfs/zfs-service/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package main

import (
"log"
"os"
"os/exec"
"os/signal"

"golang.org/x/sys/unix"
)

func main() {
cmd := exec.Command("/usr/local/sbin/zpool", "import", "-fal")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
log.Fatalf("zfs-service: zpool import error: %v\n", err)
}

ch := make(chan os.Signal, 1)
signal.Notify(ch, unix.SIGINT, unix.SIGTERM)
<-ch

cmd = exec.Command("/usr/local/sbin/zfs", "unmount", "-au")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
log.Fatalf("zfs-service: zfs unmount error: %v\n", err)
}
}
21 changes: 21 additions & 0 deletions storage/zfs/zfs-service/pkg.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: zfs-service
variant: scratch
shell: /toolchain/bin/bash
dependencies:
- stage: base
steps:
- cachePaths:
- /.cache/go-build
- /go/pkg
build:
- |
export PATH=${PATH}:${TOOLCHAIN}/go/bin
cp -r /pkg/* .
CGO_ENABLED=0 go build -ldflags "-s -w" -trimpath -o zfs-service main.go
install:
- |
mkdir -p /rootfs/usr/local/lib/containers/zfs-service
cp zfs-service /rootfs/usr/local/lib/containers/zfs-service/
finalize:
- from: /rootfs
to: /rootfs

0 comments on commit b276718

Please sign in to comment.