rebase: update go-ceph to v0.10.0

This commit updates the go-ceph to latest
release. More details about release at
https://github.com/ceph/go-ceph/releases/tag/v0.10.0

Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
Madhu Rajanna
2021-06-09 10:24:52 +05:30
committed by mergify[bot]
parent 17b0091cba
commit 5b7b5f1e3a
27 changed files with 1099 additions and 272 deletions

View File

@ -53,10 +53,10 @@ func (fsa *FSAdmin) CloneSubVolumeSnapshot(volume, group, subvolume, snapshot, n
}
func checkCloneResponse(res response) error {
if strings.HasSuffix(res.status, notProtectedSuffix) {
if strings.HasSuffix(res.Status(), notProtectedSuffix) {
return NotProtectedError{response: res}
}
return res.noData().End()
return res.NoData().End()
}
// CloneState is used to define constant values used to determine the state of
@ -94,7 +94,7 @@ type cloneStatusWrapper struct {
func parseCloneStatus(res response) (*CloneStatus, error) {
var status cloneStatusWrapper
if err := res.noStatus().unmarshal(&status).End(); err != nil {
if err := res.NoStatus().Unmarshal(&status).End(); err != nil {
return nil, err
}
return &status.Status, nil
@ -132,5 +132,5 @@ func (fsa *FSAdmin) CancelClone(volume, group, clone string) error {
if group != NoGroup {
m["group_name"] = group
}
return fsa.marshalMgrCommand(m).noData().End()
return fsa.marshalMgrCommand(m).NoData().End()
}

View File

@ -3,18 +3,16 @@
package admin
import (
"encoding/json"
"strconv"
ccom "github.com/ceph/go-ceph/common/commands"
"github.com/ceph/go-ceph/internal/commands"
"github.com/ceph/go-ceph/rados"
)
// RadosCommander provides an interface to execute JSON-formatted commands that
// allow the cephfs administrative functions to interact with the Ceph cluster.
type RadosCommander interface {
MgrCommand(buf [][]byte) ([]byte, string, error)
MonCommand(buf []byte) ([]byte, string, error)
}
type RadosCommander = ccom.RadosCommander
// FSAdmin is used to administrate CephFS within a ceph cluster.
type FSAdmin struct {
@ -60,39 +58,25 @@ func (fsa *FSAdmin) validate() error {
// rawMgrCommand takes a byte buffer and sends it to the MGR as a command.
// The buffer is expected to contain preformatted JSON.
func (fsa *FSAdmin) rawMgrCommand(buf []byte) response {
if err := fsa.validate(); err != nil {
return response{err: err}
}
return newResponse(fsa.conn.MgrCommand([][]byte{buf}))
return commands.RawMgrCommand(fsa.conn, buf)
}
// marshalMgrCommand takes an generic interface{} value, converts it to JSON and
// sends the json to the MGR as a command.
func (fsa *FSAdmin) marshalMgrCommand(v interface{}) response {
b, err := json.Marshal(v)
if err != nil {
return response{err: err}
}
return fsa.rawMgrCommand(b)
return commands.MarshalMgrCommand(fsa.conn, v)
}
// rawMonCommand takes a byte buffer and sends it to the MON as a command.
// The buffer is expected to contain preformatted JSON.
func (fsa *FSAdmin) rawMonCommand(buf []byte) response {
if err := fsa.validate(); err != nil {
return response{err: err}
}
return newResponse(fsa.conn.MonCommand(buf))
return commands.RawMonCommand(fsa.conn, buf)
}
// marshalMonCommand takes an generic interface{} value, converts it to JSON and
// sends the json to the MGR as a command.
func (fsa *FSAdmin) marshalMonCommand(v interface{}) response {
b, err := json.Marshal(v)
if err != nil {
return response{err: err}
}
return fsa.rawMonCommand(b)
return commands.MarshalMonCommand(fsa.conn, v)
}
type listNamedResult struct {
@ -101,7 +85,7 @@ type listNamedResult struct {
func parseListNames(res response) ([]string, error) {
var r []listNamedResult
if err := res.noStatus().unmarshal(&r).End(); err != nil {
if err := res.NoStatus().Unmarshal(&r).End(); err != nil {
return nil, err
}
vl := make([]string, len(r))
@ -114,10 +98,10 @@ func parseListNames(res response) ([]string, error) {
// parsePathResponse returns a cleaned up path from requests that get a path
// unless an error is encountered, then an error is returned.
func parsePathResponse(res response) (string, error) {
if res2 := res.noStatus(); !res2.Ok() {
if res2 := res.NoStatus(); !res2.Ok() {
return "", res.End()
}
b := res.body
b := res.Body()
// if there's a trailing newline in the buffer strip it.
// ceph assumes a CLI wants the output of the buffer and there's
// no format=json mode available currently.

View File

@ -3,140 +3,22 @@
package admin
import (
"encoding/json"
"errors"
"fmt"
"strings"
"github.com/ceph/go-ceph/internal/commands"
)
var (
// ErrStatusNotEmpty may be returned if a call should not have a status
// string set but one is.
ErrStatusNotEmpty = errors.New("response status not empty")
// ErrBodyNotEmpty may be returned if a call should have an empty body but
// a body value is present.
ErrBodyNotEmpty = errors.New("response body not empty")
// ErrStatusNotEmpty is an alias for commands.ErrStatusNotEmpty
ErrStatusNotEmpty = commands.ErrStatusNotEmpty
// ErrBodyNotEmpty is an alias for commands.ErrBodyNotEmpty
ErrBodyNotEmpty = commands.ErrBodyNotEmpty
)
const (
deprecatedSuffix = "call is deprecated and will be removed in a future release"
missingPrefix = "No handler found"
einval = -22
)
type response = commands.Response
type cephError interface {
ErrorCode() int
}
// NotImplementedError error values will be returned in the case that an API
// call is not available in the version of Ceph that is running in the target
// cluster.
type NotImplementedError struct {
response
}
// Error implements the error interface.
func (e NotImplementedError) Error() string {
return fmt.Sprintf("API call not implemented server-side: %s", e.status)
}
// response encapsulates the data returned by ceph and supports easy processing
// pipelines.
type response struct {
body []byte
status string
err error
}
// Ok returns true if the response contains no error.
func (r response) Ok() bool {
return r.err == nil
}
// Error implements the error interface.
func (r response) Error() string {
if r.status == "" {
return r.err.Error()
}
return fmt.Sprintf("%s: %q", r.err, r.status)
}
// Unwrap returns the error this response contains.
func (r response) Unwrap() error {
return r.err
}
// Status returns the status string value.
func (r response) Status() string {
return r.status
}
// End returns an error if the response contains an error or nil, indicating
// that response is no longer needed for processing.
func (r response) End() error {
if !r.Ok() {
if ce, ok := r.err.(cephError); ok {
if ce.ErrorCode() == einval && strings.HasPrefix(r.status, missingPrefix) {
return NotImplementedError{response: r}
}
}
return r
}
return nil
}
// noStatus asserts that the input response has no status value.
func (r response) noStatus() response {
if !r.Ok() {
return r
}
if r.status != "" {
return response{r.body, r.status, ErrStatusNotEmpty}
}
return r
}
// noBody asserts that the input response has no body value.
func (r response) noBody() response {
if !r.Ok() {
return r
}
if len(r.body) != 0 {
return response{r.body, r.status, ErrBodyNotEmpty}
}
return r
}
// noData asserts that the input response has no status or body values.
func (r response) noData() response {
return r.noStatus().noBody()
}
// filterDeprecated removes deprecation warnings from the response status.
// Use it when checking the response from calls that may be deprecated in ceph
// if you want those calls to continue working if the warning is present.
func (r response) filterDeprecated() response {
if !r.Ok() {
return r
}
if strings.HasSuffix(r.status, deprecatedSuffix) {
return response{r.body, "", r.err}
}
return r
}
// unmarshal data from the response body into v.
func (r response) unmarshal(v interface{}) response {
if !r.Ok() {
return r
}
if err := json.Unmarshal(r.body, v); err != nil {
return response{body: r.body, err: err}
}
return r
}
// NotImplementedError is an alias for commands.NotImplementedError.
type NotImplementedError = commands.NotImplementedError
// newResponse returns a response.
func newResponse(b []byte, s string, e error) response {
return response{b, s, e}
return commands.NewResponse(b, s, e)
}

View File

@ -61,7 +61,7 @@ func (fsa *FSAdmin) CreateSubVolume(volume, group, name string, o *SubVolumeOpti
o = &SubVolumeOptions{}
}
f := o.toFields(volume, group, name)
return fsa.marshalMgrCommand(f).noData().End()
return fsa.marshalMgrCommand(f).NoData().End()
}
// ListSubVolumes returns a list of subvolumes belonging to the volume and
@ -117,7 +117,7 @@ func (fsa *FSAdmin) RemoveSubVolumeWithFlags(volume, group, name string, o SubVo
if group != NoGroup {
m["group_name"] = group
}
return fsa.marshalMgrCommand(mergeFlags(m, o)).noData().End()
return fsa.marshalMgrCommand(mergeFlags(m, o)).NoData().End()
}
type subVolumeResizeFields struct {
@ -159,7 +159,7 @@ func (fsa *FSAdmin) ResizeSubVolume(
}
var result []*SubVolumeResizeResult
res := fsa.marshalMgrCommand(f)
if err := res.noStatus().unmarshal(&result).End(); err != nil {
if err := res.NoStatus().Unmarshal(&result).End(); err != nil {
return nil, err
}
return result[0], nil
@ -248,7 +248,7 @@ type subVolumeInfoWrapper struct {
func parseSubVolumeInfo(res response) (*SubVolumeInfo, error) {
var info subVolumeInfoWrapper
if err := res.noStatus().unmarshal(&info).End(); err != nil {
if err := res.NoStatus().Unmarshal(&info).End(); err != nil {
return nil, err
}
if info.VBytesQuota != nil {
@ -289,7 +289,7 @@ func (fsa *FSAdmin) CreateSubVolumeSnapshot(volume, group, source, name string)
if group != NoGroup {
m["group_name"] = group
}
return fsa.marshalMgrCommand(m).noData().End()
return fsa.marshalMgrCommand(m).NoData().End()
}
// RemoveSubVolumeSnapshot removes the specified snapshot from the subvolume.
@ -320,7 +320,7 @@ func (fsa *FSAdmin) rmSubVolumeSnapshot(volume, group, subvolume, name string, o
if group != NoGroup {
m["group_name"] = group
}
return fsa.marshalMgrCommand(mergeFlags(m, o)).noData().End()
return fsa.marshalMgrCommand(mergeFlags(m, o)).NoData().End()
}
// ListSubVolumeSnapshots returns a listing of snapshots for a given subvolume.
@ -351,7 +351,7 @@ type SubVolumeSnapshotInfo struct {
func parseSubVolumeSnapshotInfo(res response) (*SubVolumeSnapshotInfo, error) {
var info SubVolumeSnapshotInfo
if err := res.noStatus().unmarshal(&info).End(); err != nil {
if err := res.NoStatus().Unmarshal(&info).End(); err != nil {
return nil, err
}
return &info, nil
@ -390,7 +390,7 @@ func (fsa *FSAdmin) ProtectSubVolumeSnapshot(volume, group, subvolume, name stri
if group != NoGroup {
m["group_name"] = group
}
return fsa.marshalMgrCommand(m).filterDeprecated().noData().End()
return fsa.marshalMgrCommand(m).FilterDeprecated().NoData().End()
}
// UnprotectSubVolumeSnapshot removes protection from the specified snapshot.
@ -408,5 +408,5 @@ func (fsa *FSAdmin) UnprotectSubVolumeSnapshot(volume, group, subvolume, name st
if group != NoGroup {
m["group_name"] = group
}
return fsa.marshalMgrCommand(m).filterDeprecated().noData().End()
return fsa.marshalMgrCommand(m).FilterDeprecated().NoData().End()
}

View File

@ -48,7 +48,7 @@ func (fsa *FSAdmin) CreateSubVolumeGroup(volume, name string, o *SubVolumeGroupO
o = &SubVolumeGroupOptions{}
}
res := fsa.marshalMgrCommand(o.toFields(volume, name))
return res.noData().End()
return res.NoData().End()
}
// ListSubVolumeGroups returns a list of subvolume groups belonging to the
@ -86,7 +86,7 @@ func (fsa *FSAdmin) rmSubVolumeGroup(volume, name string, o commonRmFlags) error
"group_name": name,
"format": "json",
}, o))
return res.noData().End()
return res.NoData().End()
}
// SubVolumeGroupPath returns the path to the subvolume from the root of the

View File

@ -43,7 +43,7 @@ func (fsa *FSAdmin) ListFileSystems() ([]FSPoolInfo, error) {
func parseFsList(res response) ([]FSPoolInfo, error) {
var listing []FSPoolInfo
if err := res.noStatus().unmarshal(&listing).End(); err != nil {
if err := res.NoStatus().Unmarshal(&listing).End(); err != nil {
return nil, err
}
return listing, nil
@ -78,13 +78,8 @@ func parseDumpToIdents(res response) ([]VolumeIdent, error) {
if !res.Ok() {
return nil, res.End()
}
if len(res.status) >= dumpOkLen && res.status[:dumpOkLen] == dumpOkPrefix {
// Unhelpfully, ceph drops a status string on success responses for this
// call. this hacks around that by ignoring its typical prefix
res.status = ""
}
var dump fsDump
if err := res.noStatus().unmarshal(&dump).End(); err != nil {
if err := res.FilterPrefix(dumpOkPrefix).NoStatus().Unmarshal(&dump).End(); err != nil {
return nil, err
}
// copy the dump json into the simpler enumeration list
@ -123,15 +118,16 @@ type VolumeStatus struct {
func parseVolumeStatus(res response) (*VolumeStatus, error) {
var vs VolumeStatus
res = res.noStatus()
res = res.NoStatus()
if !res.Ok() {
return nil, res.End()
}
res = res.unmarshal(&vs)
res = res.Unmarshal(&vs)
if !res.Ok() {
if bytes.HasPrefix(res.body, []byte("ceph")) {
res.status = invalidTextualResponse
return nil, NotImplementedError{response: res}
if bytes.HasPrefix(res.Body(), []byte("ceph")) {
return nil, NotImplementedError{
Response: newResponse(res.Body(), invalidTextualResponse, res.Unwrap()),
}
}
return nil, res.End()
}