Skip to content

Commit

Permalink
fix resize luks volume
Browse files Browse the repository at this point in the history
Signed-off-by: hanenMizouni <[email protected]>
  • Loading branch information
outscale-hmi committed Nov 12, 2024
1 parent 25009cd commit 3cfe1d4
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 22 deletions.
7 changes: 4 additions & 3 deletions examples/kubernetes/encryption/specs/storageclass.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ metadata:
provisioner: bsu.csi.outscale.com
volumeBindingMode: WaitForFirstConsumer
parameters:
encrypted: "true"
encrypted: 'true'
luks-cipher: aes-xts-plain64
type: io1
iopsPerGB: "50"
iopsPerGB: '50'
csi.storage.k8s.io/node-stage-secret-name: luks-key
csi.storage.k8s.io/node-stage-secret-namespace: encryption

csi.storage.k8s.io/node-expand-secret-name: luks-key
csi.storage.k8s.io/node-expand-secret-namespace: encryption
4 changes: 2 additions & 2 deletions pkg/driver/luks/luks.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ type LuksService interface {
CheckLuksPassphrase(devicePath string, passphrase string) bool
LuksOpen(devicePath string, encryptedDeviceName string, passphrase string) (bool, error)
IsLuksMapping(devicePath string) (bool, string, error)
LuksResize(deviceName string) error
LuksResize(deviceName string, passphrase string) error
LuksClose(deviceName string) error
}
}
11 changes: 9 additions & 2 deletions pkg/driver/luks_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,17 @@ func IsLuksMapping(exec k8sExec.Interface, devicePath string) (bool, string, err
return false, "", nil
}

func LuksResize(exec k8sExec.Interface, deviceName string) error {
func LuksResize(exec k8sExec.Interface, deviceName string, passphrase string) error {
cryptsetupArgs := []string{"--batch-mode", "resize", deviceName}
resizeCmd := exec.Command("cryptsetup", cryptsetupArgs...)
passwordReader := strings.NewReader(passphrase)
resizeCmd.SetStdin(passwordReader)

if out, err := resizeCmd.CombinedOutput(); err != nil {
return fmt.Errorf("unable to resize LUKS volume on device %s: %w, output: %s", deviceName, err, string(out))
}

return exec.Command("cryptsetup", cryptsetupArgs...).Run()
return nil
}

func LuksClose(mounter Mounter, encryptedDeviceName string) error {
Expand Down
37 changes: 32 additions & 5 deletions pkg/driver/luks_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package driver

import (
"fmt"
"io"
"strings"
"testing"

"github.com/golang/mock/gomock"
Expand Down Expand Up @@ -268,33 +270,58 @@ func TestIsLuksMapping(t *testing.T) {

func TestLuksResize(t *testing.T) {
mockCtl := gomock.NewController(t)
defer mockCtl.Finish()

devicePath := "fake_crypt"
passphrase := "fake_passphrase"

// Check normal success
mockCommand := mocks.NewMockInterface(mockCtl)
mockRun := mocks.NewMockCmd(mockCtl)

// Expect Command to be called with only four arguments, as passphrase is passed via stdin
mockCommand.EXPECT().Command(
gomock.Eq("cryptsetup"),
gomock.Eq("--batch-mode"),
gomock.Eq("resize"),
gomock.Eq(devicePath),
).Return(mockRun)
mockRun.EXPECT().Run().Return(nil)

assert.Equal(t, nil, LuksResize(mockCommand, devicePath))
// Expect SetStdin to be called with passphrase
mockRun.EXPECT().SetStdin(gomock.Any()).DoAndReturn(func(r io.Reader) {
// Check that the reader contains the passphrase
buf := new(strings.Builder)
io.Copy(buf, r)
assert.Equal(t, passphrase, buf.String())
})

// Expect CombinedOutput instead of Run
mockRun.EXPECT().CombinedOutput().Return([]byte(""), nil)

// Check failure
// Call LuksResize with the mock command and passphrase
assert.Equal(t, nil, LuksResize(mockCommand, devicePath, passphrase))

// Check failure case
mockCommand = mocks.NewMockInterface(mockCtl)
mockRun = mocks.NewMockCmd(mockCtl)

mockCommand.EXPECT().Command(
gomock.Eq("cryptsetup"),
gomock.Eq("--batch-mode"),
gomock.Eq("resize"),
gomock.Eq(devicePath),
).Return(mockRun)
mockRun.EXPECT().Run().Return(fmt.Errorf("Error"))

assert.NotEqual(t, nil, LuksResize(mockCommand, devicePath))
mockRun.EXPECT().SetStdin(gomock.Any()).DoAndReturn(func(r io.Reader) {
buf := new(strings.Builder)
io.Copy(buf, r)
assert.Equal(t, passphrase, buf.String())
})

// Expect CombinedOutput to return an error
mockRun.EXPECT().CombinedOutput().Return([]byte(""), fmt.Errorf("Error"))

assert.NotEqual(t, nil, LuksResize(mockCommand, devicePath, passphrase))
}

func TestLuksClose(t *testing.T) {
Expand Down
10 changes: 5 additions & 5 deletions pkg/driver/mocks/mock_mounter.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/driver/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ func (m *NodeMounter) IsLuksMapping(devicePath string) (bool, string, error) {
return IsLuksMapping(m, devicePath)
}

func (m *NodeMounter) LuksResize(deviceName string) error {
return LuksResize(m, deviceName)
func (m *NodeMounter) LuksResize(deviceName string, passphrase string) error {
return LuksResize(m, deviceName, passphrase)
}

func (m *NodeMounter) LuksClose(deviceName string) error {
Expand Down
10 changes: 8 additions & 2 deletions pkg/driver/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ package driver
import (
"context"
"fmt"
"golang.org/x/sys/unix"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"

"golang.org/x/sys/unix"

csi "github.com/container-storage-interface/spec/lib/go/csi"
"github.com/outscale-dev/osc-bsu-csi-driver/pkg/cloud"
"github.com/outscale-dev/osc-bsu-csi-driver/pkg/driver/internal"
Expand Down Expand Up @@ -386,7 +387,12 @@ func (d *nodeService) NodeExpandVolume(ctx context.Context, req *csi.NodeExpandV
}

if isLuksMapping {
if err := d.mounter.LuksResize(mappingName); err != nil {
passphrase, ok := req.Secrets[LuksPassphraseKey]
if !ok {
klog.Errorf("NodeStageVolume: no passphrase key has been provided in req.Secrets: %+v", req.Secrets)
return nil, status.Error(codes.InvalidArgument, "no passphrase key has been provided")
}
if err := d.mounter.LuksResize(mappingName, passphrase); err != nil {
return nil, status.Errorf(codes.Internal, "Could not resize Luks volume %q: %v", volumeID, err)
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/driver/sanity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ func (m *fakeMounter) IsLuksMapping(devicePath string) (bool, string, error) {
return false, "", nil
}

func (m *fakeMounter) LuksResize(deviceName string) error {
func (m *fakeMounter) LuksResize(deviceName string, passphrase string) error {
return nil
}

Expand Down

0 comments on commit 3cfe1d4

Please sign in to comment.