cephfs admin: add ResizeSubVolume and supporting types

Add a function for resizing a subvolume as well as types needed to
create the JSON command and parse the response JSON. The newSize
argument can be passed a numeric value (as a ByteCount) or the special
constant `Infinite` much like the ceph cli command. This is accomplished
using the interface type `NewSize`.

Signed-off-by: John Mulligan <jmulligan@redhat.com>
This commit is contained in:
John Mulligan 2020-08-05 13:43:26 -04:00 committed by John Mulligan
parent a120c62623
commit caac65de71
4 changed files with 113 additions and 0 deletions

View File

@ -10,3 +10,26 @@ const (
gibiByte = 1024 * mebiByte
tebiByte = 1024 * gibiByte
)
// newSizeValue returns a size value as a string, as needed by the subvolume
// resize command json.
func (bc ByteCount) newSizeValue() string {
return uint64String(uint64(bc))
}
// NewSize interface values can be used to change the size of a volume.
type NewSize interface {
newSizeValue() string
}
// specialSize is a custom non-numeric new size value.
type specialSize string
// newSizeValue for a specialSize returns the literal string.
func (s specialSize) newSizeValue() string {
return string(s)
}
// Infinite is a special NewSize value that can be used to clear size limits on
// a subvolume.
const Infinite = specialSize("infinite")

View File

@ -124,3 +124,10 @@ func modeString(m int, force bool) string {
}
return ""
}
// uint64String converts a uint64 to a string. Some of the ceph json commands
// can take a string or "int" (as a string). This is a common function for
// doing that conversion.
func uint64String(v uint64) string {
return strconv.FormatUint(uint64(v), 10)
}

View File

@ -93,3 +93,45 @@ func (fsa *FSAdmin) RemoveSubVolume(volume, group, name string) error {
}
return checkEmptyResponseExpected(fsa.marshalMgrCommand(m))
}
type subVolumeResizeFields struct {
Prefix string `json:"prefix"`
Format string `json:"format"`
VolName string `json:"vol_name"`
GroupName string `json:"group_name,omitempty"`
SubName string `json:"sub_name"`
NewSize string `json:"new_size"`
NoShrink bool `json:"no_shrink"`
}
// SubVolumeResizeResult reports the size values returned by the
// ResizeSubVolume function, as reported by Ceph.
type SubVolumeResizeResult struct {
BytesUsed ByteCount `json:"bytes_used"`
BytesQuota ByteCount `json:"bytes_quota"`
BytesPercent string `json:"bytes_pcent"`
}
// ResizeSubVolume will resize a CephFS subvolume. The newSize value may be a
// ByteCount or the special Infinite constant. Setting noShrink to true will
// prevent reducing the size of the volume below the current used size.
func (fsa *FSAdmin) ResizeSubVolume(
volume, group, name string,
newSize NewSize, noShrink bool) (*SubVolumeResizeResult, error) {
f := &subVolumeResizeFields{
Prefix: "fs subvolume resize",
Format: "json",
VolName: volume,
GroupName: group,
SubName: name,
NewSize: newSize.newSizeValue(),
NoShrink: noShrink,
}
var result []*SubVolumeResizeResult
r, s, err := fsa.marshalMgrCommand(f)
if err := unmarshalResponseJSON(r, s, err, &result); err != nil {
return nil, err
}
return result[0], nil
}

View File

@ -130,3 +130,44 @@ func TestRemoveSubVolume(t *testing.T) {
assert.Equal(t, []string{}, lsv)
}
}
func TestResizeSubVolume(t *testing.T) {
fsa := getFSAdmin(t)
volume := "cephfs"
group := "sizedGroup"
subname := "sizeMe1"
err := fsa.CreateSubVolumeGroup(volume, group, nil)
assert.NoError(t, err)
defer func() {
err := fsa.RemoveSubVolumeGroup(volume, group)
assert.NoError(t, err)
}()
svopts := &SubVolumeOptions{
Mode: 0777,
Size: 20 * gibiByte,
}
err = fsa.CreateSubVolume(volume, group, subname, svopts)
assert.NoError(t, err)
defer func() {
err := fsa.RemoveSubVolume(volume, group, subname)
assert.NoError(t, err)
}()
lsv, err := fsa.ListSubVolumes(volume, group)
assert.NoError(t, err)
assert.Contains(t, lsv, subname)
rr, err := fsa.ResizeSubVolume(volume, group, subname, 30*gibiByte, false)
assert.NoError(t, err)
assert.NotNil(t, rr)
rr, err = fsa.ResizeSubVolume(volume, group, subname, 10*gibiByte, true)
assert.NoError(t, err)
assert.NotNil(t, rr)
rr, err = fsa.ResizeSubVolume(volume, group, subname, Infinite, true)
assert.NoError(t, err)
assert.NotNil(t, rr)
}