迁移配置表

This commit is contained in:
ryan
2026-06-22 19:49:37 +08:00
parent d9b8dc81ee
commit 92ceecc6ce
53 changed files with 1928 additions and 1152 deletions
+8 -8
View File
@@ -99,8 +99,8 @@ func TestMigrateUpgradesLegacyDatabaseAndPreservesData(t *testing.T) {
// Legacy normal user
`INSERT INTO users (id, username, password, display_name, role, status, email)
VALUES (2, 'jack', 'hashed_pass_456', 'Normal User jack', 10, 1, 'jack@example.com');`,
// Legacy config options
`INSERT INTO options (key, value) VALUES ('SystemName', 'CustomOpenFlare');`,
// Legacy config options(GeoIPProvider 会被迁移到 w_system_configs.geoip_provider)
`INSERT INTO options (key, value) VALUES ('GeoIPProvider', 'ip-api');`,
// Legacy origin
`INSERT INTO origins (id, name, address, remark, created_at, updated_at)
VALUES (10, 'my_origin', '127.0.0.1:8080', 'original origin', '2026-06-01 12:00:00', '2026-06-01 12:00:00');`,
@@ -181,13 +181,13 @@ func TestMigrateUpgradesLegacyDatabaseAndPreservesData(t *testing.T) {
t.Errorf("jack user migrated incorrectly: %+v", jackUser)
}
// Verify options migrated to of_options
var systemNameVal string
if err := sqliteDB.Table("of_options").Where("key = ?", "SystemName").Select("value").Scan(&systemNameVal).Error; err != nil {
t.Fatalf("query SystemName failed: %v", err)
// Verify legacy option migrated all the way to w_system_configs(of_options 已被删除)
var geoIPProviderVal string
if err := sqliteDB.Table("w_system_configs").Where("key = ?", "geoip_provider").Select("value").Scan(&geoIPProviderVal).Error; err != nil {
t.Fatalf("query geoip_provider failed: %v", err)
}
if systemNameVal != "CustomOpenFlare" {
t.Errorf("SystemName value incorrect: got %s, want CustomOpenFlare", systemNameVal)
if geoIPProviderVal != "ip-api" {
t.Errorf("geoip_provider value incorrect: got %s, want ip-api", geoIPProviderVal)
}
// Verify origin migrated to of_origins
@@ -0,0 +1,347 @@
-- +goose Up
-- 将 of_options 配置迁移到 w_system_configs(仅迁移新配置,已存在的不重复)
-- Agent 相关配置 (business, visibility=0)
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'agent_discovery_token', COALESCE(value, ''), 'business', 0, 'Agent 发现令牌'
FROM of_options WHERE key = 'AgentDiscoveryToken'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'agent_heartbeat_interval', value, 'business', 0, 'Agent 心跳间隔(毫秒)'
FROM of_options WHERE key = 'AgentHeartbeatInterval'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'agent_websocket_upgrade_enabled', value, 'business', 0, 'Agent WebSocket 升级开关'
FROM of_options WHERE key = 'AgentWebsocketUpgradeEnabled'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'node_offline_threshold', value, 'business', 0, '节点离线阈值(毫秒)'
FROM of_options WHERE key = 'NodeOfflineThreshold'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'agent_update_repo', value, 'business', 0, 'Agent 更新仓库'
FROM of_options WHERE key = 'AgentUpdateRepo'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
-- 系统功能配置 (business, visibility=0)
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'geoip_provider', value, 'business', 0, 'GeoIP 服务商'
FROM of_options WHERE key = 'GeoIPProvider'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'database_auto_cleanup_enabled', value, 'business', 0, '数据库自动清理开关'
FROM of_options WHERE key = 'DatabaseAutoCleanupEnabled'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'database_auto_cleanup_retention_days', value, 'business', 0, '数据库保留天数'
FROM of_options WHERE key = 'DatabaseAutoCleanupRetentionDays'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
-- UptimeKuma 集成配置 (business, visibility=0)
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_enabled', value, 'business', 0, 'UptimeKuma 集成开关'
FROM of_options WHERE key = 'UptimeKumaEnabled'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_url', COALESCE(value, ''), 'business', 0, 'UptimeKuma URL'
FROM of_options WHERE key = 'UptimeKumaUrl'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_username', COALESCE(value, ''), 'business', 0, 'UptimeKuma 用户名'
FROM of_options WHERE key = 'UptimeKumaUsername'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_password', COALESCE(value, ''), 'business', 0, 'UptimeKuma 密码'
FROM of_options WHERE key = 'UptimeKumaPassword'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_monitor_scope', value, 'business', 0, 'UptimeKuma 监控范围'
FROM of_options WHERE key = 'UptimeKumaMonitorScope'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_selected_sites', COALESCE(value, ''), 'business', 0, 'UptimeKuma 选定站点'
FROM of_options WHERE key = 'UptimeKumaSelectedSites'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_sync_interval', value, 'business', 0, 'UptimeKuma 同步间隔(分钟)'
FROM of_options WHERE key = 'UptimeKumaSyncInterval'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_interval', value, 'business', 0, 'UptimeKuma 监控间隔(秒)'
FROM of_options WHERE key = 'UptimeKumaInterval'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_retry', value, 'business', 0, 'UptimeKuma 重试次数'
FROM of_options WHERE key = 'UptimeKumaRetry'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_retry_interval', value, 'business', 0, 'UptimeKuma 重试间隔(秒)'
FROM of_options WHERE key = 'UptimeKumaRetryInterval'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_timeout', value, 'business', 0, 'UptimeKuma 超时(秒)'
FROM of_options WHERE key = 'UptimeKumaTimeout'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
-- OpenResty 配置(全部 business 类型,visibility=0)
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_default_server_return_status', value, 'business', 0, '默认服务器返回状态码'
FROM of_options WHERE key = 'OpenRestyDefaultServerReturnStatus'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_worker_processes', value, 'business', 0, 'Worker 进程数'
FROM of_options WHERE key = 'OpenRestyWorkerProcesses'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_worker_connections', value, 'business', 0, 'Worker 连接数'
FROM of_options WHERE key = 'OpenRestyWorkerConnections'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_worker_rlimit_nofile', value, 'business', 0, 'Worker 文件描述符限制'
FROM of_options WHERE key = 'OpenRestyWorkerRlimitNofile'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_events_use', value, 'business', 0, '事件模型'
FROM of_options WHERE key = 'OpenRestyEventsUse'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_events_multi_accept_enabled', value, 'business', 0, '多路接受开关'
FROM of_options WHERE key = 'OpenRestyEventsMultiAcceptEnabled'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_keepalive_timeout', value, 'business', 0, 'Keepalive 超时(秒)'
FROM of_options WHERE key = 'OpenRestyKeepaliveTimeout'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_keepalive_requests', value, 'business', 0, 'Keepalive 请求数'
FROM of_options WHERE key = 'OpenRestyKeepaliveRequests'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_client_header_timeout', value, 'business', 0, '客户端头超时(秒)'
FROM of_options WHERE key = 'OpenRestyClientHeaderTimeout'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_client_body_timeout', value, 'business', 0, '客户端体超时(秒)'
FROM of_options WHERE key = 'OpenRestyClientBodyTimeout'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_client_max_body_size', value, 'business', 0, '客户端最大体大小'
FROM of_options WHERE key = 'OpenRestyClientMaxBodySize'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_large_client_header_buffers', value, 'business', 0, '大客户端头缓冲区'
FROM of_options WHERE key = 'OpenRestyLargeClientHeaderBuffers'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_send_timeout', value, 'business', 0, '发送超时(秒)'
FROM of_options WHERE key = 'OpenRestySendTimeout'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_resolvers', COALESCE(value, ''), 'business', 0, 'DNS 解析器'
FROM of_options WHERE key = 'OpenRestyResolvers'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_connect_timeout', value, 'business', 0, '代理连接超时(秒)'
FROM of_options WHERE key = 'OpenRestyProxyConnectTimeout'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_send_timeout', value, 'business', 0, '代理发送超时(秒)'
FROM of_options WHERE key = 'OpenRestyProxySendTimeout'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_read_timeout', value, 'business', 0, '代理读取超时(秒)'
FROM of_options WHERE key = 'OpenRestyProxyReadTimeout'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_websocket_enabled', value, 'business', 0, 'WebSocket 支持开关'
FROM of_options WHERE key = 'OpenRestyWebsocketEnabled'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_http3_enabled', value, 'business', 0, 'HTTP/3 支持开关'
FROM of_options WHERE key = 'OpenRestyHTTP3Enabled'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_request_buffering_enabled', value, 'business', 0, '代理请求缓冲开关'
FROM of_options WHERE key = 'OpenRestyProxyRequestBufferingEnabled'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_buffering_enabled', value, 'business', 0, '代理响应缓冲开关'
FROM of_options WHERE key = 'OpenRestyProxyBufferingEnabled'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_buffers', value, 'business', 0, '代理缓冲区'
FROM of_options WHERE key = 'OpenRestyProxyBuffers'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_buffer_size', value, 'business', 0, '代理缓冲区大小'
FROM of_options WHERE key = 'OpenRestyProxyBufferSize'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_busy_buffers_size', value, 'business', 0, '代理繁忙缓冲区大小'
FROM of_options WHERE key = 'OpenRestyProxyBusyBuffersSize'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_gzip_enabled', value, 'business', 0, 'Gzip 压缩开关'
FROM of_options WHERE key = 'OpenRestyGzipEnabled'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_gzip_min_length', value, 'business', 0, 'Gzip 最小长度'
FROM of_options WHERE key = 'OpenRestyGzipMinLength'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_gzip_comp_level', value, 'business', 0, 'Gzip 压缩级别'
FROM of_options WHERE key = 'OpenRestyGzipCompLevel'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_enabled', value, 'business', 0, '缓存开关'
FROM of_options WHERE key = 'OpenRestyCacheEnabled'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_path', COALESCE(value, ''), 'business', 0, '缓存路径'
FROM of_options WHERE key = 'OpenRestyCachePath'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_levels', value, 'business', 0, '缓存层级'
FROM of_options WHERE key = 'OpenRestyCacheLevels'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_inactive', value, 'business', 0, '缓存不活跃时间'
FROM of_options WHERE key = 'OpenRestyCacheInactive'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_max_size', value, 'business', 0, '缓存最大大小'
FROM of_options WHERE key = 'OpenRestyCacheMaxSize'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_key_template', value, 'business', 0, '缓存键模板'
FROM of_options WHERE key = 'OpenRestyCacheKeyTemplate'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_lock_enabled', value, 'business', 0, '缓存锁开关'
FROM of_options WHERE key = 'OpenRestyCacheLockEnabled'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_lock_timeout', value, 'business', 0, '缓存锁超时'
FROM of_options WHERE key = 'OpenRestyCacheLockTimeout'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_use_stale', value, 'business', 0, '缓存失效策略'
FROM of_options WHERE key = 'OpenRestyCacheUseStale'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_main_config_template', value, 'business', 0, '主配置模板'
FROM of_options WHERE key = 'OpenRestyMainConfigTemplate'
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
-- +goose Down
-- 回滚时删除所有迁移的配置项
DELETE FROM w_system_configs WHERE key IN (
'agent_discovery_token',
'agent_heartbeat_interval',
'agent_websocket_upgrade_enabled',
'node_offline_threshold',
'agent_update_repo',
'geoip_provider',
'database_auto_cleanup_enabled',
'database_auto_cleanup_retention_days',
'uptime_kuma_enabled',
'uptime_kuma_url',
'uptime_kuma_username',
'uptime_kuma_password',
'uptime_kuma_monitor_scope',
'uptime_kuma_selected_sites',
'uptime_kuma_sync_interval',
'uptime_kuma_interval',
'uptime_kuma_retry',
'uptime_kuma_retry_interval',
'uptime_kuma_timeout',
'openresty_default_server_return_status',
'openresty_worker_processes',
'openresty_worker_connections',
'openresty_worker_rlimit_nofile',
'openresty_events_use',
'openresty_events_multi_accept_enabled',
'openresty_keepalive_timeout',
'openresty_keepalive_requests',
'openresty_client_header_timeout',
'openresty_client_body_timeout',
'openresty_client_max_body_size',
'openresty_large_client_header_buffers',
'openresty_send_timeout',
'openresty_resolvers',
'openresty_proxy_connect_timeout',
'openresty_proxy_send_timeout',
'openresty_proxy_read_timeout',
'openresty_websocket_enabled',
'openresty_http3_enabled',
'openresty_proxy_request_buffering_enabled',
'openresty_proxy_buffering_enabled',
'openresty_proxy_buffers',
'openresty_proxy_buffer_size',
'openresty_proxy_busy_buffers_size',
'openresty_gzip_enabled',
'openresty_gzip_min_length',
'openresty_gzip_comp_level',
'openresty_cache_enabled',
'openresty_cache_path',
'openresty_cache_levels',
'openresty_cache_inactive',
'openresty_cache_max_size',
'openresty_cache_key_template',
'openresty_cache_lock_enabled',
'openresty_cache_lock_timeout',
'openresty_cache_use_stale',
'openresty_main_config_template'
);
@@ -0,0 +1,10 @@
-- +goose Up
-- of_options 配置已于 202606220004 迁移至 w_system_configs,删除遗留表。
DROP TABLE IF EXISTS of_options;
-- +goose Down
-- 回滚时重建空表结构(数据无法恢复,迁移来源已为 w_system_configs)。
CREATE TABLE IF NOT EXISTS of_options (
key VARCHAR(128) PRIMARY KEY,
value TEXT NOT NULL DEFAULT ''
);
@@ -0,0 +1,291 @@
-- +goose Up
-- 将 of_options 配置迁移到 w_system_configs(仅迁移新配置,已存在的不重复)
-- Agent 相关配置 (business, visibility=0)
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'agent_discovery_token', COALESCE(value, ''), 'business', 0, 'Agent 发现令牌'
FROM of_options WHERE key = 'AgentDiscoveryToken';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'agent_heartbeat_interval', value, 'business', 0, 'Agent 心跳间隔(毫秒)'
FROM of_options WHERE key = 'AgentHeartbeatInterval';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'agent_websocket_upgrade_enabled', value, 'business', 0, 'Agent WebSocket 升级开关'
FROM of_options WHERE key = 'AgentWebsocketUpgradeEnabled';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'node_offline_threshold', value, 'business', 0, '节点离线阈值(毫秒)'
FROM of_options WHERE key = 'NodeOfflineThreshold';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'agent_update_repo', value, 'business', 0, 'Agent 更新仓库'
FROM of_options WHERE key = 'AgentUpdateRepo';
-- 系统功能配置 (business, visibility=0)
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'geoip_provider', value, 'business', 0, 'GeoIP 服务商'
FROM of_options WHERE key = 'GeoIPProvider';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'database_auto_cleanup_enabled', value, 'business', 0, '数据库自动清理开关'
FROM of_options WHERE key = 'DatabaseAutoCleanupEnabled';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'database_auto_cleanup_retention_days', value, 'business', 0, '数据库保留天数'
FROM of_options WHERE key = 'DatabaseAutoCleanupRetentionDays';
-- UptimeKuma 集成配置 (business, visibility=0)
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_enabled', value, 'business', 0, 'UptimeKuma 集成开关'
FROM of_options WHERE key = 'UptimeKumaEnabled';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_url', COALESCE(value, ''), 'business', 0, 'UptimeKuma URL'
FROM of_options WHERE key = 'UptimeKumaUrl';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_username', COALESCE(value, ''), 'business', 0, 'UptimeKuma 用户名'
FROM of_options WHERE key = 'UptimeKumaUsername';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_password', COALESCE(value, ''), 'business', 0, 'UptimeKuma 密码'
FROM of_options WHERE key = 'UptimeKumaPassword';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_monitor_scope', value, 'business', 0, 'UptimeKuma 监控范围'
FROM of_options WHERE key = 'UptimeKumaMonitorScope';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_selected_sites', COALESCE(value, ''), 'business', 0, 'UptimeKuma 选定站点'
FROM of_options WHERE key = 'UptimeKumaSelectedSites';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_sync_interval', value, 'business', 0, 'UptimeKuma 同步间隔(分钟)'
FROM of_options WHERE key = 'UptimeKumaSyncInterval';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_interval', value, 'business', 0, 'UptimeKuma 监控间隔(秒)'
FROM of_options WHERE key = 'UptimeKumaInterval';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_retry', value, 'business', 0, 'UptimeKuma 重试次数'
FROM of_options WHERE key = 'UptimeKumaRetry';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_retry_interval', value, 'business', 0, 'UptimeKuma 重试间隔(秒)'
FROM of_options WHERE key = 'UptimeKumaRetryInterval';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'uptime_kuma_timeout', value, 'business', 0, 'UptimeKuma 超时(秒)'
FROM of_options WHERE key = 'UptimeKumaTimeout';
-- OpenResty 配置(全部 business 类型,visibility=0)
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_default_server_return_status', value, 'business', 0, '默认服务器返回状态码'
FROM of_options WHERE key = 'OpenRestyDefaultServerReturnStatus';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_worker_processes', value, 'business', 0, 'Worker 进程数'
FROM of_options WHERE key = 'OpenRestyWorkerProcesses';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_worker_connections', value, 'business', 0, 'Worker 连接数'
FROM of_options WHERE key = 'OpenRestyWorkerConnections';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_worker_rlimit_nofile', value, 'business', 0, 'Worker 文件描述符限制'
FROM of_options WHERE key = 'OpenRestyWorkerRlimitNofile';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_events_use', value, 'business', 0, '事件模型'
FROM of_options WHERE key = 'OpenRestyEventsUse';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_events_multi_accept_enabled', value, 'business', 0, '多路接受开关'
FROM of_options WHERE key = 'OpenRestyEventsMultiAcceptEnabled';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_keepalive_timeout', value, 'business', 0, 'Keepalive 超时(秒)'
FROM of_options WHERE key = 'OpenRestyKeepaliveTimeout';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_keepalive_requests', value, 'business', 0, 'Keepalive 请求数'
FROM of_options WHERE key = 'OpenRestyKeepaliveRequests';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_client_header_timeout', value, 'business', 0, '客户端头超时(秒)'
FROM of_options WHERE key = 'OpenRestyClientHeaderTimeout';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_client_body_timeout', value, 'business', 0, '客户端体超时(秒)'
FROM of_options WHERE key = 'OpenRestyClientBodyTimeout';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_client_max_body_size', value, 'business', 0, '客户端最大体大小'
FROM of_options WHERE key = 'OpenRestyClientMaxBodySize';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_large_client_header_buffers', value, 'business', 0, '大客户端头缓冲区'
FROM of_options WHERE key = 'OpenRestyLargeClientHeaderBuffers';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_send_timeout', value, 'business', 0, '发送超时(秒)'
FROM of_options WHERE key = 'OpenRestySendTimeout';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_resolvers', COALESCE(value, ''), 'business', 0, 'DNS 解析器'
FROM of_options WHERE key = 'OpenRestyResolvers';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_connect_timeout', value, 'business', 0, '代理连接超时(秒)'
FROM of_options WHERE key = 'OpenRestyProxyConnectTimeout';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_send_timeout', value, 'business', 0, '代理发送超时(秒)'
FROM of_options WHERE key = 'OpenRestyProxySendTimeout';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_read_timeout', value, 'business', 0, '代理读取超时(秒)'
FROM of_options WHERE key = 'OpenRestyProxyReadTimeout';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_websocket_enabled', value, 'business', 0, 'WebSocket 支持开关'
FROM of_options WHERE key = 'OpenRestyWebsocketEnabled';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_http3_enabled', value, 'business', 0, 'HTTP/3 支持开关'
FROM of_options WHERE key = 'OpenRestyHTTP3Enabled';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_request_buffering_enabled', value, 'business', 0, '代理请求缓冲开关'
FROM of_options WHERE key = 'OpenRestyProxyRequestBufferingEnabled';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_buffering_enabled', value, 'business', 0, '代理响应缓冲开关'
FROM of_options WHERE key = 'OpenRestyProxyBufferingEnabled';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_buffers', value, 'business', 0, '代理缓冲区'
FROM of_options WHERE key = 'OpenRestyProxyBuffers';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_buffer_size', value, 'business', 0, '代理缓冲区大小'
FROM of_options WHERE key = 'OpenRestyProxyBufferSize';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_proxy_busy_buffers_size', value, 'business', 0, '代理繁忙缓冲区大小'
FROM of_options WHERE key = 'OpenRestyProxyBusyBuffersSize';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_gzip_enabled', value, 'business', 0, 'Gzip 压缩开关'
FROM of_options WHERE key = 'OpenRestyGzipEnabled';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_gzip_min_length', value, 'business', 0, 'Gzip 最小长度'
FROM of_options WHERE key = 'OpenRestyGzipMinLength';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_gzip_comp_level', value, 'business', 0, 'Gzip 压缩级别'
FROM of_options WHERE key = 'OpenRestyGzipCompLevel';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_enabled', value, 'business', 0, '缓存开关'
FROM of_options WHERE key = 'OpenRestyCacheEnabled';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_path', COALESCE(value, ''), 'business', 0, '缓存路径'
FROM of_options WHERE key = 'OpenRestyCachePath';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_levels', value, 'business', 0, '缓存层级'
FROM of_options WHERE key = 'OpenRestyCacheLevels';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_inactive', value, 'business', 0, '缓存不活跃时间'
FROM of_options WHERE key = 'OpenRestyCacheInactive';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_max_size', value, 'business', 0, '缓存最大大小'
FROM of_options WHERE key = 'OpenRestyCacheMaxSize';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_key_template', value, 'business', 0, '缓存键模板'
FROM of_options WHERE key = 'OpenRestyCacheKeyTemplate';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_lock_enabled', value, 'business', 0, '缓存锁开关'
FROM of_options WHERE key = 'OpenRestyCacheLockEnabled';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_lock_timeout', value, 'business', 0, '缓存锁超时'
FROM of_options WHERE key = 'OpenRestyCacheLockTimeout';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_cache_use_stale', value, 'business', 0, '缓存失效策略'
FROM of_options WHERE key = 'OpenRestyCacheUseStale';
INSERT OR REPLACE INTO w_system_configs (key, value, type, visibility, description)
SELECT 'openresty_main_config_template', value, 'business', 0, '主配置模板'
FROM of_options WHERE key = 'OpenRestyMainConfigTemplate';
-- +goose Down
-- 回滚时删除所有迁移的配置项
DELETE FROM w_system_configs WHERE key IN (
'agent_discovery_token',
'agent_heartbeat_interval',
'agent_websocket_upgrade_enabled',
'node_offline_threshold',
'agent_update_repo',
'geoip_provider',
'database_auto_cleanup_enabled',
'database_auto_cleanup_retention_days',
'uptime_kuma_enabled',
'uptime_kuma_url',
'uptime_kuma_username',
'uptime_kuma_password',
'uptime_kuma_monitor_scope',
'uptime_kuma_selected_sites',
'uptime_kuma_sync_interval',
'uptime_kuma_interval',
'uptime_kuma_retry',
'uptime_kuma_retry_interval',
'uptime_kuma_timeout',
'openresty_default_server_return_status',
'openresty_worker_processes',
'openresty_worker_connections',
'openresty_worker_rlimit_nofile',
'openresty_events_use',
'openresty_events_multi_accept_enabled',
'openresty_keepalive_timeout',
'openresty_keepalive_requests',
'openresty_client_header_timeout',
'openresty_client_body_timeout',
'openresty_client_max_body_size',
'openresty_large_client_header_buffers',
'openresty_send_timeout',
'openresty_resolvers',
'openresty_proxy_connect_timeout',
'openresty_proxy_send_timeout',
'openresty_proxy_read_timeout',
'openresty_websocket_enabled',
'openresty_http3_enabled',
'openresty_proxy_request_buffering_enabled',
'openresty_proxy_buffering_enabled',
'openresty_proxy_buffers',
'openresty_proxy_buffer_size',
'openresty_proxy_busy_buffers_size',
'openresty_gzip_enabled',
'openresty_gzip_min_length',
'openresty_gzip_comp_level',
'openresty_cache_enabled',
'openresty_cache_path',
'openresty_cache_levels',
'openresty_cache_inactive',
'openresty_cache_max_size',
'openresty_cache_key_template',
'openresty_cache_lock_enabled',
'openresty_cache_lock_timeout',
'openresty_cache_use_stale',
'openresty_main_config_template'
);
@@ -0,0 +1,10 @@
-- +goose Up
-- of_options 配置已于 202606220004 迁移至 w_system_configs,删除遗留表。
DROP TABLE IF EXISTS of_options;
-- +goose Down
-- 回滚时重建空表结构(数据无法恢复,迁移来源已为 w_system_configs)。
CREATE TABLE IF NOT EXISTS of_options (
key TEXT PRIMARY KEY,
value TEXT NOT NULL DEFAULT ''
);
+36
View File
@@ -7,7 +7,9 @@ package migrator
import (
"context"
"database/sql"
"embed"
"fmt"
"log"
"github.com/Rain-kl/Wavelet/internal/config"
@@ -79,6 +81,9 @@ func Migrate() {
if err := goose.SetDialect(gooseDialect()); err != nil {
log.Fatalf("[%s] set goose dialect failed: %v\n", dbType(), err)
}
if err := resyncGooseVersionSequence(sqlDB); err != nil {
log.Fatalf("[%s] resync goose_db_version sequence failed: %v\n", dbType(), err)
}
if err := goose.Up(sqlDB, migrationDir()); err != nil {
log.Fatalf("[%s] goose migrate failed: %v\n", dbType(), err)
}
@@ -88,6 +93,37 @@ func Migrate() {
log.Printf("[%s] goose migrate success\n", dbType())
}
// resyncGooseVersionSequence 修复 PostgreSQL 下 goose_db_version.id 自增序列落后于
// MAX(id) 的问题(常见于从 dump 恢复或历史迁移以显式 id 复制数据后)。序列落后会
// 导致 goose 记录新版本号时 INSERT 命中 goose_db_version_pkey 唯一约束冲突。
// 仅在表已存在且为 PostgreSQL 方言时执行;SQLite 使用 AUTOINCREMENT 不受影响。
func resyncGooseVersionSequence(sqlDB *sql.DB) error {
if gooseDialect() != dialectPostgres {
return nil
}
ctx := context.Background()
var exists bool
if err := sqlDB.QueryRowContext(ctx,
"SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema='public' AND table_name='goose_db_version')",
).Scan(&exists); err != nil {
return fmt.Errorf("check goose_db_version existence failed: %w", err)
}
if !exists {
return nil
}
const resyncSQL = `SELECT setval(
pg_get_serial_sequence('goose_db_version', 'id'),
GREATEST(COALESCE((SELECT MAX(id) FROM goose_db_version), 1), 1),
(SELECT MAX(id) IS NOT NULL FROM goose_db_version)
)`
if _, err := sqlDB.ExecContext(ctx, resyncSQL); err != nil {
return fmt.Errorf("setval goose_db_version sequence failed: %w", err)
}
return nil
}
func clearSystemConfigCache() {
if err := repository.InvalidateAllSystemConfigCaches(context.Background()); err != nil {
log.Printf("[%s] clear system config cache failed: %v\n", dbType(), err)
+3 -1
View File
@@ -18,7 +18,9 @@ import (
"gorm.io/gorm"
)
const expectedMigratedSystemConfigCount = 32
// expectedMigratedSystemConfigCount 包含初始 32 项系统配置,以及 202606220004
// 从 of_options 迁移过来的 48 项业务配置(OpenFlare/UptimeKuma/OpenResty)。
const expectedMigratedSystemConfigCount = 80
func TestMigrateInitializesSQLiteDatabase(t *testing.T) {
sqliteDB, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{