mirror of https://github.com/ceph/go-ceph
rados: add a more direct argv config wrapper ParseConfigArgv
Previously, ParseCmdLineArgs was the function directly wrapping the ceph rados_conf_parse_argv function. This function has the improper (IMO) behavior of assuming you didn't know your own argv[0] and just always stuck "placeholder" in argv[0]. This function adds a more direct wrapper ParseConfigArgv that allows the caller to pass an full argv, and they can put any placholder value desired if they want. Signed-off-by: John Mulligan <jmulligan@redhat.com>
This commit is contained in:
parent
8b16f804a3
commit
a50c60be49
|
@ -12,6 +12,8 @@ import (
|
|||
"github.com/ceph/go-ceph/internal/retry"
|
||||
)
|
||||
|
||||
var argvPlaceholder = "placeholder"
|
||||
|
||||
// ClusterStat represents Ceph cluster statistics.
|
||||
type ClusterStat struct {
|
||||
Kb uint64
|
||||
|
@ -190,26 +192,45 @@ func (c *Conn) GetClusterStats() (stat ClusterStat, err error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// ParseCmdLineArgs configures the connection from command line arguments.
|
||||
func (c *Conn) ParseCmdLineArgs(args []string) error {
|
||||
// add an empty element 0 -- Ceph treats the array as the actual contents
|
||||
// of argv and skips the first element (the executable name)
|
||||
argc := C.int(len(args) + 1)
|
||||
argv := make([]*C.char, argc)
|
||||
|
||||
// make the first element a string just in case it is ever examined
|
||||
argv[0] = C.CString("placeholder")
|
||||
defer C.free(unsafe.Pointer(argv[0]))
|
||||
|
||||
for i, arg := range args {
|
||||
argv[i+1] = C.CString(arg)
|
||||
defer C.free(unsafe.Pointer(argv[i+1]))
|
||||
// ParseConfigArgv configures the connection using a unix style command line
|
||||
// argument vector.
|
||||
//
|
||||
// Implements:
|
||||
// int rados_conf_parse_argv(rados_t cluster, int argc,
|
||||
// const char **argv);
|
||||
func (c *Conn) ParseConfigArgv(argv []string) error {
|
||||
if c.cluster == nil {
|
||||
return ErrNotConnected
|
||||
}
|
||||
if len(argv) == 0 {
|
||||
return ErrEmptyArgument
|
||||
}
|
||||
cargv := make([]*C.char, len(argv))
|
||||
for i := range argv {
|
||||
cargv[i] = C.CString(argv[i])
|
||||
defer C.free(unsafe.Pointer(cargv[i]))
|
||||
}
|
||||
|
||||
ret := C.rados_conf_parse_argv(c.cluster, argc, &argv[0])
|
||||
ret := C.rados_conf_parse_argv(c.cluster, C.int(len(cargv)), &cargv[0])
|
||||
return getError(ret)
|
||||
}
|
||||
|
||||
// ParseCmdLineArgs configures the connection from command line arguments.
|
||||
//
|
||||
// This function passes a placeholder value to Ceph as argv[0], see
|
||||
// ParseConfigArgv for a version of this function that allows the caller to
|
||||
// specify argv[0].
|
||||
func (c *Conn) ParseCmdLineArgs(args []string) error {
|
||||
argv := make([]string, len(args)+1)
|
||||
// Ceph expects a proper argv array as the actual contents with the
|
||||
// first element containing the executable name
|
||||
argv[0] = argvPlaceholder
|
||||
for i := range args {
|
||||
argv[i+1] = args[i]
|
||||
}
|
||||
return c.ParseConfigArgv(argv)
|
||||
}
|
||||
|
||||
// ParseDefaultConfigEnv configures the connection from the default Ceph
|
||||
// environment variable(s).
|
||||
func (c *Conn) ParseDefaultConfigEnv() error {
|
||||
|
|
|
@ -167,6 +167,31 @@ func (suite *RadosTestSuite) TestParseDefaultConfigEnv() {
|
|||
assert.Equal(suite.T(), curr_val, "/dev/null")
|
||||
}
|
||||
|
||||
func (suite *RadosTestSuite) TestParseConfigArgv() {
|
||||
prev_val, err := suite.conn.GetConfigOption("log_file")
|
||||
assert.NoError(suite.T(), err, "Invalid option")
|
||||
|
||||
argv := []string{"rados.test", "--log_file", "/dev/null"}
|
||||
err = suite.conn.ParseConfigArgv(argv)
|
||||
assert.NoError(suite.T(), err)
|
||||
|
||||
curr_val, err := suite.conn.GetConfigOption("log_file")
|
||||
assert.NoError(suite.T(), err, "Invalid option")
|
||||
|
||||
assert.NotEqual(suite.T(), prev_val, "/dev/null")
|
||||
assert.Equal(suite.T(), curr_val, "/dev/null")
|
||||
|
||||
// ensure that an empty slice triggers an error (not a crash)
|
||||
err = suite.conn.ParseConfigArgv([]string{})
|
||||
assert.Error(suite.T(), err)
|
||||
|
||||
// ensure we get an error for an invalid conn value
|
||||
badConn := &Conn{}
|
||||
err = badConn.ParseConfigArgv(
|
||||
[]string{"cephfs.test", "--log_file", "/dev/null"})
|
||||
assert.Error(suite.T(), err)
|
||||
}
|
||||
|
||||
func (suite *RadosTestSuite) TestParseCmdLineArgs() {
|
||||
prev_val, err := suite.conn.GetConfigOption("log_file")
|
||||
assert.NoError(suite.T(), err, "Invalid option")
|
||||
|
|
Loading…
Reference in New Issue