diff mbox series

[2/3] suricatta: Adapt modules to run-time selection

Message ID 20230509080726.23738-2-christian.storm@siemens.com
State Accepted
Headers show
Series [1/3] suricatta: Suricatta module run-time selection | expand

Commit Message

Storm, Christian May 9, 2023, 8:07 a.m. UTC
Adapt suricatta modules to run-time selection.

Signed-off-by: Christian Storm <christian.storm@siemens.com>
---
 suricatta/server_general.c | 50 ++++++++++++++++++++-------------
 suricatta/server_general.h |  1 -
 suricatta/server_hawkbit.c | 57 +++++++++++++++++++++++---------------
 suricatta/server_hawkbit.h |  3 ++
 suricatta/server_lua.c     | 47 +++++++++++++++++--------------
 test/test_server_hawkbit.c | 15 +++++-----
 6 files changed, 101 insertions(+), 72 deletions(-)
diff mbox series

Patch

diff --git a/suricatta/server_general.c b/suricatta/server_general.c
index e7a8c301..1c8e777e 100644
--- a/suricatta/server_general.c
+++ b/suricatta/server_general.c
@@ -25,6 +25,7 @@ 
 #include <sys/time.h>
 #include <swupdate_status.h>
 #include "suricatta/suricatta.h"
+#include "suricatta/server.h"
 #include "suricatta_private.h"
 #include "parselib.h"
 #include "channel.h"
@@ -39,16 +40,6 @@ 
 #include <pctl.h>
 #include <pthread.h>
 
-/* Prototypes for "public" functions */
-void server_print_help(void);
-server_op_res_t server_has_pending_action(int *action_id);
-server_op_res_t server_stop(void);
-server_op_res_t server_ipc(ipc_message *msg);
-server_op_res_t server_start(char *fname, int argc, char *argv[]);
-server_op_res_t server_install_update(void);
-server_op_res_t server_send_target_data(void);
-unsigned int server_get_polling_interval(void);
-
 /*
  * This is a "specialized" map_http_retcode() because
  * the return codes are interpreted
@@ -66,6 +57,7 @@  static struct option long_options[] = {
     {"retrywait", required_argument, NULL, 'w'},
     {"cache", required_argument, NULL, '2'},
     {"max-download-speed", required_argument, NULL, 'n'},
+    {"server", required_argument, NULL, 'S'},
     {NULL, 0, NULL, 0}};
 
 static unsigned short mandatory_argument_count = 0;
@@ -483,7 +475,7 @@  static server_op_res_t server_get_deployment_info(channel_t *channel, channel_da
 	return result;
 }
 
-server_op_res_t server_has_pending_action(int *action_id)
+static server_op_res_t server_has_pending_action(int *action_id)
 {
 	*action_id = 0;
 
@@ -497,17 +489,17 @@  server_op_res_t server_has_pending_action(int *action_id)
 					  &channel_data);
 }
 
-server_op_res_t server_send_target_data(void)
+static server_op_res_t server_send_target_data(void)
 {
 	return SERVER_OK;
 }
 
-unsigned int server_get_polling_interval(void)
+static unsigned int server_get_polling_interval(void)
 {
 	return server_general.polling_interval;
 }
 
-void server_print_help(void)
+static void server_print_help(void)
 {
 	fprintf(
 	    stdout,
@@ -529,7 +521,7 @@  void server_print_help(void)
 	    CHANNEL_DEFAULT_RESUME_DELAY);
 }
 
-server_op_res_t server_install_update(void)
+static server_op_res_t server_install_update(void)
 {
 	channel_data_t channel_data = channel_data_defaults;
 	server_op_res_t result = SERVER_OK;
@@ -605,7 +597,7 @@  static int server_general_settings(void *elem, void  __attribute__ ((__unused__)
 	return 0;
 }
 
-server_op_res_t server_start(char *fname, int argc, char *argv[])
+static server_op_res_t server_start(const char *fname, int argc, char *argv[])
 {
 	int choice = 0;
 
@@ -629,7 +621,7 @@  server_op_res_t server_start(char *fname, int argc, char *argv[])
 	/* reset to optind=1 to parse suricatta's argument vector */
 	optind = 1;
 	opterr = 0;
-	while ((choice = getopt_long(argc, argv, "u:l:r:w:p:2:a:n",
+	while ((choice = getopt_long(argc, argv, "u:l:r:w:p:2:a:nS:",
 				     long_options, NULL)) != -1) {
 		switch (choice) {
 		case 'u':
@@ -671,6 +663,9 @@  server_op_res_t server_start(char *fname, int argc, char *argv[])
 				(unsigned int)ustrtoull(optarg, NULL, 10);
 			break;
 
+		/* Ignore the --server option which is already parsed by the caller. */
+		case 'S':
+			break;
 		case '?':
 		/* Ignore not recognized options, they can be already parsed by the caller */
 		default:
@@ -713,7 +708,7 @@  server_op_res_t server_start(char *fname, int argc, char *argv[])
 	return SERVER_OK;
 }
 
-server_op_res_t server_stop(void)
+static server_op_res_t server_stop(void)
 {
 	(void)server_general.channel->close(server_general.channel);
 	free(server_general.channel);
@@ -721,7 +716,24 @@  server_op_res_t server_stop(void)
 	return SERVER_OK;
 }
 
-server_op_res_t server_ipc(ipc_message __attribute__ ((__unused__)) *msg)
+static server_op_res_t server_ipc(ipc_message __attribute__ ((__unused__)) *msg)
 {
 	return SERVER_OK;
 }
+
+static server_t server = {
+	.has_pending_action = &server_has_pending_action,
+	.install_update = &server_install_update,
+	.send_target_data = &server_send_target_data,
+	.get_polling_interval = &server_get_polling_interval,
+	.start = &server_start,
+	.stop = &server_stop,
+	.ipc = &server_ipc,
+	.help = &server_print_help,
+};
+
+__attribute__((constructor))
+static void register_server_general(void)
+{
+	register_server("general", &server);
+}
diff --git a/suricatta/server_general.h b/suricatta/server_general.h
index d5d8d48f..3a3ef4f7 100644
--- a/suricatta/server_general.h
+++ b/suricatta/server_general.h
@@ -29,4 +29,3 @@  typedef struct {
 	channel_t *channel;
 } server_general_t;
 
-extern server_general_t server_general;
diff --git a/suricatta/server_hawkbit.c b/suricatta/server_hawkbit.c
index 5a456e11..726ef191 100644
--- a/suricatta/server_hawkbit.c
+++ b/suricatta/server_hawkbit.c
@@ -21,6 +21,7 @@ 
 #include <swupdate_status.h>
 #include <pthread.h>
 #include "suricatta/suricatta.h"
+#include "suricatta/server.h"
 #include "suricatta_private.h"
 #include "parselib.h"
 #include "channel.h"
@@ -51,6 +52,7 @@  static struct option long_options[] = {
     {"disable-token-for-dwl", no_argument, NULL, '1'},
     {"cache", required_argument, NULL, '2'},
     {"initial-report-resend-period", required_argument, NULL, 'm'},
+    {"server", required_argument, NULL, 'S'},
 	{"connection-timeout", required_argument, NULL, 's'},
 	{"custom-http-header", required_argument, NULL, 'a'},
 	{"max-download-speed", required_argument, NULL, 'l'},
@@ -90,19 +92,17 @@  static hawkbit_enums_t hawkbit_enums[] = {
 
 extern channel_op_res_t channel_curl_init(void);
 /* Prototypes for "internal" functions */
-/* Note that they're not `static` so that they're callable from unit tests. */
-server_op_res_t server_handle_initial_state(update_state_t stateovrrd);
+/* Note that the non-`static` functions are called from unit tests. */
+static server_op_res_t server_handle_initial_state(update_state_t stateovrrd);
 static int server_update_status_callback(ipc_message *msg);
-int server_update_done_callback(RECOVERY_STATUS status);
 server_op_res_t server_process_update_artifact(int action_id,
 						json_object *json_data_artifact,
 						const char *update_action,
 						const char *part,
 						const char *version,
 						const char *name);
-void server_print_help(void);
 server_op_res_t server_set_polling_interval_json(json_object *json_root);
-server_op_res_t server_set_config_data(json_object *json_root);
+static server_op_res_t server_set_config_data(json_object *json_root);
 server_op_res_t
 server_send_deployment_reply(channel_t *channel,
 			     const int action_id, const int job_cnt_max,
@@ -146,15 +146,6 @@  static channel_data_t channel_data_defaults = {.debug = false,
 
 static struct timeval server_time;
 
-/* Prototypes for "public" functions */
-server_op_res_t server_has_pending_action(int *action_id);
-server_op_res_t server_stop(void);
-server_op_res_t server_ipc(ipc_message *msg);
-server_op_res_t server_start(char *fname, int argc, char *argv[]);
-server_op_res_t server_install_update(void);
-server_op_res_t server_send_target_data(void);
-unsigned int server_get_polling_interval(void);
-
 /*
  * Just called once to setup the tokens
  */
@@ -503,7 +494,7 @@  server_op_res_t server_set_polling_interval_json(json_object *json_root)
 	return SERVER_OK;
 }
 
-unsigned int server_get_polling_interval(void)
+static unsigned int server_get_polling_interval(void)
 {
 	return server_hawkbit.polling_interval;
 }
@@ -741,7 +732,7 @@  static size_t server_check_during_dwl(char  __attribute__ ((__unused__)) *stream
 	return ret;
 }
 
-server_op_res_t server_has_pending_action(int *action_id)
+static server_op_res_t server_has_pending_action(int *action_id)
 {
 
 	channel_data_t channel_data = channel_data_defaults;
@@ -1285,7 +1276,7 @@  cleanup:
 	return result;
 }
 
-server_op_res_t server_install_update(void)
+static server_op_res_t server_install_update(void)
 {
 	int action_id;
 	channel_data_t channel_data = channel_data_defaults;
@@ -1503,7 +1494,7 @@  int get_target_data_length(bool locked)
 	return len;
 }
 
-server_op_res_t server_send_target_data(void)
+static server_op_res_t server_send_target_data(void)
 {
 	channel_t *channel = server_hawkbit.channel;
 	struct dict_entry *entry;
@@ -1619,7 +1610,7 @@  cleanup:
 	return result;
 }
 
-void server_print_help(void)
+static void server_print_help(void)
 {
 	fprintf(
 	    stdout,
@@ -1701,7 +1692,7 @@  static int server_hawkbit_settings(void *elem, void  __attribute__ ((__unused__)
 
 }
 
-server_op_res_t server_start(char *fname, int argc, char *argv[])
+static server_op_res_t server_start(const char *fname, int argc, char *argv[])
 {
 	update_state_t update_state = STATE_NOT_AVAILABLE;
 	int choice = 0;
@@ -1743,7 +1734,7 @@  server_op_res_t server_start(char *fname, int argc, char *argv[])
 	/* reset to optind=1 to parse suricatta's argument vector */
 	optind = 1;
 	opterr = 0;
-	while ((choice = getopt_long(argc, argv, "t:i:c:u:p:xr:y::w:k:g:f:2:m:s:a:n:",
+	while ((choice = getopt_long(argc, argv, "t:i:c:u:p:xr:y::w:k:g:f:2:m:s:a:n:S:",
 				     long_options, NULL)) != -1) {
 		switch (choice) {
 		case 't':
@@ -1853,6 +1844,9 @@  server_op_res_t server_start(char *fname, int argc, char *argv[])
 		/* Ignore not recognized options, they can be already parsed by the caller */
 		case '?':
 			break;
+		/* Ignore the --server option which is already parsed by the caller. */
+		case 'S':
+			break;
 		}
 	}
 
@@ -1932,7 +1926,7 @@  server_op_res_t server_start(char *fname, int argc, char *argv[])
 	return SERVER_OK;
 }
 
-server_op_res_t server_stop(void)
+static server_op_res_t server_stop(void)
 {
 	(void)server_hawkbit.channel->close(server_hawkbit.channel);
 	free(server_hawkbit.channel);
@@ -2122,7 +2116,7 @@  static server_op_res_t server_status_ipc(ipc_message *msg)
 	return SERVER_OK;
 }
 
-server_op_res_t server_ipc(ipc_message *msg)
+static server_op_res_t server_ipc(ipc_message *msg)
 {
 	server_op_res_t result = SERVER_OK;
 
@@ -2150,3 +2144,20 @@  server_op_res_t server_ipc(ipc_message *msg)
 
 	return SERVER_OK;
 }
+
+server_t server_hawkbit_funcs = {
+	.has_pending_action = &server_has_pending_action,
+	.install_update = &server_install_update,
+	.send_target_data = &server_send_target_data,
+	.get_polling_interval = &server_get_polling_interval,
+	.start = &server_start,
+	.stop = &server_stop,
+	.ipc = &server_ipc,
+	.help = &server_print_help,
+};
+
+__attribute__((constructor))
+static void register_server_hawkbit(void)
+{
+	register_server("hawkbit", &server_hawkbit_funcs);
+}
diff --git a/suricatta/server_hawkbit.h b/suricatta/server_hawkbit.h
index 86627ee2..5f995aca 100644
--- a/suricatta/server_hawkbit.h
+++ b/suricatta/server_hawkbit.h
@@ -10,6 +10,7 @@ 
 #include <state.h>
 #include <swupdate_dict.h>
 #include <channel.h>
+#include "suricatta/server.h"
 
 /* Have a queue for errors reported by installer */
 #define HAWKBIT_MAX_REPORTED_ERRORS	10
@@ -51,6 +52,8 @@  typedef struct {
 
 extern server_hawkbit_t server_hawkbit;
 
+extern server_t server_hawkbit_funcs;
+
 static const struct {
 	const char *closed;
 	const char *proceeding;
diff --git a/suricatta/server_lua.c b/suricatta/server_lua.c
index 7209120e..579ddc70 100644
--- a/suricatta/server_lua.c
+++ b/suricatta/server_lua.c
@@ -34,6 +34,7 @@ 
 #include <swupdate_settings.h>
 #include <swupdate_dict.h>
 #include "suricatta_private.h"
+#include "suricatta/server.h"
 
 #define CONFIG_SECTION "suricatta"
 
@@ -77,19 +78,6 @@  static channel_data_t channel_data_defaults = {
 	.source = SOURCE_SURICATTA,
 };
 
-/*
- * Prototypes for "public" functions implementing the server
- * interface specified in include/suricatta/server.h.
- */
-void server_print_help(void);
-unsigned int server_get_polling_interval(void);
-server_op_res_t server_has_pending_action(int *action_id);
-server_op_res_t server_start(char *fname, int argc, char *argv[]);
-server_op_res_t server_stop(void);
-server_op_res_t server_install_update(void);
-server_op_res_t server_ipc(ipc_message *msg);
-server_op_res_t server_send_target_data(void);
-
 /* Global Lua state for this Suricatta Lua module implementation. */
 static lua_State *gL = NULL;
 
@@ -1827,7 +1815,7 @@  static int config_section_to_table(void *setting, void *data)
  * @param  argv   The array of arguments.
  * @return SERVER_OK, or, in case of errors, SERVER_EINIT or SERVER_EERR.
  */
-server_op_res_t server_start(char *fname, int argc, char *argv[])
+static server_op_res_t server_start(const char *fname, int argc, char *argv[])
 {
 	if (suricatta_lua_create() != SERVER_OK) {
 		suricatta_lua_destroy();
@@ -1873,7 +1861,7 @@  server_op_res_t server_start(char *fname, int argc, char *argv[])
  *
  * @return SERVER_OK or, in case of errors, any other from server_op_res_t.
  */
-server_op_res_t server_stop(void)
+static server_op_res_t server_stop(void)
 {
 	server_op_res_t result = map_lua_result(
 	    call_lua_func(gL, SURICATTA_FUNC_SERVER_STOP, 0));
@@ -1885,7 +1873,7 @@  server_op_res_t server_stop(void)
 /**
  * @brief Print the Suricatta Lua module's help text.
  */
-void server_print_help(void)
+static void server_print_help(void)
 {
 	if (suricatta_lua_create() != SERVER_OK) {
 		fprintf(stderr, "Error loading Suricatta Lua module.\n");
@@ -1908,7 +1896,7 @@  void server_print_help(void)
  *
  * @return Polling interval in seconds.
  */
-unsigned int server_get_polling_interval(void)
+static unsigned int server_get_polling_interval(void)
 {
 	int result = call_lua_func(gL, SURICATTA_FUNC_GET_POLLING_INTERVAL, 0);
 	return result >= 0 ? (unsigned int)result : CHANNEL_DEFAULT_POLLING_INTERVAL;
@@ -1923,7 +1911,7 @@  unsigned int server_get_polling_interval(void)
  *         in suricatta/suricatta.c, the others result in suricatta
  *         sleeping again.
  */
-server_op_res_t server_has_pending_action(int *action_id)
+static server_op_res_t server_has_pending_action(int *action_id)
 {
 	lua_pushnumber(gL, *action_id);
 	server_op_res_t result = map_lua_result(
@@ -1945,7 +1933,7 @@  server_op_res_t server_has_pending_action(int *action_id)
  *
  * @return SERVER_OK or, in case of errors, any other from server_op_res_t.
  */
-server_op_res_t server_install_update(void)
+static server_op_res_t server_install_update(void)
 {
 	return map_lua_result(call_lua_func(gL, SURICATTA_FUNC_INSTALL_UPDATE, 0));
 }
@@ -1956,7 +1944,7 @@  server_op_res_t server_install_update(void)
  *
  * @return SERVER_OK or, in case of errors, any other from server_op_res_t.
  */
-server_op_res_t server_send_target_data(void)
+static server_op_res_t server_send_target_data(void)
 {
 	return map_lua_result(call_lua_func(gL, SURICATTA_FUNC_SEND_TARGET_DATA, 0));
 }
@@ -1968,7 +1956,7 @@  server_op_res_t server_send_target_data(void)
  * @param  msg  IPC message.
  * @return SERVER_OK or, in case of errors, any other from server_op_res_t.
  */
-server_op_res_t server_ipc(ipc_message *msg)
+static server_op_res_t server_ipc(ipc_message *msg)
 {
 	lua_newtable(gL);
 	push_to_table(gL, "magic",      msg->magic);
@@ -2014,3 +2002,20 @@  server_op_res_t server_ipc(ipc_message *msg)
 	}
 	return result;
 }
+
+static server_t server = {
+	.has_pending_action = &server_has_pending_action,
+	.install_update = &server_install_update,
+	.send_target_data = &server_send_target_data,
+	.get_polling_interval = &server_get_polling_interval,
+	.start = &server_start,
+	.stop = &server_stop,
+	.ipc = &server_ipc,
+	.help = &server_print_help,
+};
+
+__attribute__((constructor))
+static void register_server_lua(void)
+{
+	register_server("lua", &server);
+}
diff --git a/test/test_server_hawkbit.c b/test/test_server_hawkbit.c
index c5f558be..fc4bb8f5 100644
--- a/test/test_server_hawkbit.c
+++ b/test/test_server_hawkbit.c
@@ -118,7 +118,6 @@  update_state_t __wrap_get_state(void)
 	return mock_type(update_state_t);
 }
 
-extern server_op_res_t server_has_pending_action(int *action_id);
 static void test_server_has_pending_action(void **state)
 {
 	(void)state;
@@ -194,7 +193,7 @@  static void test_server_has_pending_action(void **state)
 		    json_tokener_parse(json_reply_no_update));
 	will_return(__wrap_channel_get, CHANNEL_OK);
 	assert_int_equal(SERVER_NO_UPDATE_AVAILABLE,
-			 server_has_pending_action(&action_id));
+		server_hawkbit_funcs.has_pending_action(&action_id));
 
 	/* Test Case: Update Action available && !STATE_INSTALLED. */
 	will_return(__wrap_channel_get,
@@ -205,7 +204,7 @@  static void test_server_has_pending_action(void **state)
 	will_return(__wrap_channel_get, CHANNEL_OK);
 	will_return(__wrap_get_state, STATE_NOT_AVAILABLE);
 	assert_int_equal(SERVER_UPDATE_AVAILABLE,
-			 server_has_pending_action(&action_id));
+		server_hawkbit_funcs.has_pending_action(&action_id));
 
 	/* Test Case: Update Action available && STATE_INSTALLED. */
 	will_return(__wrap_channel_get,
@@ -216,7 +215,7 @@  static void test_server_has_pending_action(void **state)
 	will_return(__wrap_channel_get, CHANNEL_OK);
 	will_return(__wrap_get_state, STATE_INSTALLED);
 	assert_int_equal(SERVER_NO_UPDATE_AVAILABLE,
-			 server_has_pending_action(&action_id));
+		server_hawkbit_funcs.has_pending_action(&action_id));
 
 	/* Test Case: Cancel Action available. */
 	will_return(__wrap_channel_get,
@@ -227,7 +226,8 @@  static void test_server_has_pending_action(void **state)
 	will_return(__wrap_channel_get, CHANNEL_OK);
 	will_return(__wrap_channel_put, CHANNEL_OK);
 	will_return(__wrap_save_state, 0);
-	assert_int_equal(SERVER_OK, server_has_pending_action(&action_id));
+	assert_int_equal(SERVER_OK,
+		server_hawkbit_funcs.has_pending_action(&action_id));
 }
 
 extern server_op_res_t server_set_polling_interval_json(json_object *json_root);
@@ -374,7 +374,6 @@  static void test_server_process_update_artifact(void **state)
 #endif
 }
 
-extern server_op_res_t server_install_update(void);
 static void test_server_install_update(void **state)
 {
 	(void)state;
@@ -496,7 +495,7 @@  static void test_server_install_update(void **state)
 	will_return(__wrap_channel_get, CHANNEL_OK);
 	will_return(__wrap_channel_put, CHANNEL_OK);
 	will_return(__wrap_channel_put, CHANNEL_OK);
-	server_install_update();
+	server_hawkbit_funcs.install_update();
 
 	/* Test Case: Update works. */
 	json_data_update_available =
@@ -523,7 +522,7 @@  static void test_server_install_update(void **state)
 	will_return(__wrap_channel_put, CHANNEL_OK);
 	//will_return(__wrap_save_state, SERVER_OK);
 	will_return(__wrap_channel_put, CHANNEL_OK);
-	assert_int_equal(SERVER_OK, server_install_update());
+	assert_int_equal(SERVER_OK, server_hawkbit_funcs.install_update());
 }
 
 static int server_hawkbit_setup(void **state)