fix: zapret2 strategy args, snapshot restore output leak, and opkg update lock handling

- providers/zapret2/common.uc: import core.common and declare as_string helper to resolve type error during zapret2 strategy argument preparation.
- service/snapshot.uc: redirect command output to /dev/null in command_success_from_args to prevent stdout leakage breaking LuCI JSON parsing on snapshot restore.
- settings.js: robustly parse JSON from snapshot command output using regex delimiter.
- components/action.uc: add --force-depends to opkg install arguments, detect opkg lock contention and retry with backoff, and log non-zero exit stdout as warning.
- providers/nfqueue/runtime.uc: ensure standalone services are cleanly stopped and disabled before starting Tachyon-managed runtime.
- section.js, generator_routes.uc, apply.uc: add community_subnets option to conditionally include community CIDRs in routing and nftables.
This commit is contained in:
Dushnilin
2026-09-09 11:55:12 +03:00
parent 01dad3bab0
commit 142fff6b4a
10 changed files with 100 additions and 43 deletions
+14 -7
View File
@@ -452,7 +452,7 @@ function pkg_install_name_downgrade(package_name, package_version) {
// published under the same tag would silently not be applied. apk always writes
// the file it is handed, so its argument list stays untouched.
function pkg_install_files_command(files, force_reinstall) {
let args = is_apk() ? [ "apk", "add", "--allow-untrusted" ] : [ "opkg", "install", "--force-overwrite", "--force-downgrade" ];
let args = is_apk() ? [ "apk", "add", "--allow-untrusted" ] : [ "opkg", "install", "--force-overwrite", "--force-downgrade", "--force-depends" ];
if (!is_apk() && force_reinstall)
push(args, "--force-reinstall");
for (let file in files)
@@ -464,7 +464,7 @@ function pkg_install_files(files, force_reinstall) {
return command_success(pkg_install_files_command(files, force_reinstall));
}
// Like run_logged but retries up to 10 times on APK database lock (exit code 227)
// Like run_logged but retries up to 10 times on package manager database lock (exit code 227 for APK, lock file contention for opkg)
function run_logged_retrying(description, command) {
init_tmp_dir();
let output_file = make_tmp_file("command");
@@ -476,17 +476,24 @@ function run_logged_retrying(description, command) {
let max_attempts = 10;
for (let attempt = 0; attempt < max_attempts; attempt++) {
if (attempt > 0) {
updates_log(description + ": APK database locked, retrying in 3s (attempt " + (attempt + 1) + "/" + max_attempts + ")");
let mgr_name = is_apk() ? "APK" : "opkg";
updates_log(description + ": " + mgr_name + " database locked, retrying in 3s (attempt " + (attempt + 1) + "/" + max_attempts + ")");
command_success("sleep 3");
}
status = command_status(as_string(command) + " >" + shell_quote(output_file) + " 2>&1");
if (status != 227)
let output_text = read_file(output_file);
let is_locked = status == 227 || (status == 255 && match(output_text, /Could not lock|opkg\.lock|Resource temporarily unavailable/i) != null);
if (!is_locked)
break;
}
for (let line in split(read_file(output_file), "\n"))
if (trim(as_string(line)) != "")
updates_log(line);
let output_content = read_file(output_file);
remove_file(output_file);
let log_level = status != 0 ? "warn" : "info";
for (let line in split(output_content, "\n")) {
line = trim(as_string(line));
if (line != "")
updates_log(line, log_level);
}
if (status != 0)
updates_log(description + " failed with exit code " + status, "warn");
return status == 0;