Add resize functions

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2022-05-10 10:43:48 +02:00 committed by Daniel Weiße
parent 2b80341d99
commit 6b3d45dd09
5 changed files with 298 additions and 137 deletions

View file

@ -22,27 +22,41 @@ var testDEK = []byte{
}
type stubCryptDevice struct {
initErr error
activateErr error
deactivateErr error
formatErr error
loadErr error
wipeErr error
deviceName string
initErr error
initByNameErr error
activateErr error
activatePassErr error
deactivateErr error
formatErr error
loadErr error
keySlotAddCalled bool
keySlotAddErr error
wipeErr error
resizeErr error
}
func (c *stubCryptDevice) Init(devicePath string) error {
func (c *stubCryptDevice) Init(string) error {
return c.initErr
}
func (c *stubCryptDevice) ActivateByVolumeKey(deviceName, volumeKey string, volumeKeySize, flags int) error {
func (c *stubCryptDevice) InitByName(string) error {
return c.initByNameErr
}
func (c *stubCryptDevice) ActivateByVolumeKey(string, string, int, int) error {
return c.activateErr
}
func (c *stubCryptDevice) Deactivate(deviceName string) error {
func (c *stubCryptDevice) ActivateByPassphrase(string, int, string, int) error {
return c.activatePassErr
}
func (c *stubCryptDevice) Deactivate(string) error {
return c.deactivateErr
}
func (c *stubCryptDevice) Format(deviceType cryptsetup.DeviceType, genericParams cryptsetup.GenericParams) error {
func (c *stubCryptDevice) Format(cryptsetup.DeviceType, cryptsetup.GenericParams) error {
return c.formatErr
}
@ -54,10 +68,19 @@ func (c *stubCryptDevice) Load(cryptsetup.DeviceType) error {
return c.loadErr
}
func (c *stubCryptDevice) Wipe(devicePath string, pattern int, offset, length uint64, wipeBlockSize int, flags int, progress func(size, offset uint64) int) error {
func (c *stubCryptDevice) KeyslotAddByVolumeKey(int, string, string) error {
c.keySlotAddCalled = true
return c.keySlotAddErr
}
func (c *stubCryptDevice) Wipe(string, int, uint64, uint64, int, int, func(size, offset uint64) int) error {
return c.wipeErr
}
func (c *stubCryptDevice) Resize(string, uint64) error {
return c.resizeErr
}
func TestCloseCryptDevice(t *testing.T) {
testCases := map[string]struct {
mapper *stubCryptDevice
@ -67,16 +90,12 @@ func TestCloseCryptDevice(t *testing.T) {
mapper: &stubCryptDevice{},
wantErr: false,
},
"error on Init": {
mapper: &stubCryptDevice{
initErr: errors.New("error"),
},
"error on InitByName": {
mapper: &stubCryptDevice{initByNameErr: errors.New("error")},
wantErr: true,
},
"error on Deactivate": {
mapper: &stubCryptDevice{
deactivateErr: errors.New("error"),
},
mapper: &stubCryptDevice{deactivateErr: errors.New("error")},
wantErr: true,
},
}
@ -103,113 +122,116 @@ func TestOpenCryptDevice(t *testing.T) {
someErr := errors.New("error")
testCases := map[string]struct {
source string
volumeID string
dek string
integrity bool
mapper *stubCryptDevice
diskInfo func(disk string) (string, error)
wantErr bool
source string
volumeID string
passphrase string
integrity bool
mapper *stubCryptDevice
diskInfo func(disk string) (string, error)
wantErr bool
}{
"success with Load": {
source: "/dev/some-device",
volumeID: "volume0",
dek: string(testDEK),
mapper: &stubCryptDevice{},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: false,
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(testDEK),
mapper: &stubCryptDevice{},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: false,
},
"success with error on Load": {
source: "/dev/some-device",
volumeID: "volume0",
dek: string(testDEK),
mapper: &stubCryptDevice{loadErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: false,
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(testDEK),
mapper: &stubCryptDevice{loadErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: false,
},
"success with integrity": {
source: "/dev/some-device",
volumeID: "volume0",
dek: string(append(testDEK, testDEK[:32]...)),
integrity: true,
mapper: &stubCryptDevice{loadErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: false,
},
"incorrect key size": {
source: "/dev/some-device",
volumeID: "volume0",
dek: "short",
mapper: &stubCryptDevice{},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(append(testDEK, testDEK[:32]...)),
integrity: true,
mapper: &stubCryptDevice{loadErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: false,
},
"error on Init": {
source: "/dev/some-device",
volumeID: "volume0",
dek: string(testDEK),
mapper: &stubCryptDevice{initErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(testDEK),
mapper: &stubCryptDevice{initErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
},
"error on Format": {
source: "/dev/some-device",
volumeID: "volume0",
dek: string(testDEK),
mapper: &stubCryptDevice{loadErr: someErr, formatErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(testDEK),
mapper: &stubCryptDevice{loadErr: someErr, formatErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
},
"error on Activate": {
source: "/dev/some-device",
volumeID: "volume0",
dek: string(testDEK),
mapper: &stubCryptDevice{activateErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(testDEK),
mapper: &stubCryptDevice{activatePassErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
},
"error on diskInfo": {
source: "/dev/some-device",
volumeID: "volume0",
dek: string(testDEK),
mapper: &stubCryptDevice{loadErr: someErr},
diskInfo: func(disk string) (string, error) { return "", someErr },
wantErr: true,
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(testDEK),
mapper: &stubCryptDevice{loadErr: someErr},
diskInfo: func(disk string) (string, error) { return "", someErr },
wantErr: true,
},
"disk is already formatted": {
source: "/dev/some-device",
volumeID: "volume0",
dek: string(testDEK),
mapper: &stubCryptDevice{loadErr: someErr},
diskInfo: func(disk string) (string, error) { return "ext4", nil },
wantErr: true,
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(testDEK),
mapper: &stubCryptDevice{loadErr: someErr},
diskInfo: func(disk string) (string, error) { return "ext4", nil },
wantErr: true,
},
"error with integrity on wipe": {
source: "/dev/some-device",
volumeID: "volume0",
dek: string(append(testDEK, testDEK[:32]...)),
integrity: true,
mapper: &stubCryptDevice{loadErr: someErr, wipeErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(append(testDEK, testDEK[:32]...)),
integrity: true,
mapper: &stubCryptDevice{loadErr: someErr, wipeErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
},
"error with integrity on activate": {
source: "/dev/some-device",
volumeID: "volume0",
dek: string(append(testDEK, testDEK[:32]...)),
integrity: true,
mapper: &stubCryptDevice{loadErr: someErr, activateErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(append(testDEK, testDEK[:32]...)),
integrity: true,
mapper: &stubCryptDevice{loadErr: someErr, activateErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
},
"error with integrity on deactivate": {
source: "/dev/some-device",
volumeID: "volume0",
dek: string(append(testDEK, testDEK[:32]...)),
integrity: true,
mapper: &stubCryptDevice{loadErr: someErr, deactivateErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(append(testDEK, testDEK[:32]...)),
integrity: true,
mapper: &stubCryptDevice{loadErr: someErr, deactivateErr: someErr},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
},
"error on adding keyslot": {
source: "/dev/some-device",
volumeID: "volume0",
passphrase: string(testDEK),
mapper: &stubCryptDevice{
loadErr: someErr,
keySlotAddErr: someErr,
},
diskInfo: func(disk string) (string, error) { return "", nil },
wantErr: true,
},
}
@ -217,12 +239,18 @@ func TestOpenCryptDevice(t *testing.T) {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
out, err := openCryptDevice(tc.mapper, tc.source, tc.volumeID, tc.dek, tc.integrity, tc.diskInfo)
out, err := openCryptDevice(tc.mapper, tc.source, tc.volumeID, tc.passphrase, tc.integrity, tc.diskInfo)
if tc.wantErr {
assert.Error(err)
} else {
assert.NoError(err)
assert.Equal(cryptPrefix+tc.volumeID, out)
if tc.mapper.loadErr == nil {
assert.False(tc.mapper.keySlotAddCalled)
} else {
assert.True(tc.mapper.keySlotAddCalled)
}
}
})
}
@ -232,6 +260,60 @@ func TestOpenCryptDevice(t *testing.T) {
assert.NoError(t, err)
}
func TestResizeCryptDevice(t *testing.T) {
volumeID := "pvc-123"
someErr := errors.New("error")
testCases := map[string]struct {
volumeID string
device *stubCryptDevice
wantErr bool
}{
"success": {
volumeID: volumeID,
device: &stubCryptDevice{},
},
"InitByName fails": {
volumeID: volumeID,
device: &stubCryptDevice{initByNameErr: someErr},
wantErr: true,
},
"Load fails": {
volumeID: volumeID,
device: &stubCryptDevice{loadErr: someErr},
wantErr: true,
},
"Resize fails": {
volumeID: volumeID,
device: &stubCryptDevice{resizeErr: someErr},
wantErr: true,
},
"ActivateByPassphrase fails": {
volumeID: volumeID,
device: &stubCryptDevice{activatePassErr: someErr},
wantErr: true,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
mapper := &CryptMapper{
kms: kms.NewStaticKMS(),
mapper: tc.device,
}
res, err := mapper.ResizeCryptDevice(context.Background(), tc.volumeID)
if tc.wantErr {
assert.Error(err)
} else {
assert.NoError(err)
assert.Equal(cryptPrefix+tc.volumeID, res)
}
})
}
}
func TestIsIntegrityFS(t *testing.T) {
testCases := map[string]struct {
wantIntegrity bool