diff options
author | John Estabrook <jestabro@vyos.io> | 2025-05-23 10:31:18 -0500 |
---|---|---|
committer | John Estabrook <jestabro@vyos.io> | 2025-06-10 18:12:48 -0500 |
commit | c82b2b836b01c285576cc98ecf2b99ff3d8838ef (patch) | |
tree | 244be0a59856341181f28870a3956ab3893966a3 /src | |
parent | b40e7a2de9daa866b6423391ba7fe5b1bfa7e67c (diff) | |
download | vyos-1x-c82b2b836b01c285576cc98ecf2b99ff3d8838ef.tar.gz vyos-1x-c82b2b836b01c285576cc98ecf2b99ff3d8838ef.zip |
configd: T7488: allow distinction of first-order error verify vs apply
Leave hint if vyos-configd encounters an error in the generate/apply
stages: this only detects 'first-order' differences, meaning those
originating from the called config mode script, and not its
dependencies. This is useful for supporting automatic rollback for
certain cases of apply stage error.
Diffstat (limited to 'src')
-rwxr-xr-x | src/services/vyos-configd | 14 | ||||
-rw-r--r-- | src/shim/vyshim.c | 41 |
2 files changed, 45 insertions, 10 deletions
diff --git a/src/services/vyos-configd b/src/services/vyos-configd index 28acccd2c..c45d492f9 100755 --- a/src/services/vyos-configd +++ b/src/services/vyos-configd @@ -68,6 +68,7 @@ class Response(Enum): ERROR_COMMIT = 2 ERROR_DAEMON = 4 PASS = 8 + ERROR_COMMIT_APPLY = 16 vyos_conf_scripts_dir = directories['conf_mode'] @@ -142,8 +143,6 @@ def run_script(script_name, config, args) -> tuple[Response, str]: try: c = script.get_config(config) script.verify(c) - script.generate(c) - script.apply(c) except ConfigError as e: logger.error(e) return Response.ERROR_COMMIT, str(e) @@ -152,6 +151,17 @@ def run_script(script_name, config, args) -> tuple[Response, str]: logger.error(tb) return Response.ERROR_COMMIT, tb + try: + script.generate(c) + script.apply(c) + except ConfigError as e: + logger.error(e) + return Response.ERROR_COMMIT_APPLY, str(e) + except Exception: + tb = traceback.format_exc() + logger.error(tb) + return Response.ERROR_COMMIT_APPLY, tb + return Response.SUCCESS, '' diff --git a/src/shim/vyshim.c b/src/shim/vyshim.c index 1eb653cbf..35f995419 100644 --- a/src/shim/vyshim.c +++ b/src/shim/vyshim.c @@ -18,8 +18,10 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <fcntl.h> #include <unistd.h> #include <string.h> +#include <sys/stat.h> #include <sys/time.h> #include <time.h> #include <stdint.h> @@ -55,15 +57,17 @@ enum { SUCCESS = 1 << 0, ERROR_COMMIT = 1 << 1, ERROR_DAEMON = 1 << 2, - PASS = 1 << 3 + PASS = 1 << 3, + ERROR_COMMIT_APPLY = 1 << 4 }; volatile int init_alarm = 0; volatile int timeout = 0; -int initialization(void *); +int initialization(void *, char *); int pass_through(char **, int); void timer_handler(int); +void leave_hint(char *); double get_posix_clock_time(void); @@ -94,8 +98,17 @@ int main(int argc, char* argv[]) char *test = strstr(string_node_data, "VYOS_TAGNODE_VALUE"); ex_index = test ? 2 : 1; + char *env_tmp = getenv("VYATTA_CONFIG_TMP"); + if (env_tmp == NULL) { + fprintf(stderr, "Error: Environment variable VYATTA_CONFIG_TMP is not set.\n"); + exit(EXIT_FAILURE); + } + char *pid_str = strdup(env_tmp); + strsep(&pid_str, "_"); + debug_print("config session pid: %s\n", pid_str); + if (access(COMMIT_MARKER, F_OK) != -1) { - init_timeout = initialization(requester); + init_timeout = initialization(requester, pid_str); if (!init_timeout) remove(COMMIT_MARKER); } @@ -151,13 +164,19 @@ int main(int argc, char* argv[]) ret = -1; } + if (err & ERROR_COMMIT_APPLY) { + debug_print("Received ERROR_COMMIT_APPLY\n"); + leave_hint(pid_str); + ret = -1; + } + zmq_close(requester); zmq_ctx_destroy(context); return ret; } -int initialization(void* Requester) +int initialization(void* Requester, char* pid_val) { char *active_str = NULL; size_t active_len = 0; @@ -185,10 +204,6 @@ int initialization(void* Requester) double prev_time_value, time_value; double time_diff; - char *pid_val = getenv("VYATTA_CONFIG_TMP"); - strsep(&pid_val, "_"); - debug_print("config session pid: %s\n", pid_val); - char *sudo_user = getenv("SUDO_USER"); if (!sudo_user) { char nobody[] = "nobody"; @@ -338,6 +353,16 @@ void timer_handler(int signum) return; } +void leave_hint(char *pid_val) +{ + char tmp_str[16]; + mode_t omask = umask(0); + snprintf(tmp_str, sizeof(tmp_str), "/tmp/apply_%s", pid_val); + open(tmp_str, O_CREAT|O_RDWR|O_TRUNC, 0666); + chown(tmp_str, 1002, 102); + umask(omask); +} + #ifdef _POSIX_MONOTONIC_CLOCK double get_posix_clock_time(void) { |