- Includes routines for parsing a URI or text blob - Executes puppet based on above data - Adds a depedancy on libcurl for remote fetching of configs - Discussion of latest implementation can be found here https://fedorahosted.org/pipermail/matahari/2011-July/001375.html
Signed-off-by: Adam Stokes astokes@fedoraproject.org --- src/CMakeLists.txt | 2 +- src/include/matahari/postboot.h | 34 -------- src/include/matahari/sysconfig.h | 54 ++++++++++++ src/lib/CMakeLists.txt | 11 ++- src/lib/sysconfig_linux.c | 154 +++++++++++++++++++++++++++++++++++ src/postboot/CMakeLists.txt | 30 ------- src/postboot/postboot-console.cpp | 79 ------------------ src/postboot/postboot-qmf.cpp | 101 ----------------------- src/postboot/schema.xml | 16 ---- src/sysconfig/CMakeLists.txt | 30 +++++++ src/sysconfig/schema.xml | 35 ++++++++ src/sysconfig/sysconfig-console.cpp | 79 ++++++++++++++++++ src/sysconfig/sysconfig-qmf.cpp | 148 +++++++++++++++++++++++++++++++++ src/tests/CMakeLists.txt | 6 +- src/tests/mh_api_sysconfig.h | 35 ++++++++ 15 files changed, 545 insertions(+), 269 deletions(-) delete mode 100644 src/include/matahari/postboot.h create mode 100644 src/include/matahari/sysconfig.h create mode 100644 src/lib/sysconfig_linux.c delete mode 100644 src/postboot/CMakeLists.txt delete mode 100644 src/postboot/postboot-console.cpp delete mode 100644 src/postboot/postboot-qmf.cpp delete mode 100644 src/postboot/schema.xml create mode 100644 src/sysconfig/CMakeLists.txt create mode 100644 src/sysconfig/schema.xml create mode 100644 src/sysconfig/sysconfig-console.cpp create mode 100644 src/sysconfig/sysconfig-qmf.cpp create mode 100644 src/tests/mh_api_sysconfig.h
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 227e89c..50b3ea7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -138,7 +138,7 @@ add_subdirectory(lib) add_subdirectory(host) add_subdirectory(network) add_subdirectory(service) -add_subdirectory(postboot) +add_subdirectory(sysconfig) add_subdirectory(tests)
### Installation diff --git a/src/include/matahari/postboot.h b/src/include/matahari/postboot.h deleted file mode 100644 index b2b79e0..0000000 --- a/src/include/matahari/postboot.h +++ /dev/null @@ -1,34 +0,0 @@ -/* postboot.h - Copyright (C) 2011 Red Hat, Inc. - * Written by Adam Stokes astokes@fedoraproject.org - * - * 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 Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** - * \file - * \brief Config API - * \ingroup coreapi - */ - -#ifndef __MH_CONFIG_H__ -#define __MH_CONFIG_H__ - -#include <stdint.h> -#include <stdlib.h> - -extern uint32_t mh_is_configured(); -extern void mh_configure(const char *uri); - -#endif // __MH_CONFIG_H__ diff --git a/src/include/matahari/sysconfig.h b/src/include/matahari/sysconfig.h new file mode 100644 index 0000000..17ce0b0 --- /dev/null +++ b/src/include/matahari/sysconfig.h @@ -0,0 +1,54 @@ +/* sysconfig.h - Copyright (C) 2011 Red Hat, Inc. + * Written by Adam Stokes astokes@fedoraproject.org + * + * 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 Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * \file + * \brief Config API + * \ingroup coreapi + */ + +#ifndef __MH_SYSCONFIG_H__ +#define __MH_SYSCONFIG_H__ + +struct conf { + int scheme; + int flags; + char *uri; + char *data; + char *query; + const char *key; +}; + +// Supported SCHEME types +#define PUPPET 1 +#define AUGEAS 2 + +// Supported FLAGS +#define FORCE 1 + +extern int mh_sysconfig_run(const char *uri, int flags, int scheme, struct conf *cf); +extern int mh_sysconfig_run_string(const char *string, int flags, int scheme, struct conf *cf); +extern int mh_sysconfig_query(const char *query, const char *data, + int flags, int scheme, struct conf *cf); + +// scheme specific +extern int mh_sysconfig_run_puppet(struct conf *cf); +extern int mh_sysconfig_run_augeas(struct conf *cf); +extern int mh_sysconfig_query_augeas(struct conf *cf); + +#endif // __MH_SYSCONFIG_H__ diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index cf37cf3..c6ac072 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -1,6 +1,6 @@ # Library
-set(LIBS mcommon mhost mnetwork mservice mpostboot) +set(LIBS mcommon mhost mnetwork mservice msysconfig) include_directories(${pcre_INCLUDE_DIRS})
# See http://sourceware.org/autobook/autobook/autobook_91.html for @@ -22,9 +22,9 @@ add_library (mservice SHARED services.c services_${VARIANT}.c) set_target_properties(mservice PROPERTIES SOVERSION 1.0.0) target_link_libraries(mservice ${pcre_LIBRARIES} mcommon ${SIGAR} ${glib_LIBRARIES})
-add_library (mpostboot SHARED postboot.c) -set_target_properties(mpostboot PROPERTIES SOVERSION 1.0.0) -target_link_libraries(mpostboot ${pcre_LIBRARIES} mcommon ${glib_LIBRARIES}) +add_library (msysconfig SHARED sysconfig_${VARIANT}.c) +set_target_properties(msysconfig PROPERTIES SOVERSION 1.0.0) +target_link_libraries(msysconfig ${pcre_LIBRARIES} mcommon ${glib_LIBRARIES})
if(WIN32) foreach (lib ${LIBS}) @@ -33,7 +33,8 @@ if(WIN32) endforeach (lib ${LIBS}) else(WIN32) foreach (lib ${LIBS}) - install(TARGETS ${lib} DESTINATION lib${LIB_SUFFIX}) + target_link_libraries(${lib} curl) + install(TARGETS ${lib} DESTINATION lib${LIB_SUFFIX}) endforeach (lib ${LIBS}) endif(WIN32)
diff --git a/src/lib/sysconfig_linux.c b/src/lib/sysconfig_linux.c new file mode 100644 index 0000000..4f239c7 --- /dev/null +++ b/src/lib/sysconfig_linux.c @@ -0,0 +1,154 @@ +/* sysconfig.c - Copyright (C) 2011 Red Hat, Inc. + * Written by Adam Stokes astokes@fedoraproject.org + * + * 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 Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef WIN32 +#include "config.h" +#include <stddef.h> +#endif + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <glib.h> +#include <curl/curl.h> +#include "matahari/logging.h" +#include "matahari/sysconfig.h" +#include "matahari/utilities.h" + + +MH_TRACE_INIT_DATA(mh_sysconfig); + +static int +download(const char *uri, FILE *fp) +{ + CURL *curl; + CURLcode res; + + curl_global_init(CURL_GLOBAL_DEFAULT); + curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, uri); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + res = curl_easy_perform(curl); + + if(CURLE_OK != res) { + return -1; + } + } + curl_global_cleanup(); + return 0; +} + +int +mh_sysconfig_run(const char *uri, int flags, int scheme, struct conf *cf) { + int rc = 0; + + switch(scheme) { + case PUPPET: + cf->uri = strdup(uri); + cf->scheme = scheme; + rc = mh_sysconfig_run_puppet(cf); + free(cf->uri); + break; + default: + rc = -1; + break; + } + return rc; +} + +int +mh_sysconfig_run_string(const char *data, int flags, int scheme, struct conf *cf) { + int rc = 0; + + switch(scheme) { + case PUPPET: + cf->data = strdup(data); + cf->scheme = scheme; + rc = mh_sysconfig_run_puppet(cf); + free(cf->data); + break; + default: + rc = -1; + break; + } + return rc; +} + +int +mh_sysconfig_query(const char *query, const char *data, int flags, int scheme, struct conf *cf) { + int rc = 0; + + switch(scheme) { + case AUGEAS: + cf->query = strdup(query); + cf->data = strdup(data); + cf->scheme = scheme; + rc = mh_sysconfig_run_augeas(cf); + free(cf->query); + free(cf->data); + break; + default: + rc = -1; + break; + } + return rc; +} + + +int +mh_sysconfig_run_puppet(struct conf *cf) +{ + int rc = 0; + char *filename = NULL, *cmd = NULL; + int fd; + FILE *fp; + + if(cf->uri != NULL) { + filename = strdup("puppet_conf_XXXXXX"); + fd = mkstemp(filename); + fp = fdopen(fd, "w+b"); + rc = download(cf->uri, fp); + fclose(fp); + } else if(cf->data != NULL) { + filename = strdup("puppet_conf_blob"); + g_file_set_contents(filename, cf->data, strlen(cf->data), NULL); + } else { + return -1; + } + + asprintf(cmd, "puppet %s", filename); + rc = system(cmd); + free(filename); + free(cmd); + return rc; +} + +int +mh_sysconfig_run_augeas(struct conf *cf) +{ + fprintf(stderr, "not implemented\n"); + return 0; +} + +int +mh_sysconfig_query_augeas(struct conf *cf) +{ + fprintf(stderr, "not implemented\n"); + return 0; +} diff --git a/src/postboot/CMakeLists.txt b/src/postboot/CMakeLists.txt deleted file mode 100644 index 36d59a1..0000000 --- a/src/postboot/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -set(BASE "postboot") -set(BASE_LIB "m${BASE}") -set(QMF_AGENT "matahari-qmf-${BASE}d") -set(QMF_CONSOLE "matahari-qmf-${BASE}-consoled") - -# QMF daemon -if(WITH-QMF) - set(SCHEMA_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/qmf/org/matahariproject/QmfPackage.cpp) - generate_qmf_schemas(${CMAKE_CURRENT_SOURCE_DIR}/schema.xml ${SCHEMA_SOURCES}) - include_directories(${CMAKE_CURRENT_BINARY_DIR}) - - add_executable(${QMF_AGENT} ${BASE}-qmf.cpp ${SCHEMA_SOURCES}) - add_executable(${QMF_CONSOLE} ${BASE}-console.cpp) - - target_link_libraries(${QMF_AGENT} ${BASE_LIB} mcommon_qmf) - target_link_libraries(${QMF_CONSOLE} mcommon_qmf) - - if(NOT WIN32) - configure_file(${CMAKE_SOURCE_DIR}/matahari.init.in ${CMAKE_CURRENT_BINARY_DIR}/matahari-${BASE}) - install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/matahari-${BASE} DESTINATION ${initdir}) - # Override BASE for matahari-postboot-console - unset(BASE) - set(BASE "postboot-console") - configure_file(${CMAKE_SOURCE_DIR}/matahari.init.in ${CMAKE_CURRENT_BINARY_DIR}/matahari-${BASE}) - install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/matahari-${BASE} DESTINATION ${initdir}) - endif(NOT WIN32) - - install(TARGETS ${QMF_AGENT} DESTINATION sbin) - install(TARGETS ${QMF_CONSOLE} DESTINATION sbin) -endif(WITH-QMF) diff --git a/src/postboot/postboot-console.cpp b/src/postboot/postboot-console.cpp deleted file mode 100644 index 188c443..0000000 --- a/src/postboot/postboot-console.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* config-console.cpp - Copyright (c) 2011 Red Hat, Inc. - * Written by Adam Stokes astokes@fedoraproject.org - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef WIN32 -#include "config.h" -#endif - -#include <qpid/messaging/Connection.h> -#include <qpid/messaging/Duration.h> -#include <qmf/ConsoleSession.h> -#include <qmf/ConsoleEvent.h> -#include <qmf/Agent.h> -#include <qmf/Data.h> -#include <qmf/DataAddr.h> -#include <qmf/Query.h> -#include <qpid/types/Variant.h> - -#include <string> -#include <iostream> - -using namespace std; -using namespace qmf; -using qpid::types::Variant; -using qpid::messaging::Duration; - -int main(int argc, char** argv) -{ - string brokerUrl("amqp:tcp:127.0.0.1:49000"); - qpid::types::Variant::Map connectionOptions; - qpid::types::Variant::Map dataProperties; - string sessionOptions; - - connectionOptions["reconnect"] = true; - - dataProperties["uri"] = argv[1] ? argv[1] : "http://localhost/config/uuid"; - - qpid::messaging::Connection connection(brokerUrl, connectionOptions); - connection.open(); - - ConsoleSession session(connection, sessionOptions); - // Only filter connecting agents under matahariproject.org vendor and Config product - session.setAgentFilter("[and, [eq, _vendor, [quote, 'matahariproject.org']], [eq, _product, [quote, 'Config']]]"); - session.open(); - - Agent agent; - while (true) { - ConsoleEvent event; - if(session.nextEvent(event)) { - switch(event.getType()) { - case CONSOLE_AGENT_ADD: - { - agent = event.getAgent(); - DataAddr agent_event_addr("config", agent.getName(), 0); - ConsoleEvent result(agent.callMethod("configure", - dataProperties, - agent_event_addr)); - } - break; - default: {} - } - } - } - return 0; -} diff --git a/src/postboot/postboot-qmf.cpp b/src/postboot/postboot-qmf.cpp deleted file mode 100644 index 7058276..0000000 --- a/src/postboot/postboot-qmf.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* config-qmf.cpp - Copyright (C) 2011 Red Hat, Inc. - * Written by Adam Stokes astokes@fedoraproject.org - * - * 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 Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef WIN32 -#include "config.h" -#endif - -#include "matahari/mh_agent.h" - -#include "qmf/org/matahariproject/QmfPackage.h" - -#include <qpid/agent/ManagementAgent.h> - -extern "C" { -#include <stdlib.h> -#include <string.h> -#include <glib.h> -#include <glib/gprintf.h> -#include "matahari/postboot.h" -#include "matahari/logging.h" -#include "matahari/network.h" -#include "matahari/host.h" -#include <sigar.h> -#include <sigar_format.h> -}; - -class ConfigAgent : public MatahariAgent -{ -private: - qmf::org::matahariproject::PackageDefinition _package; -public: - virtual int setup(qmf::AgentSession session); - virtual gboolean invoke(qmf::AgentSession session, qmf::AgentEvent event, - gpointer user_data); -}; - -int -main(int argc, char **argv) -{ - ConfigAgent agent; - int rc = agent.init(argc, argv, "Config"); - if (rc == 0) { - agent.run(); - } - return rc; -} - -int -ConfigAgent::setup(qmf::AgentSession session) -{ - _package.configure(session); - _instance = qmf::Data(_package.data_Postboot); - - _instance.setProperty("hostname", mh_hostname()); - _instance.setProperty("uuid", mh_uuid()); - _instance.setProperty("is_configured", mh_is_configured()); - - _agent_session.addData(_instance, "postboot"); - return 0; -} - -gboolean -ConfigAgent::invoke(qmf::AgentSession session, qmf::AgentEvent event, gpointer user_data) -{ - if (event.getType() != qmf::AGENT_METHOD) { - return TRUE; - } - - const std::string& methodName(event.getMethodName()); - - if (methodName == "configure") { - int rc = mh_is_configured(); - if(rc == 0) { - mh_configure(event.getArguments()["uri"].asString().c_str()); - } - event.addReturnArgument("configured", rc); - } else { - session.raiseException(event, MH_NOT_IMPLEMENTED); - goto bail; - } - - session.methodSuccess(event); - -bail: - return TRUE; -} diff --git a/src/postboot/schema.xml b/src/postboot/schema.xml deleted file mode 100644 index 2d930ce..0000000 --- a/src/postboot/schema.xml +++ /dev/null @@ -1,16 +0,0 @@ -<schema package="org.matahariproject"> - - <!-- Config API --> - <class name="Postboot"> - <property name="uuid" type="sstr" access="RO" desc="Host UUID" /> - <property name="hostname" type="sstr" access="RO" desc="Hostname" index="y"/> - <property name="is_configured" type="uint32" access="RO" desc="Check if agent is configured." /> - - <statistic name="qmf-gen-no-crash" type="absTime" desc="Dummy stat to stop qmf-gen from crashing." /> - - <method name="configure" desc="Send configure method"> - <arg name="uri" dir="I" type="sstr" /> - <arg name="configured" dir="O" type="uint32" /> - </method> - </class> -</schema> diff --git a/src/sysconfig/CMakeLists.txt b/src/sysconfig/CMakeLists.txt new file mode 100644 index 0000000..1d9fba8 --- /dev/null +++ b/src/sysconfig/CMakeLists.txt @@ -0,0 +1,30 @@ +set(BASE "sysconfig") +set(BASE_LIB "m${BASE}") +set(QMF_AGENT "matahari-qmf-${BASE}d") +set(QMF_CONSOLE "matahari-qmf-${BASE}-consoled") + +# QMF daemon +if(WITH-QMF) + set(SCHEMA_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/qmf/org/matahariproject/QmfPackage.cpp) + generate_qmf_schemas(${CMAKE_CURRENT_SOURCE_DIR}/schema.xml ${SCHEMA_SOURCES}) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) + + add_executable(${QMF_AGENT} ${BASE}-qmf.cpp ${SCHEMA_SOURCES}) + add_executable(${QMF_CONSOLE} ${BASE}-console.cpp) + + target_link_libraries(${QMF_AGENT} ${BASE_LIB} mcommon_qmf) + target_link_libraries(${QMF_CONSOLE} mcommon_qmf) + + if(NOT WIN32) + configure_file(${CMAKE_SOURCE_DIR}/matahari.init.in ${CMAKE_CURRENT_BINARY_DIR}/matahari-${BASE}) + install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/matahari-${BASE} DESTINATION ${initdir}) + # Override BASE for matahari-sysconfig-console + unset(BASE) + set(BASE "sysconfig-console") + configure_file(${CMAKE_SOURCE_DIR}/matahari.init.in ${CMAKE_CURRENT_BINARY_DIR}/matahari-${BASE}) + install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/matahari-${BASE} DESTINATION ${initdir}) + endif(NOT WIN32) + + install(TARGETS ${QMF_AGENT} DESTINATION sbin) + install(TARGETS ${QMF_CONSOLE} DESTINATION sbin) +endif(WITH-QMF) diff --git a/src/sysconfig/schema.xml b/src/sysconfig/schema.xml new file mode 100644 index 0000000..d729000 --- /dev/null +++ b/src/sysconfig/schema.xml @@ -0,0 +1,35 @@ +<schema package="org.matahariproject"> + + <!-- Config API --> + <class name="Sysconfig"> + <property name="uuid" type="sstr" access="RO" desc="Host UUID" /> + <property name="hostname" type="sstr" access="RO" desc="Hostname" index="y"/> + <property name="is_postboot_configured" type="uint32" access="RO" desc="Check if agent is configured." /> + + <statistic name="qmf-gen-no-crash" type="absTime" desc="Dummy stat to stop qmf-gen from crashing." /> + + <method name="run" desc="Send configure uri method"> + <arg name="uri" dir="I" type="sstr" /> + <arg name="scheme" dir="I" type="sstr" /> + <arg name="key" dir="I" type="sstr" /> + <arg name="flags" dir="I" type="uint32" /> + </method> + + <method name="run_string" desc="Send configure text method"> + <arg name="text" dir="I" type="sstr" /> + <arg name="scheme" dir="I" type="sstr" /> + <arg name="key" dir="I" type="sstr" /> + <arg name="flags" dir="I" type="uint32" /> + </method> + + <method name="query" desc="Perform query lookup"> + <arg name="text" dir="I" type="sstr" /> + <arg name="scheme" dir="I" type="sstr" /> + <arg name="flags" dir="I" type="uint32" /> + </method> + + <method name="is_configured" desc="Check if system is configured"> + <arg name="key" dir="I" type="sstr" /> + </method> + </class> +</schema> diff --git a/src/sysconfig/sysconfig-console.cpp b/src/sysconfig/sysconfig-console.cpp new file mode 100644 index 0000000..920cbd7 --- /dev/null +++ b/src/sysconfig/sysconfig-console.cpp @@ -0,0 +1,79 @@ +/* config-console.cpp - Copyright (c) 2011 Red Hat, Inc. + * Written by Adam Stokes astokes@fedoraproject.org + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef WIN32 +#include "config.h" +#endif + +#include <qpid/messaging/Connection.h> +#include <qpid/messaging/Duration.h> +#include <qmf/ConsoleSession.h> +#include <qmf/ConsoleEvent.h> +#include <qmf/Agent.h> +#include <qmf/Data.h> +#include <qmf/DataAddr.h> +#include <qmf/Query.h> +#include <qpid/types/Variant.h> + +#include <string> +#include <iostream> + +using namespace std; +using namespace qmf; +using qpid::types::Variant; +using qpid::messaging::Duration; + +int main(int argc, char** argv) +{ + string brokerUrl("amqp:tcp:127.0.0.1:49000"); + qpid::types::Variant::Map connectionOptions; + qpid::types::Variant::Map dataProperties; + string sessionOptions; + + connectionOptions["reconnect"] = true; + + dataProperties["uri"] = argv[1] ? argv[1] : "http://localhost/config/uuid"; + + qpid::messaging::Connection connection(brokerUrl, connectionOptions); + connection.open(); + + ConsoleSession session(connection, sessionOptions); + // Only filter connecting agents under matahariproject.org vendor and Config product + session.setAgentFilter("[and, [eq, _vendor, [quote, 'matahariproject.org']], [eq, _product, [quote, 'Sysconfig']]]"); + session.open(); + + Agent agent; + while (true) { + ConsoleEvent event; + if(session.nextEvent(event)) { + switch(event.getType()) { + case CONSOLE_AGENT_ADD: + { + agent = event.getAgent(); + DataAddr agent_event_addr("config", agent.getName(), 0); + ConsoleEvent result(agent.callMethod("configure", + dataProperties, + agent_event_addr)); + } + break; + default: {} + } + } + } + return 0; +} diff --git a/src/sysconfig/sysconfig-qmf.cpp b/src/sysconfig/sysconfig-qmf.cpp new file mode 100644 index 0000000..4cbdd0d --- /dev/null +++ b/src/sysconfig/sysconfig-qmf.cpp @@ -0,0 +1,148 @@ +/* config-qmf.cpp - Copyright (C) 2011 Red Hat, Inc. + * Written by Adam Stokes astokes@fedoraproject.org + * + * 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 Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * \file + * \brief Sysconfig QMF Agent + */ + +#ifndef WIN32 +#include "config.h" +#endif + +#include "matahari/mh_agent.h" + +#include "qmf/org/matahariproject/QmfPackage.h" + +#include <qpid/agent/ManagementAgent.h> + +extern "C" { +#include <stdlib.h> +#include <string.h> +#include <glib.h> +#include <glib/gprintf.h> +#include "matahari/sysconfig.h" +#include "matahari/logging.h" +#include "matahari/network.h" +#include "matahari/host.h" +#include <sigar.h> +#include <sigar_format.h> +}; + +class ConfigAgent : public MatahariAgent +{ +private: + qmf::org::matahariproject::PackageDefinition _package; +public: + virtual int setup(qmf::AgentSession session); + virtual gboolean invoke(qmf::AgentSession session, qmf::AgentEvent event, + gpointer user_data); +}; + +int +main(int argc, char **argv) +{ + ConfigAgent agent; + int rc = agent.init(argc, argv, "Sysconfig"); + if (rc == 0) { + agent.run(); + } + return rc; +} + +int +ConfigAgent::setup(qmf::AgentSession session) +{ + _package.configure(session); + _instance = qmf::Data(_package.data_Sysconfig); + + _instance.setProperty("hostname", mh_hostname()); + _instance.setProperty("uuid", mh_uuid()); + _instance.setProperty("is_postboot_configured", 0); + + _agent_session.addData(_instance, "sysconfig"); + return 0; +} + +static int +is_configured(const char *key, int flags) { + int rc = 0; + + if(flags == FORCE) { + return rc; + } + + return rc; +} + +gboolean +ConfigAgent::invoke(qmf::AgentSession session, qmf::AgentEvent event, gpointer user_data) +{ + int rc = 0; + int flags; + struct conf *cf = NULL; + + + if (event.getType() != qmf::AGENT_METHOD) { + return TRUE; + } + + const std::string& methodName(event.getMethodName()); + + if (methodName == "run") { + flags = event.getArguments()["flags"].asInt32(); + if((is_configured(_instance.getProperty("uuid").asString().c_str(), flags)) == 0) { + rc = mh_sysconfig_run(event.getArguments()["uri"].asString().c_str(), + flags, + event.getArguments()["scheme"].asInt32(), + cf); + } + event.addReturnArgument("configured", rc); + } else if (methodName == "run_string") { + flags = event.getArguments()["flags"].asInt32(); + if((is_configured(_instance.getProperty("uuid").asString().c_str(), flags)) == 0) { + rc = mh_sysconfig_run_string(event.getArguments()["data"].asString().c_str(), + flags, + event.getArguments()["scheme"].asInt32(), + cf); + } + event.addReturnArgument("configured", rc); + } else if (methodName == "query") { + flags = event.getArguments()["flags"].asInt32(); + if((is_configured(_instance.getProperty("uuid").asString().c_str(), flags)) == 0) { + rc = mh_sysconfig_query(event.getArguments()["query"].asString().c_str(), + event.getArguments()["data"].asString().c_str(), + event.getArguments()["scheme"].asInt32(), + flags, + cf); + } + event.addReturnArgument("configured", rc); + } else if (methodName == "is_configured") { + rc = is_configured(event.getArguments()["key"].asString().c_str(), 0); + _instance.setProperty("is_postboot_configured", rc); + event.addReturnArgument("configured", rc); + } else { + session.raiseException(event, MH_NOT_IMPLEMENTED); + goto bail; + } + + session.methodSuccess(event); + +bail: + return TRUE; +} diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 6db157c..8fe81f2 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -5,13 +5,13 @@ if(CXXTEST_FOUND) ENABLE_TESTING() CXXTEST_ADD_TEST(mh_api_network_unittest network_unittest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mh_api_network.h) CXXTEST_ADD_TEST(mh_api_host_unittest host_unittest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mh_api_host.h) - CXXTEST_ADD_TEST(mh_api_postboot_unittest postboot_unittest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mh_api_postboot.h) + CXXTEST_ADD_TEST(mh_api_sysconfig_unittest sysconfig_unittest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mh_api_sysconfig.h) CXXTEST_ADD_TEST(mh_hsa_unittest hsa_unittest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mh_hsa_${VARIANT}.h) add_library(mh_tester SHARED test_utilities.c) - target_link_libraries(mh_tester ${pcre_LIBRARIES} mcommon mnetwork mhost mpostboot) + target_link_libraries(mh_tester ${pcre_LIBRARIES} mcommon mnetwork mhost msysconfig) target_link_libraries(mh_api_network_unittest mh_tester) target_link_libraries(mh_api_host_unittest mh_tester) - target_link_libraries(mh_api_postboot_unittest mh_tester) + target_link_libraries(mh_api_sysconfig_unittest mh_tester) target_link_libraries(mh_hsa_unittest mh_tester) endif(CXXTEST_FOUND)
diff --git a/src/tests/mh_api_sysconfig.h b/src/tests/mh_api_sysconfig.h new file mode 100644 index 0000000..48cadfa --- /dev/null +++ b/src/tests/mh_api_sysconfig.h @@ -0,0 +1,35 @@ +#ifndef __MH_API_NETWORK_UNITTEST_H +#define __MH_API_NETWORK_UNITTEST_H +#include <iostream> +#include <string> +#include <sstream> +#include <utility> +#include <vector> +#include <cstdlib> +#include <cstdio> +#include <sys/stat.h> +#include <dirent.h> +#include <cxxtest/TestSuite.h> + +extern "C" { +#include "matahari/sysconfig.h" +#include <glib.h> +#include "mh_test_utilities.h" +}; + +using namespace std; + +class MhApisysconfigSuite : public CxxTest::TestSuite +{ + public: + + void testIsConfigured(void) + { + const char *uri = "http://matahariproject.org/atom.xml"; + struct conf *cf = NULL; + + TS_ASSERT((mh_sysconfig_run(uri, PUPPET, 0, cf)) != -1); + } +}; + +#endif