From 64a9ec9aba8f4334be9f8dda572ae7ddb1db40f1 Mon Sep 17 00:00:00 2001 From: Gabriele Belluardo Date: Mon, 9 Feb 2026 11:28:46 +0100 Subject: [PATCH 1/2] fix: update systemd-cryptsetup path for snap environments --- internal/luks2/activate.go | 25 ++++++++++++++++++++++--- internal/luks2/export_test.go | 6 +++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/internal/luks2/activate.go b/internal/luks2/activate.go index fac74641..2c7699b1 100644 --- a/internal/luks2/activate.go +++ b/internal/luks2/activate.go @@ -24,19 +24,37 @@ import ( "fmt" "os" "os/exec" + "path/filepath" + "sync" "github.com/snapcore/snapd/osutil" ) var ( - systemdCryptsetupPath = "/lib/systemd/systemd-cryptsetup" + systemdCryptsetupPath string + once sync.Once + + // getSystemdCryptsetupPath is internal and can be overridden by tests. + getSystemdCryptsetupPath = defaultSystemdCryptsetupPath ) +func defaultSystemdCryptsetupPath() string { + once.Do(func() { + systemdCryptsetupPath = "/lib/systemd/systemd-cryptsetup" + if snapPath := os.Getenv("SNAP"); snapPath != "" { + systemdCryptsetupPath = filepath.Join(snapPath, "usr/bin/systemd-cryptsetup") + } + }) + + return systemdCryptsetupPath +} + // Activate unlocks the LUKS device at sourceDevicePath using systemd-cryptsetup and creates a device // mapping with the supplied volumeName. The device is unlocked using the supplied key. The slot // arguments specifies which keyslot ID to use - set this to AnySlot to activate with any keyslot. func Activate(volumeName, sourceDevicePath string, key []byte, slot int) error { - cmd := exec.Command(systemdCryptsetupPath, + systemdCryptsetup := getSystemdCryptsetupPath() + cmd := exec.Command(systemdCryptsetup, // attach to /dev/mapper/ "attach", volumeName, sourceDevicePath, // read key from stdin @@ -56,7 +74,8 @@ func Activate(volumeName, sourceDevicePath string, key []byte, slot int) error { // Deactivate detaches the LUKS volume with the supplied name. func Deactivate(volumeName string) error { - cmd := exec.Command(systemdCryptsetupPath, "detach", volumeName) + systemdCryptsetup := getSystemdCryptsetupPath() + cmd := exec.Command(systemdCryptsetup, "detach", volumeName) cmd.Env = os.Environ() cmd.Env = append(cmd.Env, "SYSTEMD_LOG_TARGET=console") diff --git a/internal/luks2/export_test.go b/internal/luks2/export_test.go index cf20f15c..404b3451 100644 --- a/internal/luks2/export_test.go +++ b/internal/luks2/export_test.go @@ -73,10 +73,10 @@ func MockDataDeviceInfo(stMock *unix.Stat_t) (restore func()) { } func MockSystemdCryptsetupPath(path string) (restore func()) { - origSystemdCryptsetupPath := systemdCryptsetupPath - systemdCryptsetupPath = path + origFn := getSystemdCryptsetupPath + getSystemdCryptsetupPath = func() string { return path } return func() { - systemdCryptsetupPath = origSystemdCryptsetupPath + getSystemdCryptsetupPath = origFn } } From 286f7a0427a0fd834de307f0568fa5611c0e39a9 Mon Sep 17 00:00:00 2001 From: Gabriele Belluardo Date: Thu, 12 Feb 2026 11:57:38 +0100 Subject: [PATCH 2/2] refactor: simplify systemd-cryptsetup path retrieval for snap environments --- internal/luks2/activate.go | 16 +++++----------- internal/luks2/export_test.go | 4 ++-- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/internal/luks2/activate.go b/internal/luks2/activate.go index 2c7699b1..ece65f6d 100644 --- a/internal/luks2/activate.go +++ b/internal/luks2/activate.go @@ -25,28 +25,22 @@ import ( "os" "os/exec" "path/filepath" - "sync" "github.com/snapcore/snapd/osutil" ) var ( - systemdCryptsetupPath string - once sync.Once - // getSystemdCryptsetupPath is internal and can be overridden by tests. getSystemdCryptsetupPath = defaultSystemdCryptsetupPath ) func defaultSystemdCryptsetupPath() string { - once.Do(func() { - systemdCryptsetupPath = "/lib/systemd/systemd-cryptsetup" - if snapPath := os.Getenv("SNAP"); snapPath != "" { - systemdCryptsetupPath = filepath.Join(snapPath, "usr/bin/systemd-cryptsetup") - } - }) + root := "/" + if p := os.Getenv("SNAP"); p != "" { + root = p + } - return systemdCryptsetupPath + return filepath.Join(root, "lib", "systemd", "systemd-cryptsetup") } // Activate unlocks the LUKS device at sourceDevicePath using systemd-cryptsetup and creates a device diff --git a/internal/luks2/export_test.go b/internal/luks2/export_test.go index 404b3451..33abba7f 100644 --- a/internal/luks2/export_test.go +++ b/internal/luks2/export_test.go @@ -73,10 +73,10 @@ func MockDataDeviceInfo(stMock *unix.Stat_t) (restore func()) { } func MockSystemdCryptsetupPath(path string) (restore func()) { - origFn := getSystemdCryptsetupPath + orig := getSystemdCryptsetupPath getSystemdCryptsetupPath = func() string { return path } return func() { - getSystemdCryptsetupPath = origFn + getSystemdCryptsetupPath = orig } }