Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix resize luks volume #839

Merged
merged 1 commit into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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}
outscale-toa marked this conversation as resolved.
Show resolved Hide resolved
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
Loading