From mboxrd@z Thu Jan 1 00:00:00 1970 From: rmccabe@sourceware.org Date: 23 Jul 2007 18:47:53 -0000 Subject: [Cluster-devel] conga/ricci modules/cluster/ClusterModule.cpp ... Message-ID: <20070723184753.30858.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 + * Author: Ryan McCabe */ @@ -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(var.name(), var)); - return ret; + Variable var("status", Cluster::status()); + + VarMap ret; + ret.insert(pair(var.name(), var)); + return ret; } -VarMap +VarMap get_cluster_conf(const VarMap& args) { - Variable var("cluster.conf", ClusterConf::get()); - - VarMap ret; - ret.insert(pair(var.name(), var)); - return ret; + Variable var("cluster.conf", ClusterConf::get()); + + VarMap ret; + ret.insert(pair(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(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 @@ + + + + + + + + + + + + + /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 @@ + + + + + + + + + + + + + /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 @@ + + + + + + + + + + + + + /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 @@ + + + + + + + + + + + + + +