[Cluster-devel] conga/ricci modules/cluster/ClusterModule.cpp ...
rmccabe at sourceware.org
rmccabe at sourceware.org
Mon Jul 23 18:47:53 UTC 2007
CVSROOT: /cvs/cluster
Module name: conga
Changes by: rmccabe at sourceware.org 2007-07-23 18:47:51
Modified files:
ricci/modules/cluster: ClusterModule.cpp Virt.cpp Virt.h
Added files:
ricci/test_suite/cluster: delete_xvm_key.xml
generate_xvm_key.xml get_xvm_key.xml
set_xvm_key.xml
Log message:
Complete ricci support for managing fence_xvm key files
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/ClusterModule.cpp.diff?cvsroot=cluster&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/Virt.cpp.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/Virt.h.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/test_suite/cluster/delete_xvm_key.xml.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/test_suite/cluster/generate_xvm_key.xml.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/test_suite/cluster/get_xvm_key.xml.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/test_suite/cluster/set_xvm_key.xml.diff?cvsroot=cluster&r1=NONE&r2=1.1
--- conga/ricci/modules/cluster/ClusterModule.cpp 2007/03/09 22:48:20 1.7
+++ conga/ricci/modules/cluster/ClusterModule.cpp 2007/07/23 18:47:50 1.8
@@ -1,5 +1,5 @@
/*
- Copyright Red Hat, Inc. 2006
+ Copyright Red Hat, Inc. 2006-2007
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -13,11 +13,12 @@
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
MA 02139, USA.
*/
/*
* Author: Stanko Kupcevic <kupcevic at redhat.com>
+ * Author: Ryan McCabe <rmccabe at redhat.com>
*/
@@ -27,6 +28,7 @@
#include "Clusvcadm.h"
#include "Fence.h"
#include "Virt.h"
+#include "base64.h"
using namespace std;
@@ -42,13 +44,18 @@
static VarMap fence_node(const VarMap& args);
static VarMap start_node(const VarMap& args);
static VarMap stop_node(const VarMap& args);
+
static VarMap virt_guest(const VarMap& args);
+static VarMap delete_xvm_key(const VarMap& args);
+static VarMap set_xvm_key(const VarMap& args);
+static VarMap get_xvm_key(const VarMap& args);
+static VarMap generate_xvm_key(const VarMap& args);
static ApiFcnMap build_fcn_map();
ClusterModule::ClusterModule() :
- Module(build_fcn_map())
+ Module(build_fcn_map())
{}
ClusterModule::~ClusterModule()
@@ -58,157 +65,161 @@
ApiFcnMap
build_fcn_map()
{
- FcnMap api_1_0;
- api_1_0["get_cluster.conf"] = get_cluster_conf;
- api_1_0["set_cluster.conf"] = set_cluster_conf;
-
- api_1_0["status"] = cluster_status;
-
- api_1_0["start_service"] = service_start;
- api_1_0["stop_service"] = service_stop;
- api_1_0["restart_service"] = service_restart;
- api_1_0["migrate_service"] = service_migrate;
-
- api_1_0["start_node"] = start_node;
- api_1_0["stop_node"] = stop_node;
- api_1_0["fence_node"] = fence_node;
- api_1_0["virt_guest"] = virt_guest;
-
-
- ApiFcnMap api_fcn_map;
- api_fcn_map["1.0"] = api_1_0;
-
- return api_fcn_map;
-}
+ FcnMap api_1_0;
+
+ api_1_0["get_cluster.conf"] = get_cluster_conf;
+ api_1_0["set_cluster.conf"] = set_cluster_conf;
+
+ api_1_0["status"] = cluster_status;
+
+ api_1_0["start_service"] = service_start;
+ api_1_0["stop_service"] = service_stop;
+ api_1_0["restart_service"] = service_restart;
+ api_1_0["migrate_service"] = service_migrate;
+
+ api_1_0["start_node"] = start_node;
+ api_1_0["stop_node"] = stop_node;
+ api_1_0["fence_node"] = fence_node;
-VarMap
+ api_1_0["delete_xvm_key"] = delete_xvm_key;
+ api_1_0["set_xvm_key"] = set_xvm_key;
+ api_1_0["get_xvm_key"] = get_xvm_key;
+ api_1_0["generate_xvm_key"] = generate_xvm_key;
+ api_1_0["virt_guest"] = virt_guest;
+
+
+ ApiFcnMap api_fcn_map;
+ api_fcn_map["1.0"] = api_1_0;
+
+ return api_fcn_map;
+}
+
+VarMap
cluster_status(const VarMap& args)
{
- Variable var("status", Cluster::status());
-
- VarMap ret;
- ret.insert(pair<String, Variable>(var.name(), var));
- return ret;
+ Variable var("status", Cluster::status());
+
+ VarMap ret;
+ ret.insert(pair<String, Variable>(var.name(), var));
+ return ret;
}
-VarMap
+VarMap
get_cluster_conf(const VarMap& args)
{
- Variable var("cluster.conf", ClusterConf::get());
-
- VarMap ret;
- ret.insert(pair<String, Variable>(var.name(), var));
- return ret;
+ Variable var("cluster.conf", ClusterConf::get());
+
+ VarMap ret;
+ ret.insert(pair<String, Variable>(var.name(), var));
+ return ret;
}
-VarMap
+VarMap
set_cluster_conf(const VarMap& args)
{
- XMLObject conf;
- bool propagate;
- try {
- VarMap::const_iterator iter = args.find("cluster.conf");
- if (iter == args.end())
- throw APIerror("missing cluster.conf variable");
- conf = iter->second.get_XML();
-
- propagate = false;
- iter = args.find("propagate");
- if (iter != args.end())
- propagate = iter->second.get_bool();
- } catch ( String e ) {
- throw APIerror(e);
- }
-
- ClusterConf::set(conf, propagate);
-
- VarMap ret;
- return ret;
+ XMLObject conf;
+ bool propagate;
+
+ try {
+ VarMap::const_iterator iter = args.find("cluster.conf");
+ if (iter == args.end())
+ throw APIerror("missing cluster.conf variable");
+ conf = iter->second.get_XML();
+
+ propagate = false;
+ iter = args.find("propagate");
+ if (iter != args.end())
+ propagate = iter->second.get_bool();
+ } catch ( String e ) {
+ throw APIerror(e);
+ }
+
+ ClusterConf::set(conf, propagate);
+ VarMap ret;
+ return ret;
}
-VarMap
+VarMap
service_stop(const VarMap& args)
{
- String name;
- try {
- VarMap::const_iterator iter = args.find("servicename");
- if (iter == args.end())
- throw APIerror("missing servicename variable");
- name = iter->second.get_string();
- } catch ( String e ) {
- throw APIerror(e);
- }
-
- Clusvcadm::stop(name);
-
- VarMap ret;
- return ret;
+ String name;
+
+ try {
+ VarMap::const_iterator iter = args.find("servicename");
+ if (iter == args.end())
+ throw APIerror("missing servicename variable");
+ name = iter->second.get_string();
+ } catch ( String e ) {
+ throw APIerror(e);
+ }
+
+ Clusvcadm::stop(name);
+ VarMap ret;
+ return ret;
}
-VarMap
+VarMap
service_start(const VarMap& args)
{
- String service_name, node_name;
- try {
- VarMap::const_iterator iter = args.find("servicename");
- if (iter == args.end())
- throw APIerror("missing servicename variable");
- service_name = iter->second.get_string();
-
- iter = args.find("nodename");
- if (iter != args.end())
- node_name = iter->second.get_string();
- } catch ( String e ) {
- throw APIerror(e);
- }
-
- Clusvcadm::start(service_name, node_name);
-
- VarMap ret;
- return ret;
+ String service_name, node_name;
+
+ try {
+ VarMap::const_iterator iter = args.find("servicename");
+ if (iter == args.end())
+ throw APIerror("missing servicename variable");
+ service_name = iter->second.get_string();
+
+ iter = args.find("nodename");
+ if (iter != args.end())
+ node_name = iter->second.get_string();
+ } catch ( String e ) {
+ throw APIerror(e);
+ }
+
+ Clusvcadm::start(service_name, node_name);
+ VarMap ret;
+ return ret;
}
-VarMap
+VarMap
service_migrate(const VarMap& args)
{
- String service_name, node_name;
- try {
- VarMap::const_iterator iter = args.find("servicename");
- if (iter == args.end())
- throw APIerror("missing servicename variable");
- service_name = iter->second.get_string();
-
- iter = args.find("nodename");
- if (iter != args.end())
- node_name = iter->second.get_string();
- } catch ( String e ) {
- throw APIerror(e);
- }
-
- Clusvcadm::migrate(service_name, node_name);
-
- VarMap ret;
- return ret;
+ String service_name, node_name;
+ try {
+ VarMap::const_iterator iter = args.find("servicename");
+ if (iter == args.end())
+ throw APIerror("missing servicename variable");
+ service_name = iter->second.get_string();
+
+ iter = args.find("nodename");
+ if (iter != args.end())
+ node_name = iter->second.get_string();
+ } catch ( String e ) {
+ throw APIerror(e);
+ }
+
+ Clusvcadm::migrate(service_name, node_name);
+ VarMap ret;
+ return ret;
}
-VarMap
+VarMap
service_restart(const VarMap& args)
{
- String name;
- try {
- VarMap::const_iterator iter = args.find("servicename");
- if (iter == args.end())
- throw APIerror("missing servicename variable");
- name = iter->second.get_string();
- } catch ( String e ) {
- throw APIerror(e);
- }
-
- Clusvcadm::restart(name);
-
- VarMap ret;
- return ret;
+ String name;
+ try {
+ VarMap::const_iterator iter = args.find("servicename");
+ if (iter == args.end())
+ throw APIerror("missing servicename variable");
+ name = iter->second.get_string();
+ } catch ( String e ) {
+ throw APIerror(e);
+ }
+
+ Clusvcadm::restart(name);
+ VarMap ret;
+ return ret;
}
VarMap
@@ -221,62 +232,141 @@
return ret;
}
-VarMap
+VarMap
+delete_xvm_key(const VarMap& args) {
+ Virt::delete_xvm_key();
+ VarMap ret;
+ return ret;
+}
+
+VarMap
+set_xvm_key(const VarMap& args) {
+ String key_base64;
+
+ try {
+ VarMap::const_iterator iter = args.find("key_base64");
+
+ if (iter != args.end()) {
+ key_base64 = iter->second.get_string();
+ } else {
+ throw String("missing key_base64 variable");
+ }
+ } catch ( String e ) {
+ throw APIerror(e);
+ }
+
+ Virt::set_xvm_key(key_base64.c_str());
+ VarMap ret;
+ return ret;
+}
+
+VarMap
+get_xvm_key(const VarMap& args) {
+ char *key_base64 = NULL;
+
+ key_base64 = Virt::get_xvm_key();
+ Variable var("key_base64", String(key_base64));
+ memset(key_base64, 0, strlen(key_base64));
+ free(key_base64);
+
+ VarMap ret;
+ ret.insert(pair<String, Variable>(var.name(), var));
+ return ret;
+}
+
+VarMap
+generate_xvm_key(const VarMap& args) {
+ size_t key_bytes = XVM_KEY_DEFAULT_SIZE;
+
+ try {
+ VarMap::const_iterator iter = args.find("size");
+
+ if (iter != args.end()) {
+ int bytes = iter->second.get_int();
+
+ if (bytes < XVM_KEY_MIN_SIZE) {
+ char err[64];
+ snprintf(err, sizeof(err),
+ "The minimum fence_xvm key size is %u bytes",
+ XVM_KEY_MIN_SIZE);
+ throw String(err);
+ }
+
+ if (bytes > XVM_KEY_MAX_SIZE) {
+ char err[64];
+ snprintf(err, sizeof(err),
+ "The maximum fence_xvm key size is %u bytes",
+ XVM_KEY_MAX_SIZE);
+ throw String(err);
+ }
+ key_bytes = (size_t) bytes;
+ }
+ } catch ( String e ) {
+ throw APIerror(e);
+ }
+
+ Virt::generate_xvm_key(key_bytes);
+ VarMap ret;
+ return ret;
+}
+
+VarMap
fence_node(const VarMap& args)
{
- String name;
- try {
- VarMap::const_iterator iter = args.find("nodename");
- if (iter == args.end())
- throw APIerror("missing nodename variable");
- name = iter->second.get_string();
- } catch ( String e ) {
- throw APIerror(e);
- }
-
- Fence::fence_node(name);
-
- VarMap ret;
- return ret;
+ String name;
+
+ try {
+ VarMap::const_iterator iter = args.find("nodename");
+ if (iter == args.end())
+ throw APIerror("missing nodename variable");
+ name = iter->second.get_string();
+ } catch ( String e ) {
+ throw APIerror(e);
+ }
+
+ Fence::fence_node(name);
+ VarMap ret;
+ return ret;
}
-VarMap
+VarMap
start_node(const VarMap& args)
{
- bool cluster_startup = false;
- try {
- VarMap::const_iterator iter = args.find("cluster_startup");
- if (iter != args.end())
- cluster_startup = iter->second.get_bool();
- } catch ( String e ) {
- throw APIerror(e);
- }
-
- Cluster::start_node(cluster_startup);
-
- VarMap ret;
- return ret;
+ bool cluster_startup = false;
+
+ try {
+ VarMap::const_iterator iter = args.find("cluster_startup");
+ if (iter != args.end())
+ cluster_startup = iter->second.get_bool();
+ } catch ( String e ) {
+ throw APIerror(e);
+ }
+
+ Cluster::start_node(cluster_startup);
+
+ VarMap ret;
+ return ret;
}
-VarMap
+VarMap
stop_node(const VarMap& args)
{
- bool cluster_shutdown = false;
- bool purge_conf = false;
- try {
- VarMap::const_iterator iter = args.find("cluster_shutdown");
- if (iter != args.end())
- cluster_shutdown = iter->second.get_bool();
- iter = args.find("purge_conf");
- if (iter != args.end())
- purge_conf = iter->second.get_bool();
- } catch ( String e ) {
- throw APIerror(e);
- }
-
- Cluster::stop_node(cluster_shutdown,
- purge_conf);
-
- VarMap ret;
- return ret;
+ bool cluster_shutdown = false;
+ bool purge_conf = false;
+
+ try {
+ VarMap::const_iterator iter = args.find("cluster_shutdown");
+ if (iter != args.end())
+ cluster_shutdown = iter->second.get_bool();
+
+ iter = args.find("purge_conf");
+ if (iter != args.end())
+ purge_conf = iter->second.get_bool();
+ } catch ( String e ) {
+ throw APIerror(e);
+ }
+
+ Cluster::stop_node(cluster_shutdown, purge_conf);
+ VarMap ret;
+ return ret;
}
--- conga/ricci/modules/cluster/Virt.cpp 2007/07/17 22:30:45 1.2
+++ conga/ricci/modules/cluster/Virt.cpp 2007/07/23 18:47:50 1.3
@@ -30,10 +30,6 @@
using namespace std;
-#define XVM_KEY_PATH "/etc/cluster/fence_xvm.key"
-#define XVM_KEY_MAX_SIZE 4096
-#define XVM_KEY_MIN_SIZE 128
-
bool Virt::virt_guest(void) {
try {
String out, err;
@@ -48,41 +44,43 @@
if (out.find("Manufacturer: Xen") != out.npos)
return true;
} catch ( ... ) {}
+
return false;
}
bool Virt::delete_xvm_key(void) {
- return unlink(XVM_KEY_PATH);
+ return unlink(XVM_KEY_PATH) == 0;
}
bool Virt::set_xvm_key(const char *key_base64) {
- char buf[4608];
+ char *buf = NULL;
size_t keylen;
size_t keylen_dec = 0;
- bool ret;
+ ssize_t ret;
+ bool decoded = false;
int fd;
mode_t old_mask;
char tmpname[] = "/etc/cluster/.fence_xvm.keyXXXXXX";
if (key_base64 == NULL)
- return (false);
+ throw String("no key was given");
keylen = strlen(key_base64);
if (keylen < 1)
- return (false);
+ throw String("no key was given");
- ret = base64_decode(key_base64, keylen, buf, &keylen_dec);
- if (!ret || keylen_dec < XVM_KEY_MIN_SIZE) {
- memset(buf, 0, sizeof(buf));
- return (false);
- }
+ decoded = base64_decode_alloc(key_base64, keylen, &buf, &keylen_dec);
+ if (!decoded || buf == NULL)
+ throw String("an invalid key was given");
old_mask = umask(077);
+
fd = mkstemp(tmpname);
umask(old_mask);
if (fd < 0) {
- memset(buf, 0, sizeof(buf));
- return (false);
+ memset(buf, 0, keylen_dec);
+ free(buf);
+ throw String("error setting new key");
}
fchmod(fd, 0600);
@@ -90,16 +88,18 @@
if (ret < 0 || (size_t) ret != keylen_dec) {
unlink(tmpname);
close(fd);
- memset(buf, 0, sizeof(buf));
- return (false);
+ memset(buf, 0, keylen_dec);
+ free(buf);
+ throw String("error setting new key");
}
close(fd);
- memset(buf, 0, sizeof(buf));
+ memset(buf, 0, keylen_dec);
+ free(buf);
if (rename(tmpname, XVM_KEY_PATH) != 0) {
unlink(tmpname);
- return (false);
+ throw String("error setting new key");
}
return (true);
@@ -112,63 +112,60 @@
struct stat stat;
if (keylen < XVM_KEY_MIN_SIZE || keylen > XVM_KEY_MAX_SIZE)
- return (false);
+ throw String("invalid key length");
fd = open("/dev/urandom", O_RDONLY);
if (fd < 0)
- return (false);
+ throw String("error generating key");
+
ret = read(fd, buf, keylen);
close(fd);
if ((size_t) ret != keylen)
- return (false);
+ throw String("error generating key");
+
fd = open(XVM_KEY_PATH, O_WRONLY | O_EXCL | O_CREAT, 0600);
if (fd < 0)
- return (false);
+ throw String("error generating key");
+
ret = write(fd, buf, keylen);
close(fd);
if ((size_t) ret != keylen) {
unlink(XVM_KEY_PATH);
- return (false);
+ throw String("error generating key");
}
return (true);
}
-bool Virt::get_xvm_key(char *key_out, size_t len) {
+char *Virt::get_xvm_key(void) {
int fd;
ssize_t ret;
size_t keylen_bin = 0;
size_t keylen_base64 = 0;
char buf[XVM_KEY_MAX_SIZE];
struct stat st;
-
- if (len == 0 || len > SSIZE_MAX)
- return (false);
+ char *key_out = NULL;
fd = open(XVM_KEY_PATH, O_RDONLY);
if (fd < 0)
- return (false);
+ throw String("error retrieving key");
if (fstat(fd, &st) != 0) {
close(fd);
- return (false);
+ throw String("error retrieving key");
}
ret = read(fd, buf, sizeof(buf));
close(fd);
if (ret < 0 || (off_t) ret != st.st_size) {
memset(buf, 0, sizeof(buf));
- return (false);
+ throw String("error retrieving key");
}
-
keylen_bin = (size_t) ret;
- if (len < BASE64_LENGTH(keylen_bin) + 1) {
- /* Output won't fit in the buffer. */
- memset(buf, 0, sizeof(buf));
- return (false);
- }
- base64_encode(buf, keylen_bin, key_out, len);
+ keylen_base64 = base64_encode_alloc(buf, keylen_bin, &key_out);
memset(buf, 0, sizeof(buf));
- return (false);
+ if (keylen_base64 < 1 || key_out == NULL)
+ throw String("error retrieving key");
+ return (key_out);
}
--- conga/ricci/modules/cluster/Virt.h 2007/07/17 22:30:45 1.2
+++ conga/ricci/modules/cluster/Virt.h 2007/07/23 18:47:50 1.3
@@ -22,15 +22,20 @@
#include "String.h"
-#define DMIDECODE_PATH "/usr/sbin/dmidecode"
+#define XVM_KEY_PATH "/etc/cluster/fence_xvm.key"
+#define XVM_KEY_MAX_SIZE 4096
+#define XVM_KEY_MIN_SIZE 128
+#define XVM_KEY_DEFAULT_SIZE 4096
+
+#define DMIDECODE_PATH "/usr/sbin/dmidecode"
class Virt {
public:
static bool virt_guest(void);
- bool delete_xvm_key(void);
- bool set_xvm_key(const char *key_base64);
- bool get_xvm_key(char *key_out_base64, size_t buflen);
- bool generate_xvm_key(size_t key_bytes);
+ static bool delete_xvm_key(void);
+ static bool set_xvm_key(const char *key_base64);
+ static char *get_xvm_key(void);
+ static bool generate_xvm_key(size_t key_bytes);
};
#endif
/cvs/cluster/conga/ricci/test_suite/cluster/delete_xvm_key.xml,v --> standard output
revision 1.1
--- conga/ricci/test_suite/cluster/delete_xvm_key.xml
+++ - 2007-07-23 18:47:52.828775000 +0000
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<ricci version="1.0" function="process_batch" async="false">
+<batch>
+
+<module name="cluster">
+<request sequence="1254" API_version="1.0">
+<function_call name="delete_xvm_key" />
+</request>
+</module>
+
+</batch>
+</ricci>
+
/cvs/cluster/conga/ricci/test_suite/cluster/generate_xvm_key.xml,v --> standard output
revision 1.1
--- conga/ricci/test_suite/cluster/generate_xvm_key.xml
+++ - 2007-07-23 18:47:52.920499000 +0000
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<ricci version="1.0" function="process_batch" async="false">
+<batch>
+
+<module name="cluster">
+<request sequence="1254" API_version="1.0">
+<function_call name="generate_xvm_key" />
+</request>
+</module>
+
+</batch>
+</ricci>
+
/cvs/cluster/conga/ricci/test_suite/cluster/get_xvm_key.xml,v --> standard output
revision 1.1
--- conga/ricci/test_suite/cluster/get_xvm_key.xml
+++ - 2007-07-23 18:47:53.010883000 +0000
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<ricci version="1.0" function="process_batch" async="false">
+<batch>
+
+<module name="cluster">
+<request sequence="1254" API_version="1.0">
+<function_call name="get_xvm_key" />
+</request>
+</module>
+
+</batch>
+</ricci>
+
/cvs/cluster/conga/ricci/test_suite/cluster/set_xvm_key.xml,v --> standard output
revision 1.1
--- conga/ricci/test_suite/cluster/set_xvm_key.xml
+++ - 2007-07-23 18:47:53.089392000 +0000
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<ricci version="1.0" function="process_batch" async="false">
+<batch>
+
+<module name="cluster">
+<request sequence="1254" API_version="1.0">
+<function_call name="set_xvm_key">
+ <var mutable="false" name="key_base64" type="string" value="33+Yc2b3UfmAGuvknYE2oW3r26fI/jLZYrVnmEQcnG9ANTlKBd2kFrjstZiDzWENBoOAHGCIX4p5SanuysqHZBrEmgh06FY9ZFz5Ss1unGVNzq39EQDkCIKd+rMOF8ncQTDK3RmGmNImic9Ur13w4AXgSodJJp4m3ycxh3cZDT34G1Q2ZI804FLjSSIE3UNpbtmrxLfIm5jZqquVjtQc/xRWr7MyFgu9t0a40gSVHcojYUml7PTtDkcxE6ka274qQoGLwt77Z/kR2RghuPFAoBa3quyA9V8hFtxlG8sSzTS39R82j5Y2/SNKyMJyRsSeSjNPCXlAEuTPItoCYdZghvR1F9lqXHc51nEhd+MaTCFQ5kdJZ6x1CDniCHteiA7f6a4FLMnT6R+HM7b8/MBUqd9x7iwt9aIwgppoWfTvIV+pJ8N4QrpVliUqt8ZxQ02z7D1QlIKYBGrhnsglMHv6BlZMe4ogX4YkXtV8kjSHBxYHSXvOb+LSHYT8qpQDlmAfONsj+UWsN75Af9HDTUuUcjDl05dEjxrEa/E5OAmpBixjuWrsxVjQfi/qZvETX68k1XC93YEDBwMMEej/uxfomf1BzSxlBSWX/3iXWjvxiOWXoENYLM9IYR/XmZUvq5L45bJ4KLjj178EBRyOWXHdhbD5QJLPyxRg+ePHksFsgsTp3jSqru2i1K+EFLpNGObinTNqzCtGyb0vKjuFlD2/C/IQyOGMg7mIEizJSaJvlRFtLVEJRsPN1Pi9sKXpMgaV4lzkzzGgrooz4zRXJ3cDqEKx2uqRikEakPS0jIgL41NAGlOKNQdFee4RKrB5tefVVuRdfRf8WD0XJ3Fub7YAeKosPMMP6g6aeU32HV2l7SBpxbKoeBUcNyHJ5hGn94U8LLYMJ5j0cY73o0c3AvU/vfFukzU8cLq!
Xo8ZQ/hrmc51Evk3e5QDhaiv0huR3JbcrmAVEOnrcgXXYUiezE/mDTD+IR44xrCSqO6mWOTYMh0ZGb2roZS4rRy5kykzmbVT/D4TqFHGgpn8aIyP8qVRDhH/UOZZOCdc6um+ipi+otzVQcK9yOYD4pk0rRnJ0DBzDuebLWEvcoHuBiZFzanaEGK7R7FXy3iR9eE7O/6UVbZSsr6DhmdseAKGKQ2HQ0KJ38X1zf+6vOcV/PUvYimNKmpta2qn9pkNyWTdBRVOrS3VLRNRGtHl2uE/oW9QMpL/mY5+YsPyBR8iEcD1Ra3vknGQ0hDK+6KxPeJx1f/QGaVj7oxQze5RWoVKRuhgeWcKaomxoJ+36O5rgakNduOCIUcrGKxWHb1C3YNsDxIzYLLGHhxLVbciXGzxY5EL12GsELFnK+cdv++qkX1HsiKayBt88O0YlYK1DxFK7wMvuK7stOtfzWFI67j/LGoxBYAkXuMcaRiSzDJm5ADEUrug7L9zCp9A+LYPylPu7t2qdEG57bauEosPy48g+3+/fln//JflUOQemnRbAXLfIQxWJwG4JMYDBegJcVtOvoY+kemTP0rPlDwNgijqBwaU/JW0APCZfOUzmLSbt0jV7m46IwUMkvv9Tf2npi8rKABAY7GwuZUKU1IaDYtsEx4njgodHgRQmLvrAaNLA/7L51jI35PxJ2fsj95Iia7jUmOEIe45IpOfEBxPAHGeBUryt9hohfddBocazucGz3b+14grJ68TXJsAGcTeAe66rw/W+cXksG1W5Ih8gQ+v3xUEBoXTTgqD+336C5Lf0APqBMCCF6om0n3NBIVJ4XvqTHjx6Wbj99bTooDcDKsIJVGY3sf1FZdwdsAs85s1CY3k/j6L732jwKdtV+kdqc5VTAkOG4nqST2UFI5Qtc2umjwxDrDe8GJvQLxtMXPGZcxVW3jgsLOAasYdf6VBN79HMd0FrjfG7t2lQ+BjwEmsOS/E!
gvWV2MjPsyX85901P0M8WSdB7nR5ETvYhQhizFLVjc4ZDY/GBEyCwg20ywEMGU!
7Fr0r8wg
NUWWi/+gBMsXw6DS6c4Dnwj1U6rExffMOJoXum8Gcdi2N3B1vGAH99KGOFtei3E2DJNpd+EgyuJiuO8fz7EWqbokoJba9U2XMEF+9w7YrtZUOF3tmEMlabNDff/GdBFiEPC4bD7GfBE+1jhuYito7fOMXR4e16q1WDspXhD6MGmqe0xSHXqRLtAO9EErZ9RDm0ass7Uwc3gNtgKtx3Oms4kV/+P/6WTslMmQttKpVAmU1Nhw/5cuaHwuRNNDZvNuSdj4tsykkIGsrfSdiWuE/0Ts+PI17rrgxtHBZWTF10Xg/xaAvytspNHbJylSfwN4a4aBf7U7G3DYg95onD4A4KitWA18VCcP4u8M4TDj/Tyz7Tr37/DAfyLek0+NPKFLgcSuMicBovvHrziuZ+QHCquCTAWxvLC965WKpo7jQzqNZVI195b+CocV+YgV2jKeEoaTdMDjeIVGmxElBYVCKU3+y6BVQpARJ+OSqudqPNuukXR8oBCaZQlsCVkugJ+AqPObsDLTda2mjcCREopIzXhYEYGEUwU8AIMzYlw1F15ZzHzgDOG2b3tXW7TairT2KJA0ZtigVAvHGxBh7H7Z3w0s9sInNvH/bZvjWsvB7fXu9qVZxYh9QYFew7zliyvNXUH3NIJseu3njaKluHhYzPokr2RzTHKdNVeeYcFwIWEJFGnk0AYTxb7mW2ATyWJ7CQHUwAWW0n4DyUdkiOU/081x2wPn/+SuH+YvKc1bzdszoSO2zBaAZjbz7GeZJMYAZfAmigYrjSmtMAClk8BgQy0Ecmt9y/vkoPXNq7iiu7O3dNNX2zd1QXbWkYIYhbvl+Z9zWysuVqZ/sVAavUMjm8cnpWh2Rl13siarO57TL/QysyyGYzKEJw55n+Xhjral6c7NhSi4WbuTaMwpw5pSIw38YA/3XTKLI3FXvV5ZQvNKONsKW4WwHgBDkx0QiGWayLtBU8VLEsYWHWU5jIUc3JJA7QgcV!
Swii22vlXCcmfqUJuBtV2AkVTOjUluvk9VOqR8Av3hS/iGBHHoEb8oiJUAjL2P1AqdKrmomZpfYtrVRmHOB0dbNUIq0I6sXY0v0kYzKMfu930NrJEjW1kyPJKnbTfifLlOMUYX+6HBqeSa5ml/04qYwajsG/HfgOqtlIBwOU/OilrK4wqjEIZrDR3eO6wIi2Dmeoqc5euFIfkSu2WR2AO+gxhx80lE4Kny97nykVkgK3I79hpfa7A1h0MGp6ZHKOMesGDJMtDRkCCw7ByHI/+or7ysCHfVmTVJ2nX0dpOUoK6eG+YtidtsI/8i++YLXHyZIl8y+LJHwIpLQOzbVAWoLDihrCR0INL3Z/1NCsp1UlbQwe6Ko+7YHzYGHvaVal1CKeTUmNRaX4ydwL1G57PnlYCNF9+YzLuuAKQavRd/o/LVxojlwj2LaUycfGVcXidLZmNfLulKRX7cyly0bxCuf6RNRnRdLGxnPCRu5SJJrhO9AJXKfTzWaPfIn1vUJaNfEQnhA4D1PwKRTpLlPoF/RgIlzzLY47y1o0pEQ/iRH+9W+EObka5l9Re/1K3ZKmrIJaBftpw8ynvq9sjsnR6mr4GgWGPaVkk32ywNB8MFAS0ZgDgoP2l3cKGZyKH7DifPQsO27EjulMmZHwsBdk4yrPv0Ngmz5Mg35UzkIDEqE7m/l5u27CJ5Jo5jdvio57p0DTI1Rkbr/UpsjlnWwrsq7k/bhRWbES9qXxrsI5rD3wsd1EXH4eoxyDNb4X0IkR8oD4UdGQ6JK/IZfY9hK7D0OpGatK150ftvnqabIkExve4+qdZXVIRIVYikSfbb0+2cAj4sOqr2A/TuSLwlDFLIHj1INFB4gM7qCnPQYJ4SwH86HFiBtM7tRNzT6HUNWm/qhe4tqQRYtJSH1w0kOyMXLP5yNLX57AvVzdcvURvY41DV2BgDwM8NKzSO4qNFwGs5sfyvj6uRQW21xGT7C3EHlE1QQK!
f9sRdRnRmaVHyMOLnRK0aaPsDWhwerO6Wsz2Vm3UJ4Vvgaf9ysA08UvSzcU7mO!
wbPTRciB
MNrx6q5+XIN7xTOYKPsPHkMRrDlyEPojIgnAUNISAhfSPNZuPwhAC5+OiKQV674GntSTOQ1X+VRRX5DtOEd8I/Z4FzPr+vLl8pgoEEJQlNi7UAeaz0Cn5YH8NlCvk62AjVJ/og9dk1SNr0tXMgQjkETxkTsGFamOx8YdENKqTXXVcE6yZurvnyMdTKDmYnLsPeQgeq2Ngfik/vshyLvssewA3sBm9a8iEYwErXWbu/9ccFXDA7KNS76IJfLSYqPKb68M78/ip6v4z8195MyXrx6Nzpalw3KUeXA/YNcx/jMouX8J2F1nN4V0pvHi1Lwi5bl1kCvbQKQNQtpQyZ0MGjTkxzKHxzzIMtd6a3BR+N8UvSUCxq66mLVPsXRgXuB2oyKE/Q5QnQhrotHCEAwF7Gd5yRQBne+7GzTBGc/JGLhni8iIaMg2lw8blQ4sTqWwNB2eJfyOZ1da4AI+YFubcj86O3XEihRwcsn8UZWu9hdsZuS/S6Al+Ocee1JqeHEM1uc07IAoVL6TW0X2Z6VrobCEB1Gkm9iS419EXLzG9vbjidpz5ORB8yRXDFuouv4hXFSGj4WGj9uew52bcyr+WbtlmBBL1/79E78twZsrVSZ9v/drLqq1Cxr/GIu386pdCfgl0AdZeqwXYuU+3dA5iYQDi1CLRZB9D8pMQovAJE4o/HG54lrmHQ1OckVQ6D9Bqr4Pb0yvCcVozXvDgvPcZnSZT3O1L2pIu0FVWbN5izTR3Yk0zWdGCiyGDjnbH7rs9A5PRsahpaoqjemLHePL12rsJnhcmFBx9sEeXkJQHEWBVot+GphFrMLmJ3LurVJgGi1nIIJ8yBqSno+wU5/kPcgneUZfei3QBuXClVVDS4K4CLs15LWjKgP7DFN88Ojdx3HXHjJyfm8tSyToQEEonw0O2O3Vr1fJHg5cEn8p7yCFY36AqjhqtsFPyZESnUsjW2sIcRhlOcvGP0LDqWko81qW7VUjA!
AI4Yi2eDWqCsN4OnrJ8UtkYBC07oNiUNhrwV96KPXj8hM1pn7Err56wnGym0dQ1sEUXDSKZV9vMrMNv+TKCtmN1JN0wQplx0fHDl7sUmCQsWgilELEAtVmPH8U/7xe2CHTKaAwveCbu7ebWTqLE2tTd1mmgG+9V60ptZa3SZ9EU3dpMy83cF3QUhfWZiHUh8c/jpSxnw39o8FrDcXuHjjlLJGni/dDHeMH/TVa+SLx6t/uGwZpdXSmvE4ApXMtxabHNTZO8DGbwbfjeD9kL8LA9R9Td9QfMDbYPSpUXqX7Q0HHQAdyPZIftsZ/ZphDrLyveCHsTwPWo/sGKIfQgv35mAgocuobVZqHUJngNpxNppmVbwnbw/We4pla+UZFQvM7gpBkJRAtHFwu+Wlf8/Nk87ZtgPwiNgq1gaLQLORnsRJ5okyS5v223sw=="/>
+</function_call>
+</request>
+</module>
+
+</batch>
+</ricci>
More information about the Cluster-devel
mailing list