mirror of
https://github.com/ceph/go-ceph
synced 2025-01-18 12:10:47 +00:00
cephfs/admin: API for quiesceing io on a cephfs
cephfs has new quiesce feature for cephfs volume. This change add the feature to go-ceph. Signed-off-by: Manish <myathnal@redhat.com>
This commit is contained in:
parent
9a3796f853
commit
755481f8c2
135
cephfs/admin/fs_quiesce.go
Normal file
135
cephfs/admin/fs_quiesce.go
Normal file
@ -0,0 +1,135 @@
|
||||
//go:build ceph_preview
|
||||
|
||||
package admin
|
||||
|
||||
import "fmt"
|
||||
|
||||
// fixedPointFloat is a custom type that implements the MarshalJSON interface.
|
||||
// This is used to format float64 values to two decimal places.
|
||||
// By default these get converted to integers in the JSON output and
|
||||
// fail the command.
|
||||
type fixedPointFloat float64
|
||||
|
||||
// MarshalJSON provides a custom implementation for the JSON marshalling
|
||||
// of fixedPointFloat. It formats the float to two decimal places.
|
||||
func (fpf fixedPointFloat) MarshalJSON() ([]byte, error) {
|
||||
return []byte(fmt.Sprintf("%.2f", float64(fpf))), nil
|
||||
}
|
||||
|
||||
// fSQuiesceFields is the internal type used to create JSON for ceph.
|
||||
// See FSQuiesceOptions for the type that users of the library
|
||||
// interact with.
|
||||
type fSQuiesceFields struct {
|
||||
Prefix string `json:"prefix"`
|
||||
VolName string `json:"vol_name"`
|
||||
GroupName string `json:"group_name,omitempty"`
|
||||
Members []string `json:"members,omitempty"`
|
||||
SetId string `json:"set_id,omitempty"`
|
||||
Timeout fixedPointFloat `json:"timeout,omitempty"`
|
||||
Expiration fixedPointFloat `json:"expiration,omitempty"`
|
||||
AwaitFor fixedPointFloat `json:"await_for,omitempty"`
|
||||
Await bool `json:"await,omitempty"`
|
||||
IfVersion int `json:"if_version,omitempty"`
|
||||
Include bool `json:"include,omitempty"`
|
||||
Exclude bool `json:"exclude,omitempty"`
|
||||
Reset bool `json:"reset,omitempty"`
|
||||
Release bool `json:"release,omitempty"`
|
||||
Query bool `json:"query,omitempty"`
|
||||
All bool `json:"all,omitempty"`
|
||||
Cancel bool `json:"cancel,omitempty"`
|
||||
}
|
||||
|
||||
// FSQuiesceOptions are used to specify optional, non-identifying, values
|
||||
// to be used when quiescing a cephfs volume.
|
||||
type FSQuiesceOptions struct {
|
||||
Timeout float64
|
||||
Expiration float64
|
||||
AwaitFor float64
|
||||
Await bool
|
||||
IfVersion int
|
||||
Include bool
|
||||
Exclude bool
|
||||
Reset bool
|
||||
Release bool
|
||||
Query bool
|
||||
All bool
|
||||
Cancel bool
|
||||
}
|
||||
|
||||
// toFields is used to convert the FSQuiesceOptions to the internal
|
||||
// fSQuiesceFields type.
|
||||
func (o *FSQuiesceOptions) toFields(volume, group string, subvolumes []string, setId string) *fSQuiesceFields {
|
||||
return &fSQuiesceFields{
|
||||
Prefix: "fs quiesce",
|
||||
VolName: volume,
|
||||
GroupName: group,
|
||||
Members: subvolumes,
|
||||
SetId: setId,
|
||||
Timeout: fixedPointFloat(o.Timeout),
|
||||
Expiration: fixedPointFloat(o.Expiration),
|
||||
AwaitFor: fixedPointFloat(o.AwaitFor),
|
||||
Await: o.Await,
|
||||
IfVersion: o.IfVersion,
|
||||
Include: o.Include,
|
||||
Exclude: o.Exclude,
|
||||
Reset: o.Reset,
|
||||
Release: o.Release,
|
||||
Query: o.Query,
|
||||
All: o.All,
|
||||
Cancel: o.Cancel,
|
||||
}
|
||||
}
|
||||
|
||||
// QuiesceState is used to report the state of a quiesced fs volume.
|
||||
type QuiesceState struct {
|
||||
Name string `json:"name"`
|
||||
Age float64 `json:"age"`
|
||||
}
|
||||
|
||||
// QuiesceInfoMember is used to report the state of a quiesced fs volume.
|
||||
// This is part of sets members object array in the json.
|
||||
type QuiesceInfoMember struct {
|
||||
Excluded bool `json:"excluded"`
|
||||
State QuiesceState `json:"state"`
|
||||
}
|
||||
|
||||
// QuiesceInfo reports various informational values about a quiesced volume.
|
||||
// This is returned as sets object array in the json.
|
||||
type QuiesceInfo struct {
|
||||
Version int `json:"version"`
|
||||
AgeRef float64 `json:"age_ref"`
|
||||
State QuiesceState `json:"state"`
|
||||
Timeout float64 `json:"timeout"`
|
||||
Expiration float64 `json:"expiration"`
|
||||
Members map[string]QuiesceInfoMember `json:"members"`
|
||||
}
|
||||
|
||||
// FSQuiesceInfo reports various informational values about quiesced volumes.
|
||||
type FSQuiesceInfo struct {
|
||||
Epoch int `json:"epoch"`
|
||||
SetVersion int `json:"set_version"`
|
||||
Sets map[string]QuiesceInfo `json:"sets"`
|
||||
}
|
||||
|
||||
// parseFSQuiesceInfo is used to parse the response from the quiesce command. It returns a FSQuiesceInfo object.
|
||||
func parseFSQuiesceInfo(res response) (*FSQuiesceInfo, error) {
|
||||
var info FSQuiesceInfo
|
||||
if err := res.NoStatus().Unmarshal(&info).End(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// FSQuiesce will quiesce the specified subvolumes in a volume.
|
||||
// Quiescing a fs will prevent new writes to the subvolumes.
|
||||
// Similar To:
|
||||
//
|
||||
// ceph fs quiesce <volume>
|
||||
func (fsa *FSAdmin) FSQuiesce(volume, group string, subvolumes []string, setId string, o *FSQuiesceOptions) (*FSQuiesceInfo, error) {
|
||||
if o == nil {
|
||||
o = &FSQuiesceOptions{}
|
||||
}
|
||||
f := o.toFields(volume, group, subvolumes, setId)
|
||||
|
||||
return parseFSQuiesceInfo(fsa.marshalMgrCommand(f))
|
||||
}
|
25
cephfs/admin/fs_quiesce_reef_test.go
Normal file
25
cephfs/admin/fs_quiesce_reef_test.go
Normal file
@ -0,0 +1,25 @@
|
||||
//go:build (nautilus || octopus || pacific || quincy || reef || squid || ceph_pre_squid) && ceph_preview
|
||||
|
||||
package admin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFSQuiesce(t *testing.T) {
|
||||
fsa := getFSAdmin(t)
|
||||
volume := "cephfs"
|
||||
group := NoGroup
|
||||
fsa.CreateSubVolume(volume, group, "quiesceMe", nil)
|
||||
defer func() {
|
||||
err := fsa.RemoveSubVolume(volume, group, "quiesceMe")
|
||||
assert.NoError(t, err)
|
||||
}()
|
||||
ret, err := fsa.FSQuiesce(volume, group, []string{"quiesceMe"}, "", nil)
|
||||
assert.Nil(t, ret)
|
||||
var notImplemented NotImplementedError
|
||||
assert.True(t, errors.As(err, ¬Implemented))
|
||||
}
|
51
cephfs/admin/fs_quiesce_test.go
Normal file
51
cephfs/admin/fs_quiesce_test.go
Normal file
@ -0,0 +1,51 @@
|
||||
//go:build !(nautilus || octopus || pacific || quincy || reef || squid || ceph_pre_squid) && ceph_preview
|
||||
|
||||
package admin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFSQuiesce(t *testing.T) {
|
||||
fsa := getFSAdmin(t)
|
||||
volume := "cephfs"
|
||||
group := NoGroup
|
||||
subvol := "quiesceMe"
|
||||
fsa.CreateSubVolume(volume, group, subvol, nil)
|
||||
defer func() {
|
||||
err := fsa.RemoveSubVolume(volume, group, subvol)
|
||||
assert.NoError(t, err)
|
||||
}()
|
||||
ret, err := fsa.FSQuiesce(volume, group, []string{subvol}, "", nil)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
for _, val := range ret.Sets {
|
||||
assert.Equal(t, 0.0, val.Timeout)
|
||||
}
|
||||
o := &FSQuiesceOptions{}
|
||||
o.Timeout = 10.7
|
||||
ret, err = fsa.FSQuiesce(volume, group, []string{subvol}, "", o)
|
||||
assert.NoError(t, err)
|
||||
for _, val := range ret.Sets {
|
||||
assert.Equal(t, 10.7, val.Timeout)
|
||||
}
|
||||
|
||||
o.Expiration = 15.2
|
||||
ret, err = fsa.FSQuiesce(volume, group, []string{subvol}, "", o)
|
||||
assert.NoError(t, err)
|
||||
for _, val := range ret.Sets {
|
||||
assert.Equal(t, 15.2, val.Expiration)
|
||||
assert.Equal(t, 10.7, val.Timeout)
|
||||
}
|
||||
|
||||
o.Expiration = 15
|
||||
ret, err = fsa.FSQuiesce(volume, group, []string{subvol}, "", o)
|
||||
assert.NoError(t, err)
|
||||
for _, val := range ret.Sets {
|
||||
assert.Equal(t, 15.0, val.Expiration)
|
||||
assert.Equal(t, 10.7, val.Timeout)
|
||||
}
|
||||
}
|
@ -614,7 +614,14 @@
|
||||
}
|
||||
],
|
||||
"deprecated_api": [],
|
||||
"preview_api": []
|
||||
"preview_api": [
|
||||
{
|
||||
"name": "FSAdmin.FSQuiesce",
|
||||
"comment": "FSQuiesce will quiesce the specified subvolumes in a volume.\nQuiescing a fs will prevent new writes to the subvolumes.\nSimilar To:\n\nceph fs quiesce <volume>\n",
|
||||
"added_in_version": "$NEXT_RELEASE",
|
||||
"expected_stable_version": "$NEXT_RELEASE_STABLE"
|
||||
}
|
||||
]
|
||||
},
|
||||
"rados": {
|
||||
"stable_api": [
|
||||
|
@ -8,7 +8,11 @@ No Preview/Deprecated APIs found. All APIs are considered stable.
|
||||
|
||||
## Package: cephfs/admin
|
||||
|
||||
No Preview/Deprecated APIs found. All APIs are considered stable.
|
||||
### Preview APIs
|
||||
|
||||
Name | Added in Version | Expected Stable Version |
|
||||
---- | ---------------- | ----------------------- |
|
||||
FSAdmin.FSQuiesce | $NEXT_RELEASE | $NEXT_RELEASE_STABLE |
|
||||
|
||||
## Package: rados
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user