Added ConfigScope in Firmware management

This commit is contained in:
Vivek Dutta 2025-11-04 20:00:12 +05:30 committed by IOPSYS Dev
parent 9ebc556a65
commit 0d0cef8a18
No known key found for this signature in database
4 changed files with 171 additions and 66 deletions

View file

@ -2,10 +2,11 @@
# Script to activate image in specified time.
#
# Copyright © 2022 IOPSYS Software Solutions AB
# Copyright © 2022 - 2025 IOPSYS Software Solutions AB
# Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
#
. /usr/share/libubox/jshn.sh
ROOT="$(dirname "${0}")"
CHECK_IDLE_FILE="${ROOT}/bbf_check_idle.sh"
@ -18,8 +19,10 @@ log() {
}
activate_and_reboot_device() {
local bank_id="${1}"
local keep_config="${2:-1}"
local bank_id="${1}"; shift
local keep_settings="${1}"; shift
local keep_opconf="${1}"; shift
local config_scope="${1}"; shift
local success
success=$(ubus call fwbank set_bootbank "{'bank':${bank_id}}" | jsonfilter -e @.success)
@ -28,12 +31,15 @@ activate_and_reboot_device() {
exit 1
fi
if [ "${keep_config}" = "1" ]; then
success=$(/etc/sysmngr/fwbank call copy_config 2> /dev/null | jsonfilter -e @.success)
if [ "${success}" != "true" ]; then
log "Can't copy config"
exit 1
fi
json_init
[ -n "${keep_settings}" ] && json_add_boolean "keep_settings" "${keep_settings}"
[ -n "${keep_opconf}" ] && json_add_boolean "keep_opconf" "${keep_opconf}"
[ -n "${config_scope}" ] && json_add_string "config_scope" "${config_scope}"
success=$(json_dump| /etc/sysmngr/fwbank call copy_config 2> /dev/null | jsonfilter -e @.success)
if [ "${success}" != "true" ]; then
log "Can't copy config"
exit 1
fi
log "The device will restart after a few seconds"
@ -45,16 +51,18 @@ handle_whenidle_mode() {
local bank_id="${1}"
local end_time="${2}"
local force_activation="${3}"
local keep_config="${4}"
local keep_settings="${4}"
local keep_opconf="${5}"
local config_scope="${6}"
local diff=0
[ ! -x "${CHECK_IDLE_FILE}" ] && {
activate_and_reboot_device "${bank_id}" "${keep_config}"
activate_and_reboot_device "${bank_id}" "${keep_settings}" "${keep_opconf}" "${config_scope}"
}
sh "${CHECK_IDLE_FILE}"
if [ "$?" = "0" ]; then
activate_and_reboot_device "${bank_id}" "${keep_config}"
activate_and_reboot_device "${bank_id}" "${keep_settings}" "${keep_opconf}" "${config_scope}"
else
[ "${end_time}" -gt "$((diff + RETRY_TIME))" ] && {
sleep "${RETRY_TIME}"
@ -66,7 +74,7 @@ handle_whenidle_mode() {
while [ "${end_time}" -gt "${diff}" ]; do
sh "${CHECK_IDLE_FILE}"
if [ "$?" = "0" ]; then
activate_and_reboot_device "${bank_id}" "${keep_config}"
activate_and_reboot_device "${bank_id}" "${keep_settings}" "${keep_opconf}" "${config_scope}"
else
if [ "${end_time}" -gt "$((diff + RETRY_TIME))" ]; then
@ -81,7 +89,7 @@ handle_whenidle_mode() {
done
[ "${force_activation}" = "1" ] && {
activate_and_reboot_device "${bank_id}" "${keep_config}"
activate_and_reboot_device "${bank_id}" "${keep_settings}" "${keep_opconf}" "${config_scope}"
}
}
@ -92,7 +100,7 @@ handle_confirmation_needed_mode() {
}
######################## main ########################
if [ "$#" -lt "6" ]; then
if [ "$#" -lt "8" ]; then
log "Invalid inputs [$*]"
exit 1
fi
@ -103,14 +111,16 @@ ENDTIME="${1}"; shift
LASTWINDOW="${1}"; shift
MAXRETRIES="${1}"; shift
KEEPCONFIG="${1}"; shift
KEEPOPCONF="${1}"; shift
CONFIGSCOPE="${1}"; shift
MSG="$*"
if [ "${MODE}" = "Immediately" ] || [ "${MODE}" = "AnyTime" ]; then
activate_and_reboot_device "${BANKID}" "${KEEPCONFIG}"
activate_and_reboot_device "${BANKID}" "${KEEPCONFIG}" "${KEEPOPCONF}" "${CONFIGSCOPE}"
elif [ "${MODE}" = "WhenIdle" ]; then
handle_whenidle_mode "${BANKID}" "${ENDTIME}" "${LASTWINDOW}" "${KEEPCONFIG}"
handle_whenidle_mode "${BANKID}" "${ENDTIME}" "${LASTWINDOW}" "${KEEPCONFIG}" "${KEEPOPCONF}" "${CONFIGSCOPE}"
elif [ "${MODE}" = "ConfirmationNeeded" ]; then
handle_confirmation_needed_mode "${BANKID}" "${ENDTIME}" "${LASTWINDOW}" "${MAXRETRIES}" "${KEEPCONFIG}" "${MSG}"
handle_confirmation_needed_mode "${BANKID}" "${ENDTIME}" "${LASTWINDOW}" "${MAXRETRIES}" "${KEEPCONFIG}" "${KEEPOPCONF}" "${CONFIGSCOPE}" "${MSG}"
else
log "[${MODE}] mode is not supported"
exit 1

View file

@ -30,12 +30,13 @@ struct fw_download_data {
char *obj_path;
char *commandKey;
char *keep_config;
char *keep_opconf;
char *config_scope;
char *requestor;
};
#define CRONTABS_ROOT "/etc/crontabs/root"
#define ACTIVATE_HANDLER_FILE "/usr/share/bbfdm/scripts/bbf_activate_handler.sh"
#define COPY_CONFIG_CMD "/etc/sysmngr/fwbank call copy_config 2> /dev/null"
#define MAX_TIME_WINDOW 5
/*************************************************************
@ -111,11 +112,39 @@ static char *get_fwbank_bank_id(const char *option_name)
return bank_id ? bank_id : "";
}
static void fwbank_copy_config(void)
static void fwbank_copy_config(const char *keep_settings, const char *keep_opconf, const char *config_scope)
{
char output[64] = {0};
char cmd[256] = {0};
struct blob_buf bb = {0};
bool res = false;
char *str = NULL;
run_cmd(COPY_CONFIG_CMD, output, sizeof(output));
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
if (DM_STRLEN(keep_settings) != 0) {
string_to_bool(keep_settings, &res);
blobmsg_add_u8(&bb, "keep_settings", res);
}
if (DM_STRLEN(keep_opconf) != 0) {
string_to_bool(keep_opconf, &res);
blobmsg_add_u8(&bb, "keep_opconf", res);
}
if (DM_STRLEN(config_scope) != 0) {
blobmsg_add_string(&bb, "config_scope", config_scope);
}
str = blobmsg_format_json(bb.head, true);
if (str) {
char output[256] = {0};
snprintf(cmd, sizeof(cmd), "echo '%s' |/etc/sysmngr/fwbank call copy_config 2> /dev/null", str);
run_cmd(cmd, output, sizeof(output));
FREE(str);
} else {
BBFDM_ERR("Failed to get json from blob");
}
}
static bool fwbank_set_bootbank(const char *bank_id)
@ -123,17 +152,41 @@ static bool fwbank_set_bootbank(const char *bank_id)
return sysmngr_fwbank_set_bootbank((uint32_t)DM_STRTOUL(bank_id));
}
static bool fwbank_upgrade(const char *path, bool activate, const char *bank_id, const char *keep_settings)
static bool fwbank_upgrade(const char *fw_path, struct fw_download_data *dw_data)
{
json_object *jp_in = NULL;
json_object *json_obj = NULL;
bool res = true;
bool res = false;
if (activate == false) {
dmubus_call_blocking("fwbank", "upgrade", UBUS_ARGS{{"path", path, String}, {"auto_activate", "0", Boolean}, {"bank", bank_id, Integer}, {"keep_settings", "0", Boolean}}, 4, &json_obj);
} else {
dmubus_call_blocking("fwbank", "upgrade", UBUS_ARGS{{"path", path, String}, {"auto_activate", "1", Boolean}, {"bank", bank_id, Integer}, {"keep_settings", keep_settings, Boolean}}, 4, &json_obj);
jp_in = json_object_new_object();
if (jp_in == NULL) {
BBFDM_ERR("Failed to create json object");
return false;
}
json_object_object_add(jp_in, "path", json_object_new_string(fw_path));
json_object_object_add(jp_in, "bank", json_object_new_int(strtol(dw_data->bank_id, NULL, 10)));
if (DM_STRLEN(dw_data->auto_activate) != 0) {
string_to_bool(dw_data->auto_activate, &res);
json_object_object_add(jp_in, "auto_activate", json_object_new_boolean(res));
}
if (DM_STRLEN(dw_data->keep_config) != 0) {
string_to_bool(dw_data->keep_config, &res);
json_object_object_add(jp_in, "keep_settings", json_object_new_boolean(res));
}
if (DM_STRLEN(dw_data->keep_opconf) != 0) {
string_to_bool(dw_data->keep_opconf, &res);
json_object_object_add(jp_in, "keep_opconf", json_object_new_boolean(res));
}
if (DM_STRLEN(dw_data->config_scope) != 0) {
json_object_object_add(jp_in, "config_scope", json_object_new_string(dw_data->config_scope));
}
res = true;
dmubus_call_blob_blocking("fwbank", "upgrade", jp_in, &json_obj);
if (json_obj) {
char *result = dmjson_get_value(json_obj, 1, "result");
res = (DM_LSTRCMP(result, "ok") == 0) ? true : false;
@ -142,6 +195,9 @@ static bool fwbank_upgrade(const char *path, bool activate, const char *bank_id,
if (json_obj != NULL)
json_object_put(json_obj);
if (jp_in)
json_object_put(jp_in);
return res;
}
@ -278,10 +334,8 @@ static int bbf_fw_image_download(struct ubus_context *ctx, struct fw_download_da
goto end;
}
string_to_bool(dw_data->auto_activate, &activate);
// Apply Firmware Image
if (!fwbank_upgrade(fw_image_path, activate, dw_data->bank_id, DM_STRLEN(dw_data->keep_config) ? dw_data->keep_config : "1")) {
if (!fwbank_upgrade(fw_image_path, dw_data)) {
res = 1;
snprintf(fault_msg, sizeof(fault_msg), "Internal error occurred when applying the firmware");
goto end;
@ -293,7 +347,6 @@ static int bbf_fw_image_download(struct ubus_context *ctx, struct fw_download_da
};
dmubus_wait_for_event("sysupgrade", 120, &ev_data, dmubus_receive_sysupgrade, NULL);
if (ev_data.status == false) {
res = 1;
snprintf(fault_msg, sizeof(fault_msg), "Failed to apply the downloaded image file");
@ -301,6 +354,7 @@ static int bbf_fw_image_download(struct ubus_context *ctx, struct fw_download_da
}
// Schedule a device Reboot, if auto activation is true
string_to_bool(dw_data->auto_activate, &activate);
if (activate) {
bbfdm_task_fork(_exec_reboot, NULL, NULL, NULL);
}
@ -545,6 +599,8 @@ static operation_args firmware_image_download_args = {
"CheckSum",
#ifdef SYSMNGR_VENDOR_EXTENSIONS
CUSTOM_PREFIX"KeepConfig",
CUSTOM_PREFIX"KeepOpConf",
CUSTOM_PREFIX"ConfigScope",
#endif
NULL
}
@ -595,6 +651,8 @@ static int operate_DeviceInfoFirmwareImage_Download(char *refparam, struct dmctx
#ifdef SYSMNGR_VENDOR_EXTENSIONS
dw_data.keep_config = dmjson_get_value((json_object *)value, 1, CUSTOM_PREFIX"KeepConfig");
dw_data.keep_opconf = dmjson_get_value((json_object *)value, 1, CUSTOM_PREFIX"KeepOpConf");
dw_data.config_scope = dmjson_get_value((json_object *)value, 1, CUSTOM_PREFIX"ConfigScope");
#endif
dw_data.bank_id = get_fwbank_option_value(data, "id");
dw_data.obj_path = dmstrdup(obj_path);
@ -617,6 +675,8 @@ static operation_args firmware_image_activate_args = {
"TimeWindow.{i}.MaxRetries",
#ifdef SYSMNGR_VENDOR_EXTENSIONS
CUSTOM_PREFIX"KeepConfig",
CUSTOM_PREFIX"KeepOpConf",
CUSTOM_PREFIX"ConfigScope",
#endif
NULL
}
@ -637,19 +697,16 @@ static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx
char *user_message[MAX_TIME_WINDOW] = {0};
char *max_retries[MAX_TIME_WINDOW] = {0};
char *keep_config = NULL;
bool bKeepConfig = false;
char *keep_opconf = NULL;
char *config_scope = NULL;
int res = 0, last_idx = -1;
#ifdef SYSMNGR_VENDOR_EXTENSIONS
keep_config = dmjson_get_value((json_object *)value, 1, CUSTOM_PREFIX"KeepConfig");
keep_opconf = dmjson_get_value((json_object *)value, 1, CUSTOM_PREFIX"KeepOpConf");
config_scope = dmjson_get_value((json_object *)value, 1, CUSTOM_PREFIX"ConfigScope");
#endif
if (DM_STRLEN(keep_config) == 0) {
bKeepConfig = true;
} else {
string_to_bool(keep_config, &bKeepConfig);
}
for (int i = 0; i < MAX_TIME_WINDOW; i++) {
char buf[32] = {0};
@ -720,9 +777,10 @@ static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx
ACTIVATE_HANDLER_FILE);
len = strlen(buffer);
snprintf(buffer+len, sizeof(buffer)-len, " '%s' '%s' '%ld' '%d' '%s' '%d' '%s'\n",
snprintf(buffer+len, sizeof(buffer)-len, " '%s' '%s' '%ld' '%d' '%s' '%s' '%s' '%s' '%s'\n",
mode[i], bank_id, (DM_STRTOL(end_time[i]) - DM_STRTOL(start_time[i])),
(i == last_idx), max_retries[i], bKeepConfig, user_message[i]);
(i == last_idx), max_retries[i], (keep_config)?keep_config:"1",
(keep_opconf)?keep_opconf:"1", config_scope, user_message[i]);
fprintf(file, "%s", buffer);
}
@ -734,10 +792,7 @@ static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx
if (!fwbank_set_bootbank(bank_id))
return USP_FAULT_COMMAND_FAILURE;
if (bKeepConfig == true) {
fwbank_copy_config();
}
fwbank_copy_config(keep_config, keep_opconf, config_scope);
bbfdm_task_fork(_exec_reboot, NULL, NULL, NULL);
}

View file

@ -538,20 +538,26 @@ static void fwbank_upgrade_finish_callback(struct ubus_context *ctx, struct ubus
return;
}
int sysmngr_fwbank_upgrade(const char *path, bool auto_activate, uint32_t bank_id, bool keep_settings, struct ubus_request_data *req)
static int sysmngr_fwbank_upgrade(struct blob_buf *bbp, int bank_id, struct ubus_request_data *req)
{
char *str = NULL;
char cmd[1024] = {0};
int res = 0;
snprintf(cmd, sizeof(cmd), "echo '{\"path\":\"%s\", \"auto_activate\":%d, \"bank\":%u, \"keep_settings\":%d}' | %s 2>/dev/null",
path, auto_activate, bank_id, keep_settings, FWBANK_UPGRADE_CMD);
int res = sysmngr_task_fork(fwbank_upgrade_finish_callback, cmd, 60, req, bank_id);
if (res) {
BBFDM_ERR("Failed to start task for fwbank upgrade command");
str = blobmsg_format_json(bbp->head, true);
if (str == NULL) {
return -1;
}
return 0;
snprintf(cmd, sizeof(cmd), "echo '%s' | %s 2>/dev/null", str, FWBANK_UPGRADE_CMD);
res = sysmngr_task_fork(fwbank_upgrade_finish_callback, cmd, 60, req, bank_id);
if (res) {
BBFDM_ERR("Failed to start task for fwbank upgrade command");
res = -1;
}
FREE(str);
return res;
}
static int dump_handler(struct ubus_context *ctx, struct ubus_object *obj,
@ -640,6 +646,8 @@ enum {
UPGRADE_AUTO_ACTIVATE,
UPGRADE_BANK,
UPGRADE_KEEP_SETTINGS,
UPGRADE_KEEP_OPCONF,
UPGRADE_CONFIG_MODE,
__UPGRADE_MAX
};
@ -648,6 +656,8 @@ static const struct blobmsg_policy upgrade_policy[] = {
[UPGRADE_AUTO_ACTIVATE] = { .name = "auto_activate", .type = BLOBMSG_TYPE_BOOL },
[UPGRADE_BANK] = { .name = "bank", .type = BLOBMSG_TYPE_INT32 },
[UPGRADE_KEEP_SETTINGS] = { .name = "keep_settings", .type = BLOBMSG_TYPE_BOOL},
[UPGRADE_KEEP_OPCONF] = { .name = "keep_opconf", .type = BLOBMSG_TYPE_BOOL},
[UPGRADE_CONFIG_MODE] = { .name = "config_scope", .type = BLOBMSG_TYPE_STRING},
};
static int upgrade_handler(struct ubus_context *ctx, struct ubus_object *obj,
@ -655,11 +665,11 @@ static int upgrade_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct blob_attr *msg)
{
struct blob_attr *tb[__UPGRADE_MAX];
char *fw_path = NULL;
uint32_t bank_id = 0;
bool auto_activate = false;
bool keep_settings = false;
char *tmp_string = NULL;
bool tmp_boolean = false;
int res = 0;
struct blob_buf bb = {0};
if (blobmsg_parse(upgrade_policy, __UPGRADE_MAX, tb, blob_data(msg), blob_len(msg))) {
BBFDM_ERR("Failed to parse the 'upgrade' message");
@ -667,22 +677,53 @@ static int upgrade_handler(struct ubus_context *ctx, struct ubus_object *obj,
}
if (tb[UPGRADE_PATH])
fw_path = blobmsg_get_string(tb[UPGRADE_PATH]);
tmp_string = blobmsg_get_string(tb[UPGRADE_PATH]);
if (tb[UPGRADE_AUTO_ACTIVATE])
auto_activate = blobmsg_get_bool(tb[UPGRADE_AUTO_ACTIVATE]);
if (DM_STRLEN(tmp_string) == 0) {
BBFDM_ERR("Path missing, aborting upgrade!!!");
return UBUS_STATUS_UNKNOWN_ERROR;
}
if (tb[UPGRADE_BANK])
if (tb[UPGRADE_BANK]) {
bank_id = blobmsg_get_u32(tb[UPGRADE_BANK]);
} else {
BBFDM_ERR("bank missing, aborting upgrade!!!");
return UBUS_STATUS_UNKNOWN_ERROR;
}
if (tb[UPGRADE_KEEP_SETTINGS])
keep_settings = blobmsg_get_bool(tb[UPGRADE_KEEP_SETTINGS]);
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
res = sysmngr_fwbank_upgrade(fw_path, auto_activate, bank_id, keep_settings, req);
blobmsg_add_string(&bb, "path", tmp_string);
blobmsg_add_u32(&bb, "bank", bank_id);
// default values will be enforced in fwbank script
if (tb[UPGRADE_AUTO_ACTIVATE]) {
tmp_boolean = blobmsg_get_bool(tb[UPGRADE_AUTO_ACTIVATE]);
blobmsg_add_u8(&bb, "auto_activate", tmp_boolean);
} else {
blobmsg_add_u8(&bb, "auto_activate", false);
}
if (tb[UPGRADE_KEEP_SETTINGS]) {
tmp_boolean = blobmsg_get_bool(tb[UPGRADE_KEEP_SETTINGS]);
blobmsg_add_u8(&bb, "keep_settings", tmp_boolean);
}
if (tb[UPGRADE_KEEP_OPCONF]) {
tmp_boolean = blobmsg_get_bool(tb[UPGRADE_KEEP_OPCONF]);
blobmsg_add_u8(&bb, "keep_opconf", tmp_boolean);
}
if (tb[UPGRADE_CONFIG_MODE]) {
tmp_string = blobmsg_get_string(tb[UPGRADE_CONFIG_MODE]);
blobmsg_add_string(&bb, "config_scope", tmp_string);
}
res = sysmngr_fwbank_upgrade(&bb, bank_id, req);
blob_buf_free(&bb);
if (res) {
struct blob_buf bb = {0};
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
blobmsg_add_string(&bb, "result", "failure");

View file

@ -17,7 +17,6 @@ extern struct blobmsg_policy sysmngr_bank_policy[];
struct blob_buf *sysmngr_fwbank_dump(void);
bool sysmngr_fwbank_set_bootbank(uint32_t bank_id);
int sysmngr_fwbank_upgrade(const char *path, bool auto_activate, uint32_t bank_id, bool keep_settings, struct ubus_request_data *req);
void sysmngr_fwbank_refresh_global_dump(void);