diff mbox series

[2/3] suricatta/lua: Expose bootloader interface

Message ID 20221128112326.27564-2-christian.storm@siemens.com
State Changes Requested
Headers show
Series [1/3] bootloader: Add is_bootloader() to distinguish bootloaders | expand

Commit Message

Christian Storm Nov. 28, 2022, 11:23 a.m. UTC
Expose SWUpdate's bootloader interface to suricatta Lua modules.

Signed-off-by: Christian Storm <christian.storm@siemens.com>
---
 doc/source/bootloader_interface.rst |   4 +
 suricatta/server_lua.c              | 109 ++++++++++++++++++++++++++++
 suricatta/suricatta.lua             |  56 ++++++++++++++
 3 files changed, 169 insertions(+)
diff mbox series

Patch

diff --git a/doc/source/bootloader_interface.rst b/doc/source/bootloader_interface.rst
index b8c0182..8527aec 100644
--- a/doc/source/bootloader_interface.rst
+++ b/doc/source/bootloader_interface.rst
@@ -93,6 +93,10 @@  with
 
 added to ``include/bootloader.h`` as a single central "trunk" bootloader
 name definition aiding in maintaining the uniqueness of bootloader names.
+This new "trunk" bootloader should also be added to the Suricatta Lua
+Module interface specification's bootloader Table
+``suricatta.bootloader.bootloaders = { ... }`` in
+``suricatta/suricatta.lua``.
 
 
 .. attention:: Take care to uniquely name the bootloader.
diff --git a/suricatta/server_lua.c b/suricatta/server_lua.c
index 6dcf938..3d4bf70 100644
--- a/suricatta/server_lua.c
+++ b/suricatta/server_lua.c
@@ -30,6 +30,7 @@ 
 #include <swupdate.h>
 #include <parselib.h>
 #include <state.h>
+#include <bootloader.h>
 #include <swupdate_settings.h>
 #include <swupdate_dict.h>
 #include "suricatta_private.h"
@@ -1388,6 +1389,85 @@  failure:
 	return 2;
 }
 
+/**
+ * @brief Test whether a bootloader is currently set.
+ *
+ * @param  [Lua] Name of bootloader to test for being currently set.
+ * @return [Lua] True if given name is the currently set bootloader, false otherwise.
+ */
+static int lua_bootloader_is(lua_State *L)
+{
+	lua_pushboolean(L, is_bootloader(luaL_checkstring(L, -1)));
+	return 1;
+}
+
+/**
+ * @brief Get currently set bootloader's name.
+ *
+ * @return [Lua] Name of currently set bootloader.
+ */
+static int lua_bootloader_get(lua_State *L)
+{
+	(void)lua_pushstring(L, get_bootloader());
+	return 1;
+}
+
+/**
+ * @brief Get value of a bootloader environment variable.
+ *
+ * @param  [Lua] Name of the bootloader environment variable to get value of.
+ * @return [Lua] Value of the bootloader environment variable.
+ */
+static int lua_bootloader_env_get(lua_State *L)
+{
+	char* value = bootloader_env_get(luaL_checkstring(L, -1));
+	(void)lua_pushstring(L, value);
+	free(value);
+	return 1;
+}
+
+/**
+ * @brief Set value of a bootloader environment variable.
+ *
+ * @param  [Lua] Name of the bootloader environment variable to set.
+ * @param  [Lua] Value to set the bootloader environment variable to.
+ * @return [Lua] True, or, in case of error, nil.
+ */
+static int lua_bootloader_env_set(lua_State *L)
+{
+	bootloader_env_set(luaL_checkstring(L, -2), luaL_checkstring(L, -1)) == 0
+		? lua_pushboolean(L, true)
+		: lua_pushnil(L);
+	return 1;
+}
+
+/**
+ * @brief Drop a bootloader environment variable.
+ *
+ * @param  [Lua] Name of the bootloader environment variable to drop.
+ * @return [Lua] True, or, in case of error, nil.
+ */
+static int lua_bootloader_env_unset(lua_State *L)
+{
+	bootloader_env_unset(luaL_checkstring(L, -1)) == 0
+		? lua_pushboolean(L, true)
+		: lua_pushnil(L);
+	return 1;
+}
+
+/**
+ * @brief Set multiple bootloader environment variables from local file.
+ *
+ * @param  [Lua] Path to local file in format `<variable>=<value>`.
+ * @return [Lua] True, or, in case of error, nil.
+ */
+static int lua_bootloader_env_apply(lua_State *L)
+{
+	bootloader_apply_list(luaL_checkstring(L, -1)) == 0
+		? lua_pushboolean(L, true)
+		: lua_pushnil(L);
+	return 1;
+}
 
 /**
  * @brief Get update state from persistent storage (bootloader).
@@ -1479,6 +1559,35 @@  static int suricatta_lua_module(lua_State *L)
 	#undef MAP
 	lua_settable(L, -3);
 
+	luaL_Reg lua_funcs_bootloader[] = {
+		{ "is",  lua_bootloader_is  },
+		{ "get", lua_bootloader_get },
+		{ NULL, NULL }
+	};
+	luaL_Reg lua_funcs_bootloader_env[] = {
+		{ "get",   lua_bootloader_env_get   },
+		{ "set",   lua_bootloader_env_set   },
+		{ "unset", lua_bootloader_env_unset },
+		{ "apply", lua_bootloader_env_apply },
+		{ NULL, NULL }
+	};
+	lua_pushstring(L, "bootloader");
+	lua_newtable(L);
+	luaL_setfuncs(L, lua_funcs_bootloader, 0);
+	lua_pushstring(L, "bootloaders");
+	lua_newtable(L);
+	push_to_table(L, "EBG",   BOOTLOADER_EBG);
+	push_to_table(L, "NONE",  BOOTLOADER_NONE);
+	push_to_table(L, "GRUB",  BOOTLOADER_GRUB);
+	push_to_table(L, "UBOOT", BOOTLOADER_UBOOT);
+	lua_settable(L, -3);
+	lua_pushstring(L, "env");
+	lua_newtable(L);
+	luaL_setfuncs(L, lua_funcs_bootloader_env, 0);
+	lua_settable(L, -3);
+
+	lua_settable(L, -3);
+
 	lua_pushstring(L, "status");
 	lua_newtable(L);
 	push_to_table(L, "OK",                  SERVER_OK);
diff --git a/suricatta/suricatta.lua b/suricatta/suricatta.lua
index 81988d2..bfcb3be 100644
--- a/suricatta/suricatta.lua
+++ b/suricatta/suricatta.lua
@@ -58,6 +58,62 @@  suricatta.notify = {
 }
 
 
+--- SWUpdate's bootloader interface as in `include/bootloader.h`.
+--
+--- @class suricatta.bootloader
+suricatta.bootloader = {
+    --- Bootloaders supported by SWUpdate.
+    --
+    --- @enum suricatta.bootloader.bootloaders
+    bootloaders = {
+        EBG   = "ebg",
+        NONE  = "none",
+        GRUB  = "grub",
+        UBOOT = "uboot",
+    },
+    --- Operations on the currently set bootloader's environment.
+    --
+    --- @class suricatta.bootloader.env
+    env = {}
+}
+
+--- Get currently set bootloader's name.
+--
+--- @return suricatta.bootloader.bootloaders | nil  # Name of currently set bootloader
+suricatta.bootloader.get = function() end
+
+--- Test whether bootloader `name` is currently set.
+--
+--- @param  name     suricatta.bootloader.bootloaders  Name of bootloader to test for being currently selected
+--- @return boolean                                    # True if `name` is currently set bootloader, false otherwise
+suricatta.bootloader.is = function(name) end
+
+--- Get value of a bootloader environment variable.
+--
+--- @param  variable  string  Name of the bootloader environment variable to get value for
+--- @return string | nil      # Value of the bootloader environment variable or nil if non-existent
+suricatta.bootloader.env.get = function(variable) end
+
+--- Set value of a bootloader environment variable.
+--
+--- @param  variable  string  Name of the bootloader environment variable to set
+--- @param  value     string  Value to set the bootloader environment variable `variable` to
+--- @return boolean | nil     # True on success, nil on error
+suricatta.bootloader.env.set = function(variable, value) end
+
+--- Drop a bootloader environment variable.
+--
+--- @param  variable  string  Name of the bootloader environment variable to drop
+--- @return boolean | nil     # True on success, nil on error
+suricatta.bootloader.env.unset = function(variable) end
+
+--- Set multiple bootloader environment variables from local file.
+--
+--- @param  filename  string  Path to local file in format `<variable>=<value>`
+--- @return boolean | nil     # True on success, nil on error
+suricatta.bootloader.env.apply = function(filename) end
+
+
 --- SWUpdate's persistent state IDs as in `include/state.h` and reverse-lookup.
 --
 --- @enum suricatta.pstate