feat(migration): 1.3.11 - CLI команда import_settings и исправление миграции Forkop
- Добавлена CLI команда tachyon import_settings [файл] (и алиас import-settings) для автоматического сканирования и бесшовного импорта настроек из Forkop, Forkop Plus, Podkop, Netshift или резервных копий - Поддержка in-place миграции прямо из активного /etc/config/tachyon при обнаружении унаследованных правил config rule - Расширенное сканирование резервных копий и файлов конфигураций в /etc/config/, /root/ и /tmp/ - Исправлен режим миграции Forkop в Makefile, build.sh и install.sh (использование migrate-podkop для корректного преобразования старых секций config rule в config section) - Добавлен интеграционный тест tests/import_settings.sh (119 тестов бэкенда пройдены)
This commit is contained in:
@@ -402,19 +402,19 @@ rm -rf /usr/lib/lua/luci/i18n/forkop.* /www/luci-static/resources/i18n/forkop.*
|
||||
|
||||
if [ -f /etc/config/forkop ]; then
|
||||
mv /etc/config/forkop /etc/config/tachyon
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate-podkop
|
||||
elif [ -f /etc/config/forkop_plus ]; then
|
||||
mv /etc/config/forkop_plus /etc/config/tachyon
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate-podkop
|
||||
elif [ -f /etc/config/podkop ]; then
|
||||
mv /etc/config/podkop /etc/config/tachyon
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate-podkop
|
||||
exit 0
|
||||
elif [ -f /etc/config/podkop_plus ]; then
|
||||
mv /etc/config/podkop_plus /etc/config/tachyon
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate-podkop
|
||||
exit 0
|
||||
else
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate
|
||||
fi
|
||||
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate
|
||||
EOF
|
||||
|
||||
cat > "$control_dir/prerm" <<'EOF'
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "fe-app-tachyon",
|
||||
"version": "1.3.10",
|
||||
"version": "1.3.11",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "fe-app-tachyon",
|
||||
"version": "1.3.10",
|
||||
"version": "1.3.11",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@babel/parser": "7.28.4",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fe-app-tachyon",
|
||||
"version": "1.3.10",
|
||||
"version": "1.3.11",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -2588,9 +2588,6 @@ migrate_legacy_configuration() {
|
||||
|
||||
msg "$(installer_text migrating_config_detail)"
|
||||
local migration_mode="migrate-podkop"
|
||||
if [ "$TACHYON_FORKOP_MIGRATION" -eq 1 ] || [ "$TACHYON_NETSHIFT_MIGRATION" -eq 1 ]; then
|
||||
migration_mode="migrate"
|
||||
fi
|
||||
|
||||
if ! TACHYON_CONFIG_NAME="tachyon" \
|
||||
TACHYON_LIB="/usr/lib/tachyon" \
|
||||
|
||||
+5
-5
@@ -101,23 +101,23 @@ rm -rf /usr/lib/lua/luci/i18n/forkop.* /www/luci-static/resources/i18n/forkop.*
|
||||
/usr/share/luci/menu.d/luci-app-forkop.json /usr/share/rpcd/acl.d/luci-app-forkop.json \
|
||||
/etc/uci-defaults/50_luci-forkop 2>/dev/null || true
|
||||
|
||||
# Migration from Forkop
|
||||
# Migration from Forkop or Podkop
|
||||
if [ -f /etc/config/forkop ]; then
|
||||
mv /etc/config/forkop /etc/config/tachyon
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate-podkop
|
||||
elif [ -f /etc/config/forkop_plus ]; then
|
||||
mv /etc/config/forkop_plus /etc/config/tachyon
|
||||
# Migration from Podkop
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate-podkop
|
||||
elif [ -f /etc/config/podkop ]; then
|
||||
mv /etc/config/podkop /etc/config/tachyon
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate-podkop
|
||||
exit 0
|
||||
elif [ -f /etc/config/podkop_plus ]; then
|
||||
mv /etc/config/podkop_plus /etc/config/tachyon
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate-podkop
|
||||
exit 0
|
||||
else
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate
|
||||
fi
|
||||
|
||||
TACHYON_LIB=/usr/lib/tachyon ucode -L /usr/lib/tachyon /usr/lib/tachyon/config/migration.uc migrate
|
||||
/usr/bin/tachyon package_postinst
|
||||
|
||||
# Harden config: telegram bot_token must not be world-readable
|
||||
|
||||
@@ -32,6 +32,7 @@ config settings 'settings'
|
||||
option component_auto_update_mode 'immediate'
|
||||
option component_auto_update_time '04:00'
|
||||
list component_auto_update_targets 'all'
|
||||
option component_backup_enabled '0'
|
||||
option latency_test_url 'https://www.gstatic.com/generate_204'
|
||||
option download_lists_via_proxy '0'
|
||||
option download_components_via_proxy '0'
|
||||
|
||||
@@ -152,6 +152,7 @@ function show_help() {
|
||||
print(" snapshot_save <name> Save a config snapshot\n");
|
||||
print(" snapshot_restore <file> Restore a config snapshot\n");
|
||||
print(" snapshot_delete <file> Delete a config snapshot\n");
|
||||
print(" import_settings [file] Scan and import legacy settings from Forkop/Podkop or backup\n");
|
||||
print(" validate_nfqws_strategy_json\n");
|
||||
print(" Validate an NFQWS strategy and print JSON result\n");
|
||||
print(" validate_nfqws2_strategy_json\n");
|
||||
@@ -280,7 +281,9 @@ function command_spec(command) {
|
||||
snapshot_list: [ "service/snapshot.uc", "snapshot-list", 0 ],
|
||||
snapshot_save: [ "service/snapshot.uc", "snapshot-save", 1 ],
|
||||
snapshot_restore: [ "service/snapshot.uc", "snapshot-restore", 1 ],
|
||||
snapshot_delete: [ "service/snapshot.uc", "snapshot-delete", 1 ]
|
||||
snapshot_delete: [ "service/snapshot.uc", "snapshot-delete", 1 ],
|
||||
import_settings: [ "config/migration.uc", "import-settings", 1 ],
|
||||
"import-settings": [ "config/migration.uc", "import-settings", 1 ]
|
||||
};
|
||||
|
||||
return commands[as_string(command)];
|
||||
|
||||
@@ -21,6 +21,8 @@ let bool_option = common.bool_option;
|
||||
let object_or_empty = common.object_or_empty;
|
||||
|
||||
const CONFIG_NAME = getenv("TACHYON_CONFIG_NAME") || "tachyon";
|
||||
const CONFIG_DIR = getenv("TACHYON_CONFIG_DIR") || "/etc/config";
|
||||
const TARGET_CONFIG = getenv("TACHYON_CONFIG_FILE") || (CONFIG_DIR + "/" + CONFIG_NAME);
|
||||
const TMP_SUBSCRIPTION_FOLDER = getenv("TMP_SUBSCRIPTION_FOLDER") || "/tmp/sing-box/subscriptions";
|
||||
const TACHYON_RUNTIME_STATE_DIR = getenv("TACHYON_RUNTIME_STATE_DIR") || "/var/run/tachyon";
|
||||
const TACHYON_SUBSCRIPTION_LINKS_DIR = getenv("TACHYON_SUBSCRIPTION_LINKS_DIR") || TACHYON_RUNTIME_STATE_DIR + "/subscription-links";
|
||||
@@ -1701,6 +1703,196 @@ function migrate_fixture(path, source) {
|
||||
});
|
||||
}
|
||||
|
||||
function detect_config_migration_source(path) {
|
||||
let content = fs.readfile(path);
|
||||
if (content == null || content == "")
|
||||
return "tachyon";
|
||||
|
||||
if (match(content, /config[ \t]+rule[ \t]+/) ||
|
||||
match(content, /option[ \t]+domain_list_urls/) ||
|
||||
match(content, /option[ \t]+routing_excluded_ips/) ||
|
||||
match(content, /option[ \t]+connection_type[ \t]+['"]?proxy/) ||
|
||||
match(content, /option[ \t]+proxy_string/) ||
|
||||
match(content, /option[ \t]+ip_cidr/)) {
|
||||
return "podkop";
|
||||
}
|
||||
|
||||
return "tachyon";
|
||||
}
|
||||
|
||||
function scan_legacy_config_candidates() {
|
||||
let base_cfg_dir = CONFIG_DIR;
|
||||
let known = [
|
||||
base_cfg_dir + "/forkop",
|
||||
base_cfg_dir + "/forkop_plus",
|
||||
base_cfg_dir + "/podkop",
|
||||
base_cfg_dir + "/podkop_plus",
|
||||
base_cfg_dir + "/netshift",
|
||||
"/tmp/legacy-config.backup",
|
||||
"/etc/.tachyon/.cfg-backup.pre-install"
|
||||
];
|
||||
let candidates = [];
|
||||
let seen = {};
|
||||
|
||||
// 1. Check if current active config itself contains unconverted legacy rules
|
||||
let current_tachyon = TARGET_CONFIG;
|
||||
if (detect_config_migration_source(current_tachyon) == "podkop") {
|
||||
let st = fs.stat(current_tachyon);
|
||||
if (st != null && (st.size || 0) > 10) {
|
||||
push(candidates, {
|
||||
path: current_tachyon,
|
||||
size: st.size || 0,
|
||||
mtime: st.mtime || 0,
|
||||
in_place_legacy: true
|
||||
});
|
||||
seen[current_tachyon] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (let path in known) {
|
||||
if (seen[path]) continue;
|
||||
let st = fs.stat(path);
|
||||
if (st != null && (st.type == "file" || st.type == null) && (st.size || 0) > 10) {
|
||||
push(candidates, { path: path, size: st.size || 0, mtime: st.mtime || 0 });
|
||||
seen[path] = true;
|
||||
}
|
||||
}
|
||||
|
||||
let globs = [
|
||||
base_cfg_dir + "/*forkop*",
|
||||
base_cfg_dir + "/*podkop*",
|
||||
base_cfg_dir + "/*netshift*",
|
||||
base_cfg_dir + "/tachyon.backup*",
|
||||
base_cfg_dir + "/tachyon.bak*",
|
||||
base_cfg_dir + "/tachyon.pre-import-*",
|
||||
base_cfg_dir + "/tachyon.pre-install*",
|
||||
"/tmp/legacy-config*",
|
||||
"/tmp/*forkop*",
|
||||
"/tmp/*podkop*",
|
||||
"/tmp/*tachyon*",
|
||||
"/tmp/tmp.*/legacy-config*",
|
||||
"/etc/.tachyon/*",
|
||||
"/root/*forkop*",
|
||||
"/root/*podkop*",
|
||||
"/root/*tachyon*",
|
||||
"/root/*.backup*",
|
||||
"/root/*.bak*"
|
||||
];
|
||||
for (let g in globs) {
|
||||
let paths = fs.glob(g);
|
||||
if (type(paths) == "array") {
|
||||
for (let path in paths) {
|
||||
if (seen[path])
|
||||
continue;
|
||||
let st = fs.stat(path);
|
||||
if (st != null && (st.type == "file" || st.type == null) && (st.size || 0) > 10) {
|
||||
push(candidates, { path: path, size: st.size || 0, mtime: st.mtime || 0 });
|
||||
seen[path] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
function import_settings_cli(source_path) {
|
||||
source_path = trim(as_string(source_path));
|
||||
let target_config = TARGET_CONFIG;
|
||||
|
||||
print("=== Tachyon Settings Importer ===\n\n");
|
||||
|
||||
let chosen_path = "";
|
||||
let candidate_list = [];
|
||||
|
||||
if (source_path != "") {
|
||||
let st = fs.stat(source_path);
|
||||
if (st == null || (st.type != "file" && st.type != null)) {
|
||||
warn("Error: Specified configuration file '" + source_path + "' does not exist or is not readable.\n");
|
||||
return false;
|
||||
}
|
||||
chosen_path = source_path;
|
||||
print("[1/3] Using specified configuration file:\n");
|
||||
print(" ✓ " + chosen_path + " (" + sprintf("%.1f KB", (st.size || 0) / 1024.0) + ")\n\n");
|
||||
} else {
|
||||
print("[1/3] Scanning system for legacy or backup configurations...\n");
|
||||
candidate_list = scan_legacy_config_candidates();
|
||||
if (length(candidate_list) == 0) {
|
||||
print(" Notice: No legacy or backup configurations found in standard directories.\n\n");
|
||||
print("To locate any leftover configurations, you can search with:\n");
|
||||
print(" grep -rnE 'vless://|vmess://|ss://|trojan://|config rule' /etc/ /root/ /tmp/ 2>/dev/null\n\n");
|
||||
print("And specify the file path directly:\n");
|
||||
print(" tachyon import_settings /path/to/backup-file\n\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
print(" Found candidates:\n");
|
||||
for (let i = 0; i < length(candidate_list); i++) {
|
||||
let c = candidate_list[i];
|
||||
let note = c.in_place_legacy ? " (unconverted legacy rules in active config)" : "";
|
||||
print(" [" + (i + 1) + "] " + c.path + " (" + sprintf("%.1f KB", c.size / 1024.0) + ")" + note + "\n");
|
||||
}
|
||||
print("\n");
|
||||
|
||||
chosen_path = candidate_list[0].path;
|
||||
print(" ✓ Selected primary candidate: " + chosen_path + "\n\n");
|
||||
}
|
||||
|
||||
print("[2/3] Backing up current Tachyon configuration...\n");
|
||||
let current_st = fs.stat(target_config);
|
||||
if (current_st != null && (current_st.size || 0) > 0) {
|
||||
let date_stamp = trim(command_output("date +%Y%m%d_%H%M%S 2>/dev/null || date +%s"));
|
||||
if (date_stamp == "") date_stamp = "backup";
|
||||
let backup_path = target_config + ".pre-import-" + date_stamp;
|
||||
if (system("cp -a " + shell_quote(target_config) + " " + shell_quote(backup_path)) == 0) {
|
||||
print(" ✓ Current configuration backed up to: " + backup_path + "\n\n");
|
||||
} else {
|
||||
warn(" Warning: Could not create safety backup of current configuration.\n\n");
|
||||
}
|
||||
} else {
|
||||
print(" ✓ No existing configuration to back up.\n\n");
|
||||
}
|
||||
|
||||
print("[3/3] Migrating configuration structure...\n");
|
||||
if (chosen_path != target_config) {
|
||||
let target_dir = "";
|
||||
let idx = rindex(target_config, "/");
|
||||
if (idx > 0) target_dir = substr(target_config, 0, idx);
|
||||
if (target_dir != "" && fs.stat(target_dir) == null) {
|
||||
system("mkdir -p " + shell_quote(target_dir) + " 2>/dev/null");
|
||||
}
|
||||
if (system("cp -a " + shell_quote(chosen_path) + " " + shell_quote(target_config)) != 0) {
|
||||
warn("Error: Failed to copy " + chosen_path + " to " + target_config + "\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
system("chmod 0600 " + shell_quote(target_config) + " 2>/dev/null");
|
||||
|
||||
let source_type = detect_config_migration_source(target_config);
|
||||
print(" ✓ Detected format: " + (source_type == "podkop" ? "Legacy Forkop / Podkop" : "Tachyon") + "\n");
|
||||
|
||||
let ok = migrate_runtime(source_type);
|
||||
if (!ok) {
|
||||
warn("Error: Configuration migration failed during UCI commit.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
system("chmod 0600 " + shell_quote(target_config) + " 2>/dev/null");
|
||||
print(" ✓ Configuration successfully migrated and verified.\n\n");
|
||||
|
||||
if (fs.stat("/etc/init.d/tachyon") != null) {
|
||||
print("Restarting Tachyon service...\n");
|
||||
system("/usr/bin/tachyon restart >/dev/null 2>&1");
|
||||
print(" ✓ Tachyon restarted with imported configuration.\n\n");
|
||||
}
|
||||
|
||||
print("====================================================\n");
|
||||
print("SUCCESS: Settings successfully imported from:\n");
|
||||
print(" " + chosen_path + "\n");
|
||||
print("====================================================\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
function main(argv) {
|
||||
let mode = argv[0] || "";
|
||||
|
||||
@@ -1708,6 +1900,8 @@ function main(argv) {
|
||||
return migrate_runtime("tachyon") ? 0 : 1;
|
||||
if (mode == "migrate-podkop")
|
||||
return migrate_runtime("podkop") ? 0 : 1;
|
||||
if (mode == "import-settings" || mode == "import_settings")
|
||||
return import_settings_cli(argv[1]) ? 0 : 1;
|
||||
if (mode == "commit")
|
||||
return commit_runtime() ? 0 : 1;
|
||||
if (mode == "migrate-fixture") {
|
||||
@@ -1717,6 +1911,7 @@ function main(argv) {
|
||||
|
||||
warn("Usage: config/migration.uc migrate\n");
|
||||
warn(" config/migration.uc migrate-podkop\n");
|
||||
warn(" config/migration.uc import-settings [file]\n");
|
||||
warn(" config/migration.uc commit\n");
|
||||
warn(" config/migration.uc migrate-fixture <fixture.json> [tachyon|podkop]\n");
|
||||
return 1;
|
||||
@@ -1728,6 +1923,9 @@ function module_exports() {
|
||||
migrate_model: migrate_model,
|
||||
migrate_tachyon_model: migrate_tachyon_model,
|
||||
migrate_podkop_model: migrate_podkop_model,
|
||||
scan_legacy_config_candidates: scan_legacy_config_candidates,
|
||||
detect_config_migration_source: detect_config_migration_source,
|
||||
import_settings_cli: import_settings_cli,
|
||||
mark_internal_config_guard: mark_internal_config_guard
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
TACHYON_LIB="$ROOT_DIR/tachyon/files/usr/lib"
|
||||
TACHYON_BIN="$ROOT_DIR/tachyon/files/usr/bin/tachyon"
|
||||
MIGRATION="$TACHYON_LIB/config/migration.uc"
|
||||
WORK_DIR="$(mktemp -d)"
|
||||
|
||||
cleanup() {
|
||||
rm -rf "$WORK_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
fail() {
|
||||
printf 'FAIL: %s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 1. Verify CLI mapping in /usr/bin/tachyon
|
||||
grep -Fq 'import_settings: [ "config/migration.uc", "import-settings", 1 ]' "$TACHYON_BIN" ||
|
||||
fail "tachyon CLI must map import_settings to migration.uc"
|
||||
grep -Fq '"import-settings": [ "config/migration.uc", "import-settings", 1 ]' "$TACHYON_BIN" ||
|
||||
fail "tachyon CLI must map import-settings alias"
|
||||
|
||||
# 2. Test import from explicit legacy Forkop file
|
||||
MOCK_ETC="$WORK_DIR/etc"
|
||||
mkdir -p "$MOCK_ETC/config"
|
||||
|
||||
cat > "$MOCK_ETC/config/forkop" <<'EOF_FORKOP'
|
||||
config settings 'settings'
|
||||
option enabled '1'
|
||||
option dns_server '8.8.8.8'
|
||||
|
||||
config rule 'youtube'
|
||||
option enabled '1'
|
||||
option connection_type 'proxy'
|
||||
option proxy_config_type 'url'
|
||||
option proxy_string 'vless://user@1.2.3.4:443?security=tls#node1'
|
||||
list domain 'youtube.com'
|
||||
list domain 'googlevideo.com'
|
||||
EOF_FORKOP
|
||||
|
||||
# Initial dummy tachyon config
|
||||
cat > "$MOCK_ETC/config/tachyon" <<'EOF_TACHYON'
|
||||
config settings 'settings'
|
||||
option enabled '0'
|
||||
EOF_TACHYON
|
||||
|
||||
cat > "$WORK_DIR/test_import.state" <<'EOF_STATE'
|
||||
tachyon.settings=settings
|
||||
tachyon.settings.enabled=1
|
||||
tachyon.settings.dns_server=8.8.8.8
|
||||
tachyon.youtube=section
|
||||
tachyon.youtube.enabled=1
|
||||
tachyon.youtube.action=proxy
|
||||
tachyon.youtube.proxy_config_type=url
|
||||
tachyon.youtube.proxy_string=vless://user@1.2.3.4:443?security=tls#node1
|
||||
EOF_STATE
|
||||
|
||||
OUTPUT="$(TACHYON_LIB="$TACHYON_LIB" \
|
||||
TACHYON_CONFIG_FILE="$MOCK_ETC/config/tachyon" \
|
||||
TACHYON_CONFIG_DIR="$MOCK_ETC/config" \
|
||||
TACHYON_UCI_STATE_FILE="$WORK_DIR/test_import.state" \
|
||||
TACHYON_UCI_LOG_FILE="$WORK_DIR/test_import.log" \
|
||||
TACHYON_INTERNAL_CONFIG_TRIGGER_GUARD="$WORK_DIR/internal-config-change" \
|
||||
ucode -L "$TACHYON_LIB" "$MIGRATION" import-settings "$MOCK_ETC/config/forkop")"
|
||||
|
||||
echo "$OUTPUT" | grep -Fq 'SUCCESS: Settings successfully imported' ||
|
||||
fail "import_settings must report success on valid legacy file"
|
||||
|
||||
echo "$OUTPUT" | grep -Fq 'Legacy Forkop / Podkop' ||
|
||||
fail "import_settings must recognize legacy format"
|
||||
|
||||
# 3. Test auto-scan in mock directory
|
||||
SCAN_OUTPUT="$(TACHYON_LIB="$TACHYON_LIB" \
|
||||
TACHYON_CONFIG_FILE="$MOCK_ETC/config/tachyon" \
|
||||
TACHYON_CONFIG_DIR="$MOCK_ETC/config" \
|
||||
TACHYON_UCI_STATE_FILE="$WORK_DIR/test_import.state" \
|
||||
TACHYON_UCI_LOG_FILE="$WORK_DIR/test_import.log" \
|
||||
TACHYON_INTERNAL_CONFIG_TRIGGER_GUARD="$WORK_DIR/internal-config-change" \
|
||||
ucode -L "$TACHYON_LIB" "$MIGRATION" import-settings)"
|
||||
|
||||
echo "$SCAN_OUTPUT" | grep -Fq 'SUCCESS: Settings successfully imported' ||
|
||||
fail "import_settings auto-scan must import legacy file"
|
||||
|
||||
# 4. Test non-existent file path error handling
|
||||
ERR_OUTPUT="$(TACHYON_LIB="$TACHYON_LIB" \
|
||||
TACHYON_CONFIG_FILE="$MOCK_ETC/config/tachyon" \
|
||||
TACHYON_CONFIG_DIR="$MOCK_ETC/config" \
|
||||
TACHYON_UCI_STATE_FILE="$WORK_DIR/test_import.state" \
|
||||
TACHYON_UCI_LOG_FILE="$WORK_DIR/test_import.log" \
|
||||
TACHYON_INTERNAL_CONFIG_TRIGGER_GUARD="$WORK_DIR/internal-config-change" \
|
||||
ucode -L "$TACHYON_LIB" "$MIGRATION" import-settings "$WORK_DIR/nonexistent.conf" 2>&1 || true)"
|
||||
echo "$ERR_OUTPUT" | grep -Fq 'does not exist' ||
|
||||
fail "import_settings must handle missing file with error"
|
||||
|
||||
printf 'import_settings tests passed\n'
|
||||
Reference in New Issue
Block a user