mirror of
https://github.com/ceph/go-ceph
synced 2024-12-25 15:42:30 +00:00
cephfs admin: flexibly decode the MDSVersion field in volume status
It appears the JSON being returned from `ceph fs status` has changed. The field returning the mds version was previously "just" a string. Now its a more complex thing. This of course breaks the old version of the go code which is statically typed to expect a string. In order not to break backwards compatibility we replace the object used for parsing the JSON with a private object that has a custom unmarshaller function for the mds version field. If it sees the string it uses the string. Otherwise, it looks for this new structure and, if possible, extracts the version string from the first item. Signed-off-by: John Mulligan <jmulligan@redhat.com>
This commit is contained in:
parent
ac1401b4e2
commit
ae44f69791
@ -2,6 +2,7 @@ package admin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -114,8 +115,40 @@ type VolumeStatus struct {
|
||||
Pools []VolumePool `json:"pools"`
|
||||
}
|
||||
|
||||
func parseVolumeStatus(res response) (*VolumeStatus, error) {
|
||||
var vs VolumeStatus
|
||||
type mdsVersionField struct {
|
||||
Version string
|
||||
Items []struct {
|
||||
Version string `json:"version"`
|
||||
}
|
||||
}
|
||||
|
||||
func (m *mdsVersionField) UnmarshalJSON(data []byte) (err error) {
|
||||
if err = json.Unmarshal(data, &m.Version); err == nil {
|
||||
return
|
||||
}
|
||||
return json.Unmarshal(data, &m.Items)
|
||||
}
|
||||
|
||||
// volumeStatusResponse deals with the changing output of the mgr
|
||||
// api json
|
||||
type volumeStatusResponse struct {
|
||||
Pools []VolumePool `json:"pools"`
|
||||
MDSVersion mdsVersionField `json:"mds_version"`
|
||||
}
|
||||
|
||||
func (v *volumeStatusResponse) volumeStatus() *VolumeStatus {
|
||||
vstatus := &VolumeStatus{}
|
||||
vstatus.Pools = v.Pools
|
||||
if v.MDSVersion.Version != "" {
|
||||
vstatus.MDSVersion = v.MDSVersion.Version
|
||||
} else if len(v.MDSVersion.Items) > 0 {
|
||||
vstatus.MDSVersion = v.MDSVersion.Items[0].Version
|
||||
}
|
||||
return vstatus
|
||||
}
|
||||
|
||||
func parseVolumeStatus(res response) (*volumeStatusResponse, error) {
|
||||
var vs volumeStatusResponse
|
||||
res = res.NoStatus()
|
||||
if !res.Ok() {
|
||||
return nil, res.End()
|
||||
@ -142,5 +175,9 @@ func (fsa *FSAdmin) VolumeStatus(name string) (*VolumeStatus, error) {
|
||||
"prefix": "fs status",
|
||||
"format": "json",
|
||||
})
|
||||
return parseVolumeStatus(res)
|
||||
v, err := parseVolumeStatus(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v.volumeStatus(), nil
|
||||
}
|
||||
|
@ -208,6 +208,10 @@ var sampleVolumeStatus1 = []byte(`
|
||||
}
|
||||
`)
|
||||
|
||||
var sampleVolumeStatusQ = []byte(`
|
||||
{"clients": [{"clients": 3, "fs": "cephfs"}], "mds_version": [{"daemon": ["Z"], "version": "ceph version 17.1.0 (c675060073a05d40ef404d5921c81178a52af6e0) quincy (dev)"}], "mdsmap": [{"caps": 11, "dirs": 26, "dns": 49, "inos": 30, "name": "Z", "rank": 0, "rate": 0, "state": "active"}], "pools": [{"avail": 1018405056, "id": 2, "name": "cephfs_metadata", "type": "metadata", "used": 467690}, {"avail": 1018405056, "id": 1, "name": "cephfs_data", "type": "data", "used": 8}]}
|
||||
`)
|
||||
|
||||
var sampleVolumeStatusTextJunk = []byte(`cephfs - 2 clients
|
||||
======
|
||||
+------+--------+-----+---------------+-------+-------+
|
||||
@ -244,8 +248,9 @@ func TestParseVolumeStatus(t *testing.T) {
|
||||
assert.Error(t, err)
|
||||
})
|
||||
t.Run("ok", func(t *testing.T) {
|
||||
s, err := parseVolumeStatus(R(sampleVolumeStatus1, "", nil))
|
||||
v, err := parseVolumeStatus(R(sampleVolumeStatus1, "", nil))
|
||||
assert.NoError(t, err)
|
||||
s := v.volumeStatus()
|
||||
if assert.NotNil(t, s) {
|
||||
assert.Contains(t, s.MDSVersion, "ceph version 15.2.4")
|
||||
assert.Contains(t, s.MDSVersion, "octopus")
|
||||
@ -258,6 +263,15 @@ func TestParseVolumeStatus(t *testing.T) {
|
||||
assert.True(t, errors.As(err, ¬Impl))
|
||||
}
|
||||
})
|
||||
t.Run("quincy", func(t *testing.T) {
|
||||
v, err := parseVolumeStatus(R(sampleVolumeStatusQ, "", nil))
|
||||
assert.NoError(t, err)
|
||||
s := v.volumeStatus()
|
||||
if assert.NotNil(t, s) {
|
||||
assert.Contains(t, s.MDSVersion, "ceph version 17.1.0")
|
||||
assert.Contains(t, s.MDSVersion, "quincy")
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user