mirror of
https://github.com/ceph/go-ceph
synced 2025-02-09 14:57:41 +00:00
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:
parent
a120c62623
commit
caac65de71
@ -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")
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user