feat: карточки сервисов на дашборде + секция Hosts в правилах + скрытие вкладки Conditions для Hosts
Дашборд: - Добавлены карточки статуса Zapret, Zapret2, ByeDpi на панель мониторинга - Показывают статус (работает/остановлен), количество перезапусков, предупреждения - Баг: API возвращает boolean а не число — исправлено сравнение Секция Hosts: - Перенесены опции hosts из глобальных настроек в отдельный тип секции (action=hosts) - Опции: пользовательские DNS записи, удалённые списки хостов, автообновление, интервал - Миграция: автоматический перенос глобальных настроек hosts в секцию - Вкладка «Условия» скрыта для секций типа Hosts (hosts записи применяются глобально) - Возвращена кнопка «Import Hosts File» с модальным окном загрузки из файла - Убраны неиспользуемые опции из settings.js (~280 строк) Локализация: - Переведены 6 новых строк для превью импорта hosts
This commit is contained in:
@@ -103,6 +103,7 @@ const PRIORITY_UC = LIB_DIR + "/singbox/priority.uc";
|
||||
const DNS_FAILOVER_UC = LIB_DIR + "/singbox/dns_failover.uc";
|
||||
const SUBSCRIPTION_CACHE_UC = LIB_DIR + "/subscription/cache.uc";
|
||||
const UPDATES_UC = LIB_DIR + "/components/updates.uc";
|
||||
const HOSTS_UC = LIB_DIR + "/components/hosts.uc";
|
||||
const STATE_UC = LIB_DIR + "/service/state.uc";
|
||||
const RELOAD_UC = LIB_DIR + "/service/reload.uc";
|
||||
const UI_UC = LIB_DIR + "/service/ui.uc";
|
||||
@@ -747,6 +748,8 @@ function start_main() {
|
||||
if (status != 0)
|
||||
return status;
|
||||
|
||||
module_background(HOSTS_UC, [ "list-update" ]);
|
||||
|
||||
status = module_status(SINGBOX_UC, [ "configure-service" ]);
|
||||
if (status != 0)
|
||||
return status;
|
||||
@@ -1048,6 +1051,7 @@ function parse_reload_plan(output) {
|
||||
changed_byedpi_runtime: 0,
|
||||
changed_cron: 0,
|
||||
changed_list: 0,
|
||||
changed_hosts_list: 0,
|
||||
needs_sing_box_reload: 0,
|
||||
needs_nft_rebuild: 0,
|
||||
needs_zapret_restart: 0,
|
||||
@@ -1057,6 +1061,7 @@ function parse_reload_plan(output) {
|
||||
needs_dnsmasq_restore: 0,
|
||||
needs_cron_refresh: 0,
|
||||
needs_list_update: 0,
|
||||
needs_hosts_update: 0,
|
||||
has_work: 0
|
||||
};
|
||||
|
||||
@@ -1091,6 +1096,7 @@ function reload_actions_summary(plan) {
|
||||
actions = append_reload_action(actions, plan.needs_dnsmasq_configure || plan.needs_dnsmasq_restore, "dnsmasq");
|
||||
actions = append_reload_action(actions, plan.needs_cron_refresh, "scheduled jobs");
|
||||
actions = append_reload_action(actions, plan.needs_list_update, "remote lists");
|
||||
actions = append_reload_action(actions, plan.needs_hosts_update, "hosts lists");
|
||||
return actions;
|
||||
}
|
||||
|
||||
@@ -1270,6 +1276,9 @@ function reload(reason) {
|
||||
if (plan.needs_byedpi_restart == 1)
|
||||
module_success(BYEDPI_UC, [ "stop-runtime" ]);
|
||||
|
||||
if (plan.needs_hosts_update == 1)
|
||||
module_success(HOSTS_UC, [ "list-update" ]);
|
||||
|
||||
if (plan.needs_nft_rebuild == 1) {
|
||||
log_message("Rebuilding nftables rules", "info");
|
||||
status = nft_rebuild_runtime();
|
||||
|
||||
@@ -65,6 +65,7 @@ function emit_reload_plan(previous, current, context) {
|
||||
zapret2_runtime: current.zapret2_runtime != previous.zapret2_runtime,
|
||||
byedpi_runtime: current.byedpi_runtime != previous.byedpi_runtime,
|
||||
list: current.list != previous.list,
|
||||
hosts_list: current.hosts_list != previous.hosts_list,
|
||||
cron: current.cron != previous.cron
|
||||
};
|
||||
|
||||
@@ -77,7 +78,8 @@ function emit_reload_plan(previous, current, context) {
|
||||
dnsmasq_configure: false,
|
||||
dnsmasq_restore: false,
|
||||
cron_refresh: false,
|
||||
list_update: false
|
||||
list_update: false,
|
||||
hosts_update: false
|
||||
};
|
||||
|
||||
if (changed.sing_box)
|
||||
@@ -120,6 +122,11 @@ function emit_reload_plan(previous, current, context) {
|
||||
if (changed.list && context.has_list_update_sources)
|
||||
needs.list_update = true;
|
||||
|
||||
if (changed.hosts_list) {
|
||||
needs.hosts_update = true;
|
||||
needs.sing_box_reload = true;
|
||||
}
|
||||
|
||||
if (needs.nft_rebuild && context.has_nft_list_update_sources)
|
||||
needs.list_update = true;
|
||||
|
||||
@@ -147,7 +154,8 @@ function emit_reload_plan(previous, current, context) {
|
||||
needs.dnsmasq_configure ||
|
||||
needs.dnsmasq_restore ||
|
||||
needs.cron_refresh ||
|
||||
needs.list_update;
|
||||
needs.list_update ||
|
||||
needs.hosts_update;
|
||||
|
||||
emit("urltest_new_enabled_sections", new_urltest_enabled_sections(
|
||||
previous.urltest_sections,
|
||||
@@ -166,6 +174,7 @@ function emit_reload_plan(previous, current, context) {
|
||||
emit_bool("changed_byedpi_runtime", changed.byedpi_runtime);
|
||||
emit_bool("changed_cron", changed.cron);
|
||||
emit_bool("changed_list", changed.list);
|
||||
emit_bool("changed_hosts_list", changed.hosts_list);
|
||||
|
||||
emit_bool("needs_sing_box_reload", needs.sing_box_reload);
|
||||
emit_bool("needs_nft_rebuild", needs.nft_rebuild);
|
||||
@@ -176,6 +185,7 @@ function emit_reload_plan(previous, current, context) {
|
||||
emit_bool("needs_dnsmasq_restore", needs.dnsmasq_restore);
|
||||
emit_bool("needs_cron_refresh", needs.cron_refresh);
|
||||
emit_bool("needs_list_update", needs.list_update);
|
||||
emit_bool("needs_hosts_update", needs.hosts_update);
|
||||
emit_bool("has_work", has_work);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,6 +167,7 @@ const RELOAD_STATE_FIELDS = [
|
||||
"zapret2_runtime_signature",
|
||||
"byedpi_runtime_signature",
|
||||
"list_signature",
|
||||
"hosts_list_signature",
|
||||
"cron_signature",
|
||||
"urltest_enabled_sections",
|
||||
"dont_touch_dhcp"
|
||||
@@ -715,6 +716,8 @@ function rule_has_list_update_source(enabled, action, community_lists, remote_do
|
||||
return false;
|
||||
if (as_string(action) == "dns")
|
||||
return list_has_remote_references(domain_ip_lists);
|
||||
if (as_string(action) == "hosts")
|
||||
return false;
|
||||
|
||||
return (
|
||||
has_community_subnet_list(community_lists) ||
|
||||
@@ -726,7 +729,7 @@ function rule_has_list_update_source(enabled, action, community_lists, remote_do
|
||||
}
|
||||
|
||||
function rule_has_nft_list_update_source(enabled, action, community_lists, remote_subnet_lists, rule_set_with_subnets, domain_ip_lists) {
|
||||
if (!arg_bool(enabled) || as_string(action) == "dns")
|
||||
if (!arg_bool(enabled) || as_string(action) == "dns" || as_string(action) == "hosts")
|
||||
return false;
|
||||
|
||||
return (
|
||||
@@ -917,7 +920,7 @@ function nft_runtime_signature_body(settings, sections) {
|
||||
|
||||
let action = option(section, "action", "");
|
||||
body = signature_add_value(body, "rule." + name + ".action", action);
|
||||
if (action == "dns")
|
||||
if (action == "dns" || action == "hosts")
|
||||
continue;
|
||||
body = signature_add_value(body, "rule." + name + ".ip_cidr", section_rule_condition_csv(section, "ip_cidr", "subnets"));
|
||||
body = signature_add_value(body, "rule." + name + ".source_ip_cidr", section_rule_condition_csv(section, "source_ip_cidr", "subnets"));
|
||||
@@ -1130,6 +1133,14 @@ function append_list_update_signature_body(body, section) {
|
||||
body = signature_add_value(body, "lists." + name + ".domain_ip_lists", option(section, "domain_ip_lists", ""));
|
||||
return body;
|
||||
}
|
||||
if (action == "hosts") {
|
||||
body = signature_add_value(body, "lists." + name + ".hosts_list_urls", option(section, "hosts_list_urls", ""));
|
||||
body = signature_add_value(body, "lists." + name + ".hosts_list_disabled", option(section, "hosts_list_disabled", ""));
|
||||
body = signature_add_value(body, "lists." + name + ".dns_hosts", option(section, "dns_hosts", ""));
|
||||
body = signature_add_value(body, "lists." + name + ".hosts_list_auto_update", option(section, "hosts_list_auto_update", ""));
|
||||
body = signature_add_value(body, "lists." + name + ".hosts_list_update_interval", option(section, "hosts_list_update_interval", ""));
|
||||
return body;
|
||||
}
|
||||
|
||||
body = signature_add_value(body, "lists." + name + ".ports", section_rule_ports_csv(section));
|
||||
body = signature_add_value(body, "lists." + name + ".community_subnet_lists", rule_config.filter_community_subnet_lists_value(connections.community_lists_value(section)));
|
||||
@@ -1150,6 +1161,24 @@ function list_update_signature_body(sections) {
|
||||
return body;
|
||||
}
|
||||
|
||||
function hosts_list_signature_body(sections) {
|
||||
let body = "";
|
||||
for (let section in sections) {
|
||||
section = object_or_empty(section);
|
||||
if (option(section, "action", "") != "hosts")
|
||||
continue;
|
||||
if (!bool_option(section, "enabled", true))
|
||||
continue;
|
||||
let name = section_name(section);
|
||||
body = signature_add_value(body, "hosts." + name + ".hosts_list_urls", option(section, "hosts_list_urls", ""));
|
||||
body = signature_add_value(body, "hosts." + name + ".hosts_list_disabled", option(section, "hosts_list_disabled", ""));
|
||||
body = signature_add_value(body, "hosts." + name + ".dns_hosts", option(section, "dns_hosts", ""));
|
||||
body = signature_add_value(body, "hosts." + name + ".hosts_list_auto_update", option(section, "hosts_list_auto_update", "0"));
|
||||
body = signature_add_value(body, "hosts." + name + ".hosts_list_update_interval", option(section, "hosts_list_update_interval", ""));
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
function cron_signature_body(settings, sections) {
|
||||
let body = signature_add_value("", "settings.update_interval", settings_update_interval(settings));
|
||||
body = signature_add_value(body, "settings.component_update_check_interval", settings_component_update_check_interval(settings));
|
||||
@@ -1167,6 +1196,17 @@ function cron_signature_body(settings, sections) {
|
||||
body = signature_add_value(body, "subscription." + name + ".subscription_update_interval", section_subscription_update_interval(section));
|
||||
}
|
||||
|
||||
for (let section in sections) {
|
||||
section = object_or_empty(section);
|
||||
if (option(section, "action", "") != "hosts")
|
||||
continue;
|
||||
if (!bool_option(section, "enabled", true))
|
||||
continue;
|
||||
let name = section_name(section);
|
||||
body = signature_add_value(body, "hosts." + name + ".hosts_list_auto_update", option(section, "hosts_list_auto_update", "0"));
|
||||
body = signature_add_value(body, "hosts." + name + ".hosts_list_update_interval", option(section, "hosts_list_update_interval", ""));
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
@@ -1305,6 +1345,11 @@ function append_sing_box_rule_signature_body(body, section, sections) {
|
||||
if (bool_option(section, "dns_detour_enabled", false))
|
||||
body = signature_add_value(body, prefix + ".dns_detour_section", option(section, "dns_detour_section", ""));
|
||||
}
|
||||
else if (action == "hosts") {
|
||||
body = signature_add_value(body, prefix + ".hosts_list_urls", option(section, "hosts_list_urls", ""));
|
||||
body = signature_add_value(body, prefix + ".hosts_list_disabled", option(section, "hosts_list_disabled", ""));
|
||||
body = signature_add_value(body, prefix + ".dns_hosts", option(section, "dns_hosts", ""));
|
||||
}
|
||||
|
||||
body = signature_add_value(body, prefix + ".domain", section_rule_condition_csv(section, "domain", "domains"));
|
||||
body = signature_add_value(body, prefix + ".domain_suffix", section_rule_condition_csv(section, "domain_suffix", "domains"));
|
||||
@@ -1599,6 +1644,7 @@ function reload_state_values_from_sources(format, settings, sections, servers, d
|
||||
zapret2_runtime_signature: signature_hash(zapret2_runtime_signature_body(sections)),
|
||||
byedpi_runtime_signature: signature_hash(byedpi_runtime_signature_body(sections)),
|
||||
list_signature: signature_hash(list_update_signature_body(sections)),
|
||||
hosts_list_signature: signature_hash(hosts_list_signature_body(sections)),
|
||||
cron_signature: signature_hash(cron_signature_body(settings, sections)),
|
||||
urltest_enabled_sections: urltest_enabled_sections_value(sections),
|
||||
dont_touch_dhcp: dont_touch_dhcp_value(settings)
|
||||
@@ -2018,6 +2064,12 @@ else if (mode == "list-update-signature-fixture") {
|
||||
let data = fixture_data(ARGV[1]);
|
||||
exit(print_signature_hash(list_update_signature_body(fixture_section_list(data))) ? 0 : 1);
|
||||
}
|
||||
else if (mode == "hosts-list-signature")
|
||||
exit(print_signature_hash(hosts_list_signature_body(uci_sections("section"))) ? 0 : 1);
|
||||
else if (mode == "hosts-list-signature-fixture") {
|
||||
let data = fixture_data(ARGV[1]);
|
||||
exit(print_signature_hash(hosts_list_signature_body(fixture_section_list(data))) ? 0 : 1);
|
||||
}
|
||||
else if (mode == "cron-signature")
|
||||
exit(print_signature_hash(cron_signature_body(uci_settings(), uci_sections("section"))) ? 0 : 1);
|
||||
else if (mode == "cron-signature-fixture") {
|
||||
|
||||
Reference in New Issue
Block a user