mirror of
https://github.com/tnb-labs/panel.git
synced 2026-10-13 08:59:07 +08:00
refactor: 把 context 打通到数据库、对象存储与容器 API
上一轮打通 shell 路径时留下三处接口本身不带 ctx,导致底下的 context.Background() 无法消除。这三处 contextcheck 都不报(接口方法没有 ctx 形参,静态分析认为合理),属于 lint 发现不了的死角: - pkg/db.Operator 的 17 个方法加 ctx,MySQL/Postgres/ClickHouse/SQLite/ MongoDB/Elasticsearch 实现同步改。其中 Elasticsearch 的 resty 请求原先 根本没挂 ctx,不只是传了 Background - pkg/storage.Storage 的 6 个方法加 ctx,local/s3/sftp/webdav 四个实现与 s3sdk 子包同步改;sftp 连接改用 net.Dialer.DialContext,连接阶段可取消 - internal/data/container*.go 的 moby client 调用,Container/Image/Network/ Volume 四个 Repo 共 26 个方法加 ctx 非测试代码的 context.Background() 从 71 处降到 14 处,剩下的是应用根 ctx、 有意的独立超时,以及几个瞬时本机操作的叶子函数。双平台 lint 保持 0 issues。 新增 23 处 context.WithoutCancel,其中两处的理由值得记: 备份上传断开取消链,是因为 ClearStorageExpired 按 mtime 保留最新 N 份, 上传被取消留下的截断文件会被当成最新的有效备份,把真正完好的旧备份挤出 保留窗口——静默的数据丢失。而 Put 失败路径没有任何远端清理逻辑,本地侧 反而有(任务队列独享 TMPDIR + defer RemoveAll),两边不对称。 Postgres.UserDrop 是 REASSIGN OWNED → DROP OWNED → DROP USER 三步,中途 取消会留下丢了所有权却没被删掉的用户;MySQL 权限变更后的 FLUSH 被跳过则 新授权根本不生效。 ImagePull 经核实不需要断开:moby 的 LayerDownloadManager 把未完成的层写在 临时文件里并在取消时删除,层只有完整校验后才注册进 layer store,取消不会 留下悬空层。 顺带删掉 8 处 //nolint:contextcheck,它们当初就是因为 Operator 接口没有 ctx 才挂上的。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+24
-22
@@ -233,16 +233,18 @@ func (s *App) SetRootPassword(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
oldRootPassword, _ := s.settingRepo.Get(biz.SettingKeyMySQLRootPassword)
|
||||
// 改密后还要写回面板设置,中途取消会让面板存的密码与实际不符
|
||||
ctx := context.WithoutCancel(r.Context())
|
||||
mysql, err := db.NewMySQL(r.Context(), "root", oldRootPassword, db.MySQLSocket(app.Root), "unix")
|
||||
if err != nil {
|
||||
// 尝试安全模式直接改密,中途取消会让面板存的密码与实际不符
|
||||
if err = db.MySQLResetRootPassword(context.WithoutCancel(r.Context()), req.Password, app.Root); err != nil {
|
||||
// 尝试安全模式直接改密
|
||||
if err = db.MySQLResetRootPassword(ctx, req.Password, app.Root); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
defer mysql.Close()
|
||||
if err = mysql.UserPassword("root", req.Password, "localhost"); err != nil {
|
||||
if err = mysql.UserPassword(ctx, "root", req.Password, "localhost"); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -365,7 +367,7 @@ func (s *App) ProcessList(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer mysql.Close()
|
||||
|
||||
rows, err := mysql.Query(`
|
||||
rows, err := mysql.Query(r.Context(), `
|
||||
SELECT ID, coalesce(USER,''), coalesce(HOST,''), coalesce(DB,''), coalesce(COMMAND,''),
|
||||
TIME, coalesce(STATE,''), coalesce(INFO,'')
|
||||
FROM information_schema.PROCESSLIST WHERE ID != CONNECTION_ID() ORDER BY TIME DESC`)
|
||||
@@ -408,7 +410,7 @@ func (s *App) KillProcess(w http.ResponseWriter, r *http.Request) {
|
||||
defer mysql.Close()
|
||||
|
||||
// KILL 不支持预编译参数,id 已校验为正整数
|
||||
if _, err = mysql.Exec(fmt.Sprintf(`KILL %d`, id)); err != nil {
|
||||
if _, err = mysql.Exec(r.Context(), fmt.Sprintf(`KILL %d`, id)); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -425,7 +427,7 @@ func (s *App) TransactionList(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer mysql.Close()
|
||||
|
||||
rows, err := mysql.Query(`
|
||||
rows, err := mysql.Query(r.Context(), `
|
||||
SELECT trx_id, trx_mysql_thread_id, coalesce(trx_state,''), coalesce(trx_query,''),
|
||||
timestampdiff(SECOND, trx_started, now()), trx_rows_locked, trx_rows_modified
|
||||
FROM information_schema.INNODB_TRX ORDER BY trx_started`)
|
||||
@@ -455,14 +457,14 @@ func (s *App) TransactionList(w http.ResponseWriter, r *http.Request) {
|
||||
FROM performance_schema.data_lock_waits w
|
||||
JOIN information_schema.innodb_trx r ON r.trx_id = w.REQUESTING_ENGINE_TRANSACTION_ID
|
||||
JOIN information_schema.innodb_trx b ON b.trx_id = w.BLOCKING_ENGINE_TRANSACTION_ID`
|
||||
if s.isMariaDB(mysql) {
|
||||
if s.isMariaDB(r.Context(), mysql) {
|
||||
lockSQL = `
|
||||
SELECT r.trx_mysql_thread_id, coalesce(r.trx_query,''), b.trx_mysql_thread_id, coalesce(b.trx_query,'')
|
||||
FROM information_schema.INNODB_LOCK_WAITS w
|
||||
JOIN information_schema.INNODB_TRX r ON r.trx_id = w.requesting_trx_id
|
||||
JOIN information_schema.INNODB_TRX b ON b.trx_id = w.blocking_trx_id`
|
||||
}
|
||||
if lockRows, lockErr := mysql.Query(lockSQL); lockErr == nil {
|
||||
if lockRows, lockErr := mysql.Query(r.Context(), lockSQL); lockErr == nil {
|
||||
defer func() { _ = lockRows.Close() }()
|
||||
for lockRows.Next() {
|
||||
var item LockWait
|
||||
@@ -490,7 +492,7 @@ func (s *App) TopSQL(w http.ResponseWriter, r *http.Request) {
|
||||
defer mysql.Close()
|
||||
|
||||
var enabled int
|
||||
if err = mysql.QueryRow(`SELECT @@performance_schema`).Scan(&enabled); err != nil {
|
||||
if err = mysql.QueryRow(r.Context(), `SELECT @@performance_schema`).Scan(&enabled); err != nil {
|
||||
if strings.Contains(err.Error(), "Unknown system variable") {
|
||||
service.Success(w, TopSQL{Supported: false, Items: []TopSQLItem{}})
|
||||
return
|
||||
@@ -506,7 +508,7 @@ func (s *App) TopSQL(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
rows, err := mysql.Query(`
|
||||
rows, err := mysql.Query(r.Context(), `
|
||||
SELECT coalesce(SCHEMA_NAME,''), COUNT_STAR, SUM_TIMER_WAIT DIV 1000000000,
|
||||
round(AVG_TIMER_WAIT/1e9,2), SUM_ROWS_SENT, SUM_ROWS_EXAMINED, coalesce(DIGEST_TEXT,'')
|
||||
FROM performance_schema.events_statements_summary_by_digest
|
||||
@@ -544,7 +546,7 @@ func (s *App) EnableTopSQL(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer mysql.Close()
|
||||
var enabled int
|
||||
if err = mysql.QueryRow(`SELECT @@performance_schema`).Scan(&enabled); err != nil {
|
||||
if err = mysql.QueryRow(r.Context(), `SELECT @@performance_schema`).Scan(&enabled); err != nil {
|
||||
service.Error(w, http.StatusUnprocessableEntity, s.t.Get("performance_schema is not supported by this instance"))
|
||||
return
|
||||
}
|
||||
@@ -575,7 +577,7 @@ func (s *App) ResetTopSQL(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer mysql.Close()
|
||||
|
||||
if _, err = mysql.Exec(`TRUNCATE TABLE performance_schema.events_statements_summary_by_digest`); err != nil {
|
||||
if _, err = mysql.Exec(r.Context(), `TRUNCATE TABLE performance_schema.events_statements_summary_by_digest`); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -592,7 +594,7 @@ func (s *App) DatabaseList(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer mysql.Close()
|
||||
|
||||
rows, err := mysql.Query(`
|
||||
rows, err := mysql.Query(r.Context(), `
|
||||
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA
|
||||
WHERE SCHEMA_NAME NOT IN ('mysql','information_schema','performance_schema','sys')
|
||||
ORDER BY SCHEMA_NAME`)
|
||||
@@ -646,7 +648,7 @@ func (s *App) TableList(w http.ResponseWriter, r *http.Request) {
|
||||
args = append(args, req.Database)
|
||||
}
|
||||
query += ` ORDER BY data_length + index_length DESC LIMIT 50`
|
||||
rows, err := mysql.Query(query, args...)
|
||||
rows, err := mysql.Query(r.Context(), query, args...)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -729,7 +731,7 @@ func (s *App) BinlogList(w http.ResponseWriter, r *http.Request) {
|
||||
defer mysql.Close()
|
||||
|
||||
var enabled int
|
||||
if err = mysql.QueryRow(`SELECT @@log_bin`).Scan(&enabled); err != nil {
|
||||
if err = mysql.QueryRow(r.Context(), `SELECT @@log_bin`).Scan(&enabled); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -738,7 +740,7 @@ func (s *App) BinlogList(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
rows, err := mysql.Query(`SHOW BINARY LOGS`)
|
||||
rows, err := mysql.Query(r.Context(), `SHOW BINARY LOGS`)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -778,7 +780,7 @@ func (s *App) PurgeBinlog(w http.ResponseWriter, r *http.Request) {
|
||||
defer mysql.Close()
|
||||
|
||||
// 校验文件名存在于 binlog 列表,PURGE 不支持预编译参数
|
||||
rows, err := mysql.Query(`SHOW BINARY LOGS`)
|
||||
rows, err := mysql.Query(r.Context(), `SHOW BINARY LOGS`)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -793,7 +795,7 @@ func (s *App) PurgeBinlog(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = mysql.Exec(fmt.Sprintf(`PURGE BINARY LOGS TO '%s'`, req.File)); err != nil {
|
||||
if _, err = mysql.Exec(r.Context(), fmt.Sprintf(`PURGE BINARY LOGS TO '%s'`, req.File)); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -810,10 +812,10 @@ func (s *App) ReplicationStatus(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer mysql.Close()
|
||||
|
||||
rows, err := mysql.Query(`SHOW REPLICA STATUS`)
|
||||
rows, err := mysql.Query(r.Context(), `SHOW REPLICA STATUS`)
|
||||
if err != nil {
|
||||
// 老版本 fallback
|
||||
if rows, err = mysql.Query(`SHOW SLAVE STATUS`); err != nil {
|
||||
if rows, err = mysql.Query(r.Context(), `SHOW SLAVE STATUS`); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -859,9 +861,9 @@ func (s *App) connect(ctx context.Context) (db.Operator, error) {
|
||||
}
|
||||
|
||||
// isMariaDB 判断当前实例是否为 MariaDB
|
||||
func (s *App) isMariaDB(op db.Operator) bool {
|
||||
func (s *App) isMariaDB(ctx context.Context, op db.Operator) bool {
|
||||
var version string
|
||||
if err := op.QueryRow(`SELECT VERSION()`).Scan(&version); err != nil {
|
||||
if err := op.QueryRow(ctx, `SELECT VERSION()`).Scan(&version); err != nil {
|
||||
return false
|
||||
}
|
||||
return strings.Contains(strings.ToLower(version), "mariadb")
|
||||
|
||||
@@ -234,16 +234,18 @@ func (s *App) SetPostgresPassword(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
oldPassword, _ := s.settingRepo.Get(biz.SettingKeyPostgresPassword)
|
||||
port := db.PostgresPort(app.Root)
|
||||
// 改完密码还要存进面板库,中途取消会让两边密码对不上
|
||||
ctx := context.WithoutCancel(r.Context())
|
||||
postgres, err := db.NewPostgres(r.Context(), "postgres", oldPassword, "127.0.0.1", port)
|
||||
if err != nil {
|
||||
// 直接修改密码,改完还要存进面板库,中途取消会让两边密码对不上
|
||||
if _, err = shell.Execf(context.WithoutCancel(r.Context()), `su - postgres -c "psql -p %d -c \"ALTER USER postgres WITH PASSWORD '%s';\""`, port, req.Password); err != nil {
|
||||
// 回退到直接修改密码
|
||||
if _, err = shell.Execf(ctx, `su - postgres -c "psql -p %d -c \"ALTER USER postgres WITH PASSWORD '%s';\""`, port, req.Password); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to set postgres password: %v", err))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
defer postgres.Close()
|
||||
if err = postgres.UserPassword("postgres", req.Password); err != nil {
|
||||
if err = postgres.UserPassword(ctx, "postgres", req.Password); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to set postgres password: %v", err))
|
||||
return
|
||||
}
|
||||
@@ -453,7 +455,7 @@ func (s *App) EnableExtension(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer postgres.Close()
|
||||
|
||||
if _, err = postgres.Exec(fmt.Sprintf(`CREATE EXTENSION IF NOT EXISTS "%s"`, ext.ExtName)); err != nil {
|
||||
if _, err = postgres.Exec(r.Context(), fmt.Sprintf(`CREATE EXTENSION IF NOT EXISTS "%s"`, ext.ExtName)); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to enable extension: %v", err))
|
||||
return
|
||||
}
|
||||
@@ -470,7 +472,7 @@ func (s *App) SessionList(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer postgres.Close()
|
||||
|
||||
rows, err := postgres.Query(`
|
||||
rows, err := postgres.Query(r.Context(), `
|
||||
SELECT a.pid, coalesce(a.datname,''), coalesce(a.usename,''), coalesce(a.client_addr::text,''),
|
||||
coalesce(a.state,''), coalesce(a.wait_event_type,''), coalesce(a.wait_event,''),
|
||||
coalesce(array_to_string(pg_blocking_pids(a.pid),','),''),
|
||||
@@ -519,7 +521,7 @@ func (s *App) TerminateSession(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer postgres.Close()
|
||||
|
||||
if _, err = postgres.Exec(`SELECT pg_terminate_backend($1)`, pid); err != nil {
|
||||
if _, err = postgres.Exec(r.Context(), `SELECT pg_terminate_backend($1)`, pid); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -536,7 +538,7 @@ func (s *App) TopSQL(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer postgres.Close()
|
||||
|
||||
rows, err := postgres.Query(`
|
||||
rows, err := postgres.Query(r.Context(), `
|
||||
SELECT coalesce(d.datname,''), s.calls, round(s.total_exec_time)::bigint,
|
||||
round(s.mean_exec_time::numeric,2)::float8, s.rows,
|
||||
coalesce(round(100.0*s.shared_blks_hit/nullif(s.shared_blks_hit+s.shared_blks_read,0),1),0)::float8,
|
||||
@@ -606,7 +608,7 @@ func (s *App) EnableTopSQL(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer postgres.Close()
|
||||
|
||||
if _, err = postgres.Exec(`CREATE EXTENSION IF NOT EXISTS pg_stat_statements`); err != nil {
|
||||
if _, err = postgres.Exec(r.Context(), `CREATE EXTENSION IF NOT EXISTS pg_stat_statements`); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -623,7 +625,7 @@ func (s *App) ResetTopSQL(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer postgres.Close()
|
||||
|
||||
if _, err = postgres.Exec(`SELECT pg_stat_statements_reset()`); err != nil {
|
||||
if _, err = postgres.Exec(r.Context(), `SELECT pg_stat_statements_reset()`); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -640,7 +642,7 @@ func (s *App) DatabaseList(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer postgres.Close()
|
||||
|
||||
rows, err := postgres.Query(`SELECT datname FROM pg_database WHERE datallowconn ORDER BY datname`)
|
||||
rows, err := postgres.Query(r.Context(), `SELECT datname FROM pg_database WHERE datallowconn ORDER BY datname`)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -679,7 +681,7 @@ func (s *App) BloatList(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer postgres.Close()
|
||||
|
||||
rows, err := postgres.Query(`
|
||||
rows, err := postgres.Query(r.Context(), `
|
||||
SELECT schemaname, relname, pg_size_pretty(pg_total_relation_size(relid)),
|
||||
pg_total_relation_size(relid), n_live_tup, n_dead_tup,
|
||||
coalesce(round(100.0*n_dead_tup/nullif(n_live_tup+n_dead_tup,0),1),0)::float8,
|
||||
@@ -773,17 +775,17 @@ func (s *App) WalStatus(w http.ResponseWriter, r *http.Request) {
|
||||
defer postgres.Close()
|
||||
|
||||
var wal Wal
|
||||
if err = postgres.QueryRow(`SELECT pg_size_pretty(coalesce(sum(size),0)) FROM pg_ls_waldir()`).Scan(&wal.WalSize); err != nil {
|
||||
if err = postgres.QueryRow(r.Context(), `SELECT pg_size_pretty(coalesce(sum(size),0)) FROM pg_ls_waldir()`).Scan(&wal.WalSize); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
if err = postgres.QueryRow(`SELECT archived_count, failed_count, coalesce(last_archived_wal,''), coalesce(last_failed_wal,'') FROM pg_stat_archiver`).Scan(
|
||||
if err = postgres.QueryRow(r.Context(), `SELECT archived_count, failed_count, coalesce(last_archived_wal,''), coalesce(last_failed_wal,'') FROM pg_stat_archiver`).Scan(
|
||||
&wal.Archiver.ArchivedCount, &wal.Archiver.FailedCount, &wal.Archiver.LastArchivedWal, &wal.Archiver.LastFailedWal); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
slotRows, err := postgres.Query(`SELECT slot_name, slot_type, active, coalesce(pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)),'') FROM pg_replication_slots`)
|
||||
slotRows, err := postgres.Query(r.Context(), `SELECT slot_name, slot_type, active, coalesce(pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)),'') FROM pg_replication_slots`)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -803,7 +805,7 @@ func (s *App) WalStatus(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
replRows, err := postgres.Query(`SELECT coalesce(client_addr::text,''), coalesce(state,''), coalesce(sync_state,''), coalesce(pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)),'') FROM pg_stat_replication`)
|
||||
replRows, err := postgres.Query(r.Context(), `SELECT coalesce(client_addr::text,''), coalesce(state,''), coalesce(sync_state,''), coalesce(pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)),'') FROM pg_stat_replication`)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -841,7 +843,7 @@ func (s *App) DropReplicationSlot(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer postgres.Close()
|
||||
|
||||
if _, err = postgres.Exec(`SELECT pg_drop_replication_slot($1)`, slot); err != nil {
|
||||
if _, err = postgres.Exec(r.Context(), `SELECT pg_drop_replication_slot($1)`, slot); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -488,7 +488,7 @@ func (uc *AlertUsecase) collect(ctx context.Context, rule *AlertRule, info types
|
||||
}), nil
|
||||
|
||||
case AlertTypeContainer:
|
||||
containers, err := uc.container.ListAll(containerSock(uc.setting))
|
||||
containers, err := uc.container.ListAll(ctx, containerSock(uc.setting))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -31,9 +31,9 @@ type BackupRepo interface {
|
||||
Delete(ctx context.Context, typ BackupType, name string) error
|
||||
Restore(ctx context.Context, typ BackupType, backup, target string) error
|
||||
ClearExpired(path, prefix string, save uint) error
|
||||
ClearStorageExpired(account uint, dir, prefix string, save uint) error
|
||||
ClearStorageExpired(ctx context.Context, account uint, dir, prefix string, save uint) error
|
||||
CutoffLog(ctx context.Context, path, target string) (string, error)
|
||||
CutoffUpload(account uint, typ BackupType, name string, files []string) error
|
||||
CutoffUpload(ctx context.Context, account uint, typ BackupType, name string, files []string) error
|
||||
GetDefaultPath(typ BackupType) string
|
||||
FixPanel(ctx context.Context) error
|
||||
UpdatePanel(ctx context.Context, version, url, checksum string, progress func(string)) error
|
||||
@@ -113,16 +113,16 @@ func (uc *BackupUsecase) ClearExpired(path, prefix string, save uint) error {
|
||||
return uc.repo.ClearExpired(path, prefix, save)
|
||||
}
|
||||
|
||||
func (uc *BackupUsecase) ClearStorageExpired(account uint, dir, prefix string, save uint) error {
|
||||
return uc.repo.ClearStorageExpired(account, dir, prefix, save)
|
||||
func (uc *BackupUsecase) ClearStorageExpired(ctx context.Context, account uint, dir, prefix string, save uint) error {
|
||||
return uc.repo.ClearStorageExpired(ctx, account, dir, prefix, save)
|
||||
}
|
||||
|
||||
func (uc *BackupUsecase) CutoffLog(ctx context.Context, path, target string) (string, error) {
|
||||
return uc.repo.CutoffLog(ctx, path, target)
|
||||
}
|
||||
|
||||
func (uc *BackupUsecase) CutoffUpload(account uint, typ BackupType, name string, files []string) error {
|
||||
return uc.repo.CutoffUpload(account, typ, name, files)
|
||||
func (uc *BackupUsecase) CutoffUpload(ctx context.Context, account uint, typ BackupType, name string, files []string) error {
|
||||
return uc.repo.CutoffUpload(ctx, account, typ, name, files)
|
||||
}
|
||||
|
||||
func (uc *BackupUsecase) GetDefaultPath(typ BackupType) string {
|
||||
|
||||
+45
-44
@@ -1,6 +1,7 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
@@ -12,19 +13,19 @@ import (
|
||||
)
|
||||
|
||||
type ContainerRepo interface {
|
||||
ListAll(sock string) ([]types.Container, error)
|
||||
Inspect(sock string, id string) (any, error)
|
||||
Create(sock string, req *request.ContainerCreate) (string, error)
|
||||
Remove(sock string, id string) error
|
||||
Start(sock string, id string) error
|
||||
Stop(sock string, id string) error
|
||||
Restart(sock string, id string) error
|
||||
Pause(sock string, id string) error
|
||||
Unpause(sock string, id string) error
|
||||
Kill(sock string, id string) error
|
||||
Rename(sock string, id string, newName string) error
|
||||
Logs(sock string, id string, tail int) (string, error)
|
||||
Prune(sock string) error
|
||||
ListAll(ctx context.Context, sock string) ([]types.Container, error)
|
||||
Inspect(ctx context.Context, sock string, id string) (any, error)
|
||||
Create(ctx context.Context, sock string, req *request.ContainerCreate) (string, error)
|
||||
Remove(ctx context.Context, sock string, id string) error
|
||||
Start(ctx context.Context, sock string, id string) error
|
||||
Stop(ctx context.Context, sock string, id string) error
|
||||
Restart(ctx context.Context, sock string, id string) error
|
||||
Pause(ctx context.Context, sock string, id string) error
|
||||
Unpause(ctx context.Context, sock string, id string) error
|
||||
Kill(ctx context.Context, sock string, id string) error
|
||||
Rename(ctx context.Context, sock string, id string, newName string) error
|
||||
Logs(ctx context.Context, sock string, id string, tail int) (string, error)
|
||||
Prune(ctx context.Context, sock string) error
|
||||
}
|
||||
|
||||
type ContainerUsecase struct {
|
||||
@@ -43,14 +44,14 @@ func NewContainerUsecase(t *gotext.Locale, containerRepo ContainerRepo, settingR
|
||||
}
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) ListAll() ([]types.Container, error) {
|
||||
func (uc *ContainerUsecase) ListAll(ctx context.Context) ([]types.Container, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.ListAll(sock)
|
||||
return uc.repo.ListAll(ctx, sock)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) ListByName(name string) ([]types.Container, error) {
|
||||
func (uc *ContainerUsecase) ListByName(ctx context.Context, name string) ([]types.Container, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
containers, err := uc.repo.ListAll(sock)
|
||||
containers, err := uc.repo.ListAll(ctx, sock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -62,14 +63,14 @@ func (uc *ContainerUsecase) ListByName(name string) ([]types.Container, error) {
|
||||
return containers, nil
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Inspect(id string) (any, error) {
|
||||
func (uc *ContainerUsecase) Inspect(ctx context.Context, id string) (any, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Inspect(sock, id)
|
||||
return uc.repo.Inspect(ctx, sock, id)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Create(req *request.ContainerCreate) (string, error) {
|
||||
func (uc *ContainerUsecase) Create(ctx context.Context, req *request.ContainerCreate) (string, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Create(sock, req)
|
||||
return uc.repo.Create(ctx, sock, req)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) CreateBackground(req *request.ContainerCreate) error {
|
||||
@@ -96,12 +97,12 @@ func (uc *ContainerUsecase) CreateBackground(req *request.ContainerCreate) error
|
||||
}
|
||||
|
||||
// Update 删除旧容器后按新配置重建同名容器
|
||||
func (uc *ContainerUsecase) Update(id string, req *request.ContainerCreate) (string, error) {
|
||||
func (uc *ContainerUsecase) Update(ctx context.Context, id string, req *request.ContainerCreate) (string, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
if err := uc.repo.Remove(sock, id); err != nil {
|
||||
if err := uc.repo.Remove(ctx, sock, id); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return uc.repo.Create(sock, req)
|
||||
return uc.repo.Create(ctx, sock, req)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) UpdateBackground(id string, req *request.ContainerCreate) error {
|
||||
@@ -131,52 +132,52 @@ func (uc *ContainerUsecase) UpdateBackground(id string, req *request.ContainerCr
|
||||
return uc.task.Push(task)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Remove(id string) error {
|
||||
func (uc *ContainerUsecase) Remove(ctx context.Context, id string) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Remove(sock, id)
|
||||
return uc.repo.Remove(ctx, sock, id)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Start(id string) error {
|
||||
func (uc *ContainerUsecase) Start(ctx context.Context, id string) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Start(sock, id)
|
||||
return uc.repo.Start(ctx, sock, id)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Stop(id string) error {
|
||||
func (uc *ContainerUsecase) Stop(ctx context.Context, id string) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Stop(sock, id)
|
||||
return uc.repo.Stop(ctx, sock, id)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Restart(id string) error {
|
||||
func (uc *ContainerUsecase) Restart(ctx context.Context, id string) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Restart(sock, id)
|
||||
return uc.repo.Restart(ctx, sock, id)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Pause(id string) error {
|
||||
func (uc *ContainerUsecase) Pause(ctx context.Context, id string) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Pause(sock, id)
|
||||
return uc.repo.Pause(ctx, sock, id)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Unpause(id string) error {
|
||||
func (uc *ContainerUsecase) Unpause(ctx context.Context, id string) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Unpause(sock, id)
|
||||
return uc.repo.Unpause(ctx, sock, id)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Kill(id string) error {
|
||||
func (uc *ContainerUsecase) Kill(ctx context.Context, id string) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Kill(sock, id)
|
||||
return uc.repo.Kill(ctx, sock, id)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Rename(id string, newName string) error {
|
||||
func (uc *ContainerUsecase) Rename(ctx context.Context, id string, newName string) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Rename(sock, id, newName)
|
||||
return uc.repo.Rename(ctx, sock, id, newName)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Logs(id string, tail int) (string, error) {
|
||||
func (uc *ContainerUsecase) Logs(ctx context.Context, id string, tail int) (string, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Logs(sock, id, tail)
|
||||
return uc.repo.Logs(ctx, sock, id, tail)
|
||||
}
|
||||
|
||||
func (uc *ContainerUsecase) Prune() error {
|
||||
func (uc *ContainerUsecase) Prune(ctx context.Context) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Prune(sock)
|
||||
return uc.repo.Prune(ctx, sock)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/leonelquinteros/gotext"
|
||||
|
||||
"github.com/acepanel/panel/v3/internal/request"
|
||||
@@ -9,11 +11,11 @@ import (
|
||||
)
|
||||
|
||||
type ContainerImageRepo interface {
|
||||
List(sock string) ([]types.ContainerImage, error)
|
||||
Exist(sock string, name string) (bool, error)
|
||||
Pull(sock string, req *request.ContainerImagePull) error
|
||||
Remove(sock string, id string) error
|
||||
Prune(sock string) error
|
||||
List(ctx context.Context, sock string) ([]types.ContainerImage, error)
|
||||
Exist(ctx context.Context, sock string, name string) (bool, error)
|
||||
Pull(ctx context.Context, sock string, req *request.ContainerImagePull) error
|
||||
Remove(ctx context.Context, sock string, id string) error
|
||||
Prune(ctx context.Context, sock string) error
|
||||
}
|
||||
|
||||
type ContainerImageUsecase struct {
|
||||
@@ -32,19 +34,19 @@ func NewContainerImageUsecase(t *gotext.Locale, containerImageRepo ContainerImag
|
||||
}
|
||||
}
|
||||
|
||||
func (uc *ContainerImageUsecase) List() ([]types.ContainerImage, error) {
|
||||
func (uc *ContainerImageUsecase) List(ctx context.Context) ([]types.ContainerImage, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.List(sock)
|
||||
return uc.repo.List(ctx, sock)
|
||||
}
|
||||
|
||||
func (uc *ContainerImageUsecase) Exist(name string) (bool, error) {
|
||||
func (uc *ContainerImageUsecase) Exist(ctx context.Context, name string) (bool, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Exist(sock, name)
|
||||
return uc.repo.Exist(ctx, sock, name)
|
||||
}
|
||||
|
||||
func (uc *ContainerImageUsecase) Pull(req *request.ContainerImagePull) error {
|
||||
func (uc *ContainerImageUsecase) Pull(ctx context.Context, req *request.ContainerImagePull) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Pull(sock, req)
|
||||
return uc.repo.Pull(ctx, sock, req)
|
||||
}
|
||||
|
||||
func (uc *ContainerImageUsecase) PullBackground(req *request.ContainerImagePull) error {
|
||||
@@ -63,12 +65,12 @@ func (uc *ContainerImageUsecase) PullBackground(req *request.ContainerImagePull)
|
||||
return uc.task.Push(task)
|
||||
}
|
||||
|
||||
func (uc *ContainerImageUsecase) Remove(id string) error {
|
||||
func (uc *ContainerImageUsecase) Remove(ctx context.Context, id string) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Remove(sock, id)
|
||||
return uc.repo.Remove(ctx, sock, id)
|
||||
}
|
||||
|
||||
func (uc *ContainerImageUsecase) Prune() error {
|
||||
func (uc *ContainerImageUsecase) Prune(ctx context.Context) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Prune(sock)
|
||||
return uc.repo.Prune(ctx, sock)
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/acepanel/panel/v3/internal/request"
|
||||
"github.com/acepanel/panel/v3/pkg/types"
|
||||
)
|
||||
|
||||
type ContainerNetworkRepo interface {
|
||||
List(sock string) ([]types.ContainerNetwork, error)
|
||||
Create(sock string, req *request.ContainerNetworkCreate) (string, error)
|
||||
Remove(sock string, id string) error
|
||||
Prune(sock string) error
|
||||
List(ctx context.Context, sock string) ([]types.ContainerNetwork, error)
|
||||
Create(ctx context.Context, sock string, req *request.ContainerNetworkCreate) (string, error)
|
||||
Remove(ctx context.Context, sock string, id string) error
|
||||
Prune(ctx context.Context, sock string) error
|
||||
}
|
||||
|
||||
type ContainerNetworkUsecase struct {
|
||||
@@ -21,22 +23,22 @@ func NewContainerNetworkUsecase(repo ContainerNetworkRepo, setting SettingRepo)
|
||||
return &ContainerNetworkUsecase{repo: repo, setting: setting}
|
||||
}
|
||||
|
||||
func (uc *ContainerNetworkUsecase) List() ([]types.ContainerNetwork, error) {
|
||||
func (uc *ContainerNetworkUsecase) List(ctx context.Context) ([]types.ContainerNetwork, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.List(sock)
|
||||
return uc.repo.List(ctx, sock)
|
||||
}
|
||||
|
||||
func (uc *ContainerNetworkUsecase) Create(req *request.ContainerNetworkCreate) (string, error) {
|
||||
func (uc *ContainerNetworkUsecase) Create(ctx context.Context, req *request.ContainerNetworkCreate) (string, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Create(sock, req)
|
||||
return uc.repo.Create(ctx, sock, req)
|
||||
}
|
||||
|
||||
func (uc *ContainerNetworkUsecase) Remove(id string) error {
|
||||
func (uc *ContainerNetworkUsecase) Remove(ctx context.Context, id string) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Remove(sock, id)
|
||||
return uc.repo.Remove(ctx, sock, id)
|
||||
}
|
||||
|
||||
func (uc *ContainerNetworkUsecase) Prune() error {
|
||||
func (uc *ContainerNetworkUsecase) Prune(ctx context.Context) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Prune(sock)
|
||||
return uc.repo.Prune(ctx, sock)
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/acepanel/panel/v3/internal/request"
|
||||
"github.com/acepanel/panel/v3/pkg/types"
|
||||
)
|
||||
|
||||
type ContainerVolumeRepo interface {
|
||||
List(sock string) ([]types.ContainerVolume, error)
|
||||
Create(sock string, req *request.ContainerVolumeCreate) (string, error)
|
||||
Remove(sock string, id string) error
|
||||
Prune(sock string) error
|
||||
List(ctx context.Context, sock string) ([]types.ContainerVolume, error)
|
||||
Create(ctx context.Context, sock string, req *request.ContainerVolumeCreate) (string, error)
|
||||
Remove(ctx context.Context, sock string, id string) error
|
||||
Prune(ctx context.Context, sock string) error
|
||||
}
|
||||
|
||||
type ContainerVolumeUsecase struct {
|
||||
@@ -21,22 +23,22 @@ func NewContainerVolumeUsecase(repo ContainerVolumeRepo, setting SettingRepo) *C
|
||||
return &ContainerVolumeUsecase{repo: repo, setting: setting}
|
||||
}
|
||||
|
||||
func (uc *ContainerVolumeUsecase) List() ([]types.ContainerVolume, error) {
|
||||
func (uc *ContainerVolumeUsecase) List(ctx context.Context) ([]types.ContainerVolume, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.List(sock)
|
||||
return uc.repo.List(ctx, sock)
|
||||
}
|
||||
|
||||
func (uc *ContainerVolumeUsecase) Create(req *request.ContainerVolumeCreate) (string, error) {
|
||||
func (uc *ContainerVolumeUsecase) Create(ctx context.Context, req *request.ContainerVolumeCreate) (string, error) {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Create(sock, req)
|
||||
return uc.repo.Create(ctx, sock, req)
|
||||
}
|
||||
|
||||
func (uc *ContainerVolumeUsecase) Remove(id string) error {
|
||||
func (uc *ContainerVolumeUsecase) Remove(ctx context.Context, id string) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Remove(sock, id)
|
||||
return uc.repo.Remove(ctx, sock, id)
|
||||
}
|
||||
|
||||
func (uc *ContainerVolumeUsecase) Prune() error {
|
||||
func (uc *ContainerVolumeUsecase) Prune(ctx context.Context) error {
|
||||
sock := containerSock(uc.setting)
|
||||
return uc.repo.Prune(sock)
|
||||
return uc.repo.Prune(ctx, sock)
|
||||
}
|
||||
|
||||
+17
-14
@@ -93,7 +93,7 @@ func (uc *DatabaseUsecase) Create(ctx context.Context, req *request.DatabaseCrea
|
||||
return mongoErr
|
||||
}
|
||||
defer mongo.Close()
|
||||
if mongoErr = mongo.DatabaseCreate(req.Name); mongoErr != nil { //nolint:contextcheck
|
||||
if mongoErr = mongo.DatabaseCreate(ctx, req.Name); mongoErr != nil {
|
||||
return mongoErr
|
||||
}
|
||||
uc.log.Info("database created", slog.String("type", OperationTypeDatabase), slog.Uint64("operator_id", operatorID(ctx)), slog.String("name", req.Name), slog.Uint64("server_id", uint64(req.ServerID)))
|
||||
@@ -106,6 +106,9 @@ func (uc *DatabaseUsecase) Create(ctx context.Context, req *request.DatabaseCrea
|
||||
}
|
||||
defer operator.Close()
|
||||
|
||||
// 建用户 → 建库 → 授权是一个整体,中途取消会留下空库或没有权限的用户
|
||||
ctx = context.WithoutCancel(ctx)
|
||||
|
||||
switch server.Type {
|
||||
case DatabaseTypeMysql:
|
||||
if req.CreateUser {
|
||||
@@ -118,19 +121,19 @@ func (uc *DatabaseUsecase) Create(ctx context.Context, req *request.DatabaseCrea
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err = operator.DatabaseCreate(req.Name); err != nil {
|
||||
if err = operator.DatabaseCreate(ctx, req.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
if req.Username != "" {
|
||||
// 授权已有用户时按其实际 host 授权,MySQL 8 起 GRANT 不再隐式创建用户
|
||||
hosts := []string{req.Host}
|
||||
if !req.CreateUser {
|
||||
if hosts = uc.mysqlUserHosts(operator, req.Username); len(hosts) == 0 {
|
||||
if hosts = uc.mysqlUserHosts(ctx, operator, req.Username); len(hosts) == 0 {
|
||||
return errors.New(uc.t.Get("database user %s does not exist", req.Username))
|
||||
}
|
||||
}
|
||||
for _, host := range hosts {
|
||||
if err = operator.PrivilegesGrant(req.Username, req.Name, host); err != nil {
|
||||
if err = operator.PrivilegesGrant(ctx, req.Username, req.Name, host); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -146,11 +149,11 @@ func (uc *DatabaseUsecase) Create(ctx context.Context, req *request.DatabaseCrea
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err = operator.DatabaseCreate(req.Name); err != nil {
|
||||
if err = operator.DatabaseCreate(ctx, req.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
if req.Username != "" {
|
||||
if err = operator.PrivilegesGrant(req.Username, req.Name); err != nil {
|
||||
if err = operator.PrivilegesGrant(ctx, req.Username, req.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -158,7 +161,7 @@ func (uc *DatabaseUsecase) Create(ctx context.Context, req *request.DatabaseCrea
|
||||
if !ok {
|
||||
return errors.New(uc.t.Get("%s does not support database comment", server.Type))
|
||||
}
|
||||
if err = pg.DatabaseComment(req.Name, req.Comment); err != nil { //nolint:contextcheck
|
||||
if err = pg.DatabaseComment(ctx, req.Name, req.Comment); err != nil {
|
||||
return err
|
||||
}
|
||||
case DatabaseTypeClickHouse:
|
||||
@@ -171,11 +174,11 @@ func (uc *DatabaseUsecase) Create(ctx context.Context, req *request.DatabaseCrea
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err = operator.DatabaseCreate(req.Name); err != nil {
|
||||
if err = operator.DatabaseCreate(ctx, req.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
if req.Username != "" {
|
||||
if err = operator.PrivilegesGrant(req.Username, req.Name); err != nil {
|
||||
if err = operator.PrivilegesGrant(ctx, req.Username, req.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -189,8 +192,8 @@ func (uc *DatabaseUsecase) Create(ctx context.Context, req *request.DatabaseCrea
|
||||
}
|
||||
|
||||
// mysqlUserHosts 查询 MySQL 用户实际存在的 host 列表
|
||||
func (uc *DatabaseUsecase) mysqlUserHosts(operator db.Operator, user string) []string {
|
||||
rows, err := operator.Query("SELECT host FROM mysql.user WHERE user = ?", user)
|
||||
func (uc *DatabaseUsecase) mysqlUserHosts(ctx context.Context, operator db.Operator, user string) []string {
|
||||
rows, err := operator.Query(ctx, "SELECT host FROM mysql.user WHERE user = ?", user)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@@ -219,7 +222,7 @@ func (uc *DatabaseUsecase) Delete(ctx context.Context, serverID uint, name strin
|
||||
return mongoErr
|
||||
}
|
||||
defer mongo.Close()
|
||||
if mongoErr = mongo.DatabaseDrop(name); mongoErr != nil { //nolint:contextcheck
|
||||
if mongoErr = mongo.DatabaseDrop(ctx, name); mongoErr != nil {
|
||||
return mongoErr
|
||||
}
|
||||
case DatabaseTypeSQLite:
|
||||
@@ -230,7 +233,7 @@ func (uc *DatabaseUsecase) Delete(ctx context.Context, serverID uint, name strin
|
||||
return opErr
|
||||
}
|
||||
defer operator.Close()
|
||||
if opErr = operator.DatabaseDrop(name); opErr != nil {
|
||||
if opErr = operator.DatabaseDrop(ctx, name); opErr != nil {
|
||||
return opErr
|
||||
}
|
||||
}
|
||||
@@ -258,7 +261,7 @@ func (uc *DatabaseUsecase) Comment(ctx context.Context, req *request.DatabaseCom
|
||||
if !ok {
|
||||
return errors.New(uc.t.Get("%s does not support database comment", server.Type))
|
||||
}
|
||||
return pg.DatabaseComment(req.Name, req.Comment) //nolint:contextcheck
|
||||
return pg.DatabaseComment(ctx, req.Name, req.Comment)
|
||||
default:
|
||||
return errors.New(uc.t.Get("%s does not support database comment", server.Type))
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ func (uc *DatabaseServerUsecase) Sync(ctx context.Context, id uint) error {
|
||||
|
||||
switch server.Type {
|
||||
case DatabaseTypeMysql:
|
||||
allUsers, err := operator.Users()
|
||||
allUsers, err := operator.Users(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -219,7 +219,7 @@ func (uc *DatabaseServerUsecase) Sync(ctx context.Context, id uint) error {
|
||||
}
|
||||
}
|
||||
case DatabaseTypePostgresql:
|
||||
allUsers, err := operator.Users()
|
||||
allUsers, err := operator.Users(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -238,7 +238,7 @@ func (uc *DatabaseServerUsecase) Sync(ctx context.Context, id uint) error {
|
||||
}
|
||||
}
|
||||
case DatabaseTypeClickHouse:
|
||||
allUsers, err := operator.Users()
|
||||
allUsers, err := operator.Users(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -116,17 +116,20 @@ func (uc *DatabaseUserUsecase) Create(ctx context.Context, req *request.Database
|
||||
}
|
||||
defer operator.Close()
|
||||
|
||||
// 建用户 → 建库 → 授权 → 落库是一个整体,中途取消会留下没有权限的用户
|
||||
ctx = context.WithoutCancel(ctx)
|
||||
|
||||
// 创建用户
|
||||
if err = operator.UserCreate(req.Username, req.Password, req.Host); err != nil {
|
||||
if err = operator.UserCreate(ctx, req.Username, req.Password, req.Host); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建数据库并授权
|
||||
for name := range slices.Values(req.Privileges) {
|
||||
if err = operator.DatabaseCreate(name); err != nil {
|
||||
if err = operator.DatabaseCreate(ctx, name); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = operator.PrivilegesGrant(req.Username, name, req.Host); err != nil {
|
||||
if err = operator.PrivilegesGrant(ctx, req.Username, name, req.Host); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -166,28 +169,31 @@ func (uc *DatabaseUserUsecase) Update(ctx context.Context, req *request.Database
|
||||
}
|
||||
defer operator.Close()
|
||||
|
||||
// 改密码 → 撤权 → 重新授权 → 落库是一个整体,中途取消会让面板记录与实际权限不一致
|
||||
ctx = context.WithoutCancel(ctx)
|
||||
|
||||
// 更新密码
|
||||
if req.Password != "" {
|
||||
if err = operator.UserPassword(user.Username, req.Password, user.Host); err != nil {
|
||||
if err = operator.UserPassword(ctx, user.Username, req.Password, user.Host); err != nil {
|
||||
return err
|
||||
}
|
||||
user.Password = req.Password
|
||||
}
|
||||
|
||||
// 撤销被移除的权限
|
||||
currentPrivileges, _ := operator.UserPrivileges(user.Username, user.Host)
|
||||
currentPrivileges, _ := operator.UserPrivileges(ctx, user.Username, user.Host)
|
||||
for name := range slices.Values(currentPrivileges) {
|
||||
if !slices.Contains(req.Privileges, name) {
|
||||
_ = operator.PrivilegesRevoke(user.Username, name, user.Host)
|
||||
_ = operator.PrivilegesRevoke(ctx, user.Username, name, user.Host)
|
||||
}
|
||||
}
|
||||
|
||||
// 创建数据库并授权
|
||||
for name := range slices.Values(req.Privileges) {
|
||||
if err = operator.DatabaseCreate(name); err != nil {
|
||||
if err = operator.DatabaseCreate(ctx, name); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = operator.PrivilegesGrant(user.Username, name, user.Host); err != nil {
|
||||
if err = operator.PrivilegesGrant(ctx, user.Username, name, user.Host); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -218,7 +224,8 @@ func (uc *DatabaseUserUsecase) Delete(ctx context.Context, id uint) error {
|
||||
}
|
||||
defer operator.Close()
|
||||
|
||||
_ = operator.UserDrop(user.Username, user.Host)
|
||||
// 取消会让面板记录已删而引擎里的用户残留
|
||||
_ = operator.UserDrop(context.WithoutCancel(ctx), user.Username, user.Host)
|
||||
|
||||
if err = uc.repo.DeleteByID(id); err != nil {
|
||||
return err
|
||||
@@ -242,6 +249,9 @@ func (uc *DatabaseUserUsecase) DeleteByNames(ctx context.Context, serverID uint,
|
||||
}
|
||||
defer operator.Close()
|
||||
|
||||
// 取消会让面板记录已删而引擎里的用户残留
|
||||
ctx = context.WithoutCancel(ctx)
|
||||
|
||||
switch server.Type {
|
||||
case DatabaseTypeMysql:
|
||||
users, err := uc.repo.ListByNames(serverID, names)
|
||||
@@ -256,11 +266,11 @@ func (uc *DatabaseUserUsecase) DeleteByNames(ctx context.Context, serverID uint,
|
||||
break
|
||||
}
|
||||
}
|
||||
_ = operator.UserDrop(name, host)
|
||||
_ = operator.UserDrop(ctx, name, host)
|
||||
}
|
||||
case DatabaseTypePostgresql, DatabaseTypeClickHouse:
|
||||
for name := range slices.Values(names) {
|
||||
_ = operator.UserDrop(name)
|
||||
_ = operator.UserDrop(ctx, name)
|
||||
}
|
||||
default:
|
||||
}
|
||||
|
||||
+25
-17
@@ -353,7 +353,7 @@ func (r *backupRepo) CutoffLog(ctx context.Context, path, target string) (string
|
||||
}
|
||||
|
||||
// CutoffUpload 将指定的切割日志文件上传到远程存储
|
||||
func (r *backupRepo) CutoffUpload(account uint, typ biz.BackupType, name string, files []string) error {
|
||||
func (r *backupRepo) CutoffUpload(ctx context.Context, account uint, typ biz.BackupType, name string, files []string) error {
|
||||
backupStorage, err := r.GetStorage(account)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -370,7 +370,7 @@ func (r *backupRepo) CutoffUpload(account uint, typ biz.BackupType, name string,
|
||||
return err
|
||||
}
|
||||
remotePath := filepath.Join("cutoff", string(typ), name, filepath.Base(localPath))
|
||||
if putErr := client.Put(remotePath, file); putErr != nil {
|
||||
if putErr := r.upload(ctx, client, remotePath, file); putErr != nil {
|
||||
_ = file.Close()
|
||||
return putErr
|
||||
}
|
||||
@@ -434,7 +434,7 @@ func (r *backupRepo) ClearExpired(path, prefix string, save uint) error {
|
||||
// dir 存储器内的目标目录,备份为 <类型>,切割日志为 cutoff/<类型>/<目标>
|
||||
// prefix 目标文件前缀
|
||||
// save 保存份数
|
||||
func (r *backupRepo) ClearStorageExpired(storage uint, dir, prefix string, save uint) error {
|
||||
func (r *backupRepo) ClearStorageExpired(ctx context.Context, storage uint, dir, prefix string, save uint) error {
|
||||
backupStorage, err := r.GetStorage(storage)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -445,7 +445,7 @@ func (r *backupRepo) ClearStorageExpired(storage uint, dir, prefix string, save
|
||||
return err
|
||||
}
|
||||
|
||||
files, err := client.List(dir)
|
||||
files, err := client.List(ctx, dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -457,7 +457,7 @@ func (r *backupRepo) ClearStorageExpired(storage uint, dir, prefix string, save
|
||||
var filtered []fileInfo
|
||||
for _, file := range files {
|
||||
if strings.HasPrefix(file, prefix) && r.isBackupArchive(file) {
|
||||
lastModified, modErr := client.LastModified(filepath.Join(dir, file))
|
||||
lastModified, modErr := client.LastModified(ctx, filepath.Join(dir, file))
|
||||
if modErr != nil {
|
||||
continue
|
||||
}
|
||||
@@ -480,13 +480,15 @@ func (r *backupRepo) ClearStorageExpired(storage uint, dir, prefix string, save
|
||||
}
|
||||
|
||||
// 切片保留 save 份,删除剩余
|
||||
// 已判定过期的文件删到一半就停会留下无人认领的残留,这段不可取消
|
||||
deleteCtx := context.WithoutCancel(ctx)
|
||||
toDelete := filtered[save:]
|
||||
for _, file := range toDelete {
|
||||
filePath := filepath.Join(dir, file.name)
|
||||
if app.IsCli {
|
||||
fmt.Println(r.t.Get("|-Cleaning expired file: %s", filePath))
|
||||
}
|
||||
if err = client.Delete(filePath); err != nil {
|
||||
if err = client.Delete(deleteCtx, filePath); err != nil {
|
||||
return errors.New(r.t.Get("Cleanup failed: %v", err))
|
||||
}
|
||||
}
|
||||
@@ -494,6 +496,12 @@ func (r *backupRepo) ClearStorageExpired(storage uint, dir, prefix string, save
|
||||
return nil
|
||||
}
|
||||
|
||||
// upload 上传备份文件到存储器
|
||||
// 上传中途取消会在远端留下截断的文件,而过期清理只按前缀和后缀识别备份,会把它当成有效备份计入保留份数
|
||||
func (r *backupRepo) upload(ctx context.Context, client storage.Storage, path string, content stdio.Reader) error {
|
||||
return client.Put(context.WithoutCancel(ctx), path, content)
|
||||
}
|
||||
|
||||
// getStorage 获取存储器
|
||||
func (r *backupRepo) getStorage(backupStorage biz.BackupStorage) (storage.Storage, error) {
|
||||
switch backupStorage.Type {
|
||||
@@ -562,7 +570,7 @@ func (r *backupRepo) createWebsite(ctx context.Context, name string, storage sto
|
||||
}
|
||||
defer func(file *os.File) { _ = file.Close() }(file)
|
||||
|
||||
if err = storage.Put(filepath.Join(string(biz.BackupTypeWebsite), name), file); err != nil {
|
||||
if err = r.upload(ctx, storage, filepath.Join(string(biz.BackupTypeWebsite), name), file); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -584,7 +592,7 @@ func (r *backupRepo) createMySQL(ctx context.Context, name string, storage stora
|
||||
return err
|
||||
}
|
||||
defer mysql.Close()
|
||||
if exist, _ := mysql.DatabaseExists(target); !exist {
|
||||
if exist, _ := mysql.DatabaseExists(ctx, target); !exist {
|
||||
return errors.New(r.t.Get("database does not exist: %s", target))
|
||||
}
|
||||
|
||||
@@ -602,7 +610,7 @@ func (r *backupRepo) createMySQL(ctx context.Context, name string, storage stora
|
||||
// 导出数据库
|
||||
var gtidMode string
|
||||
dumpArgs := "--single-transaction --quick --routines --events --max-allowed-packet=1G"
|
||||
if mysql.QueryRow(`SELECT @@gtid_mode`).Scan(>idMode) == nil {
|
||||
if mysql.QueryRow(ctx, `SELECT @@gtid_mode`).Scan(>idMode) == nil {
|
||||
dumpArgs += " --set-gtid-purged=OFF"
|
||||
}
|
||||
name += ".sql"
|
||||
@@ -629,7 +637,7 @@ func (r *backupRepo) createMySQL(ctx context.Context, name string, storage stora
|
||||
}
|
||||
defer func(file *os.File) { _ = file.Close() }(file)
|
||||
|
||||
if err = storage.Put(filepath.Join(string(biz.BackupTypeMySQL), name), file); err != nil {
|
||||
if err = r.upload(ctx, storage, filepath.Join(string(biz.BackupTypeMySQL), name), file); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -652,7 +660,7 @@ func (r *backupRepo) createPostgres(ctx context.Context, name string, storage st
|
||||
return err
|
||||
}
|
||||
defer postgres.Close()
|
||||
if exist, _ := postgres.DatabaseExists(target); !exist {
|
||||
if exist, _ := postgres.DatabaseExists(ctx, target); !exist {
|
||||
return errors.New(r.t.Get("database does not exist: %s", target))
|
||||
}
|
||||
|
||||
@@ -692,7 +700,7 @@ func (r *backupRepo) createPostgres(ctx context.Context, name string, storage st
|
||||
}
|
||||
defer func(file *os.File) { _ = file.Close() }(file)
|
||||
|
||||
if err = storage.Put(filepath.Join(string(biz.BackupTypePostgres), name), file); err != nil {
|
||||
if err = r.upload(ctx, storage, filepath.Join(string(biz.BackupTypePostgres), name), file); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -785,7 +793,7 @@ func (r *backupRepo) createClickHouse(ctx context.Context, name string, storage
|
||||
}
|
||||
defer func(file *os.File) { _ = file.Close() }(file)
|
||||
|
||||
if err = storage.Put(filepath.Join(string(biz.BackupTypeClickHouse), name), file); err != nil {
|
||||
if err = r.upload(ctx, storage, filepath.Join(string(biz.BackupTypeClickHouse), name), file); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -849,7 +857,7 @@ func (r *backupRepo) createPath(ctx context.Context, name string, storage storag
|
||||
}
|
||||
defer func(file *os.File) { _ = file.Close() }(file)
|
||||
|
||||
if err = storage.Put(filepath.Join(string(biz.BackupTypePath), name), file); err != nil {
|
||||
if err = r.upload(ctx, storage, filepath.Join(string(biz.BackupTypePath), name), file); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -969,7 +977,7 @@ func (r *backupRepo) restoreMySQL(ctx context.Context, backup, target string) er
|
||||
return err
|
||||
}
|
||||
defer mysql.Close()
|
||||
if exist, _ := mysql.DatabaseExists(target); !exist {
|
||||
if exist, _ := mysql.DatabaseExists(ctx, target); !exist {
|
||||
return errors.New(r.t.Get("database does not exist: %s", target))
|
||||
}
|
||||
|
||||
@@ -1002,7 +1010,7 @@ func (r *backupRepo) restorePostgres(ctx context.Context, backup, target string)
|
||||
return err
|
||||
}
|
||||
defer postgres.Close()
|
||||
if exist, _ := postgres.DatabaseExists(target); !exist {
|
||||
if exist, _ := postgres.DatabaseExists(ctx, target); !exist {
|
||||
return errors.New(r.t.Get("database does not exist: %s", target))
|
||||
}
|
||||
|
||||
@@ -1214,7 +1222,7 @@ func (r *backupRepo) createRedisLike(ctx context.Context, name string, storage s
|
||||
}
|
||||
defer func(file *os.File) { _ = file.Close() }(file)
|
||||
|
||||
if err = storage.Put(filepath.Join(kind, name), file); err != nil {
|
||||
if err = r.upload(ctx, storage, filepath.Join(kind, name), file); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
+31
-27
@@ -29,14 +29,14 @@ func NewContainerRepo() biz.ContainerRepo {
|
||||
}
|
||||
|
||||
// ListAll 列出所有容器
|
||||
func (r *containerRepo) ListAll(sock string) ([]types.Container, error) {
|
||||
func (r *containerRepo) ListAll(ctx context.Context, sock string) ([]types.Container, error) {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
resp, err := apiClient.ContainerList(context.Background(), client.ContainerListOptions{
|
||||
resp, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
|
||||
All: true,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -114,14 +114,14 @@ func (r *containerRepo) ListAll(sock string) ([]types.Container, error) {
|
||||
}
|
||||
|
||||
// Inspect 获取容器详细信息
|
||||
func (r *containerRepo) Inspect(sock string, id string) (any, error) {
|
||||
func (r *containerRepo) Inspect(ctx context.Context, sock string, id string) (any, error) {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
resp, err := apiClient.ContainerInspect(context.Background(), id, client.ContainerInspectOptions{})
|
||||
resp, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -130,14 +130,15 @@ func (r *containerRepo) Inspect(sock string, id string) (any, error) {
|
||||
}
|
||||
|
||||
// Create 创建容器
|
||||
func (r *containerRepo) Create(sock string, req *request.ContainerCreate) (string, error) {
|
||||
func (r *containerRepo) Create(ctx context.Context, sock string, req *request.ContainerCreate) (string, error) {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
ctx := context.Background()
|
||||
// 创建后紧接着启动,中途取消会留下已创建未启动的容器
|
||||
ctx = context.WithoutCancel(ctx)
|
||||
|
||||
// 获取镜像信息
|
||||
image, err := apiClient.ImageInspect(ctx, req.Image)
|
||||
@@ -295,109 +296,111 @@ func (r *containerRepo) Create(sock string, req *request.ContainerCreate) (strin
|
||||
}
|
||||
|
||||
// Remove 移除容器
|
||||
func (r *containerRepo) Remove(sock string, id string) error {
|
||||
func (r *containerRepo) Remove(ctx context.Context, sock string, id string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ContainerRemove(context.Background(), id, client.ContainerRemoveOptions{
|
||||
// 中途取消会把容器留在删除中的半状态
|
||||
_, err = apiClient.ContainerRemove(context.WithoutCancel(ctx), id, client.ContainerRemoveOptions{
|
||||
Force: true,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// Start 启动容器
|
||||
func (r *containerRepo) Start(sock string, id string) error {
|
||||
func (r *containerRepo) Start(ctx context.Context, sock string, id string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ContainerStart(context.Background(), id, client.ContainerStartOptions{})
|
||||
_, err = apiClient.ContainerStart(ctx, id, client.ContainerStartOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Stop 停止容器
|
||||
func (r *containerRepo) Stop(sock string, id string) error {
|
||||
func (r *containerRepo) Stop(ctx context.Context, sock string, id string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ContainerStop(context.Background(), id, client.ContainerStopOptions{})
|
||||
_, err = apiClient.ContainerStop(ctx, id, client.ContainerStopOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Restart 重启容器
|
||||
func (r *containerRepo) Restart(sock string, id string) error {
|
||||
func (r *containerRepo) Restart(ctx context.Context, sock string, id string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ContainerRestart(context.Background(), id, client.ContainerRestartOptions{})
|
||||
// 内部先停后启,中途取消会把容器留在停止状态
|
||||
_, err = apiClient.ContainerRestart(context.WithoutCancel(ctx), id, client.ContainerRestartOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Pause 暂停容器
|
||||
func (r *containerRepo) Pause(sock string, id string) error {
|
||||
func (r *containerRepo) Pause(ctx context.Context, sock string, id string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ContainerPause(context.Background(), id, client.ContainerPauseOptions{})
|
||||
_, err = apiClient.ContainerPause(ctx, id, client.ContainerPauseOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Unpause 恢复容器
|
||||
func (r *containerRepo) Unpause(sock string, id string) error {
|
||||
func (r *containerRepo) Unpause(ctx context.Context, sock string, id string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ContainerUnpause(context.Background(), id, client.ContainerUnpauseOptions{})
|
||||
_, err = apiClient.ContainerUnpause(ctx, id, client.ContainerUnpauseOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Kill 杀死容器
|
||||
func (r *containerRepo) Kill(sock string, id string) error {
|
||||
func (r *containerRepo) Kill(ctx context.Context, sock string, id string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ContainerKill(context.Background(), id, client.ContainerKillOptions{
|
||||
_, err = apiClient.ContainerKill(ctx, id, client.ContainerKillOptions{
|
||||
Signal: "KILL",
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// Rename 重命名容器
|
||||
func (r *containerRepo) Rename(sock string, id string, newName string) error {
|
||||
func (r *containerRepo) Rename(ctx context.Context, sock string, id string, newName string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ContainerRename(context.Background(), id, client.ContainerRenameOptions{
|
||||
_, err = apiClient.ContainerRename(ctx, id, client.ContainerRenameOptions{
|
||||
NewName: newName,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// Logs 查看容器末尾 tail 行日志
|
||||
func (r *containerRepo) Logs(sock string, id string, tail int) (string, error) {
|
||||
func (r *containerRepo) Logs(ctx context.Context, sock string, id string, tail int) (string, error) {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -405,13 +408,13 @@ func (r *containerRepo) Logs(sock string, id string, tail int) (string, error) {
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
// 非 TTY 容器日志为多路复用流,需按 TTY 设置决定是否解复用
|
||||
inspect, err := apiClient.ContainerInspect(context.Background(), id, client.ContainerInspectOptions{})
|
||||
inspect, err := apiClient.ContainerInspect(ctx, id, client.ContainerInspectOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
tty := inspect.Container.Config != nil && inspect.Container.Config.Tty
|
||||
|
||||
reader, err := apiClient.ContainerLogs(context.Background(), id, client.ContainerLogsOptions{
|
||||
reader, err := apiClient.ContainerLogs(ctx, id, client.ContainerLogsOptions{
|
||||
ShowStdout: true,
|
||||
ShowStderr: true,
|
||||
Tail: strconv.Itoa(tail),
|
||||
@@ -430,14 +433,15 @@ func (r *containerRepo) Logs(sock string, id string, tail int) (string, error) {
|
||||
}
|
||||
|
||||
// Prune 清理未使用的容器
|
||||
func (r *containerRepo) Prune(sock string) error {
|
||||
func (r *containerRepo) Prune(ctx context.Context, sock string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ContainerPrune(context.Background(), client.ContainerPruneOptions{
|
||||
// 中途取消会留下清理到一半的状态
|
||||
_, err = apiClient.ContainerPrune(context.WithoutCancel(ctx), client.ContainerPruneOptions{
|
||||
Filters: make(client.Filters).Add("label", "created_by!=acepanel"),
|
||||
})
|
||||
return err
|
||||
|
||||
@@ -27,14 +27,14 @@ func NewContainerImageRepo() biz.ContainerImageRepo {
|
||||
}
|
||||
|
||||
// List 列出镜像
|
||||
func (r *containerImageRepo) List(sock string) ([]types.ContainerImage, error) {
|
||||
func (r *containerImageRepo) List(ctx context.Context, sock string) ([]types.ContainerImage, error) {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
resp, err := apiClient.ImageList(context.Background(), client.ImageListOptions{
|
||||
resp, err := apiClient.ImageList(ctx, client.ImageListOptions{
|
||||
All: true,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -61,14 +61,14 @@ func (r *containerImageRepo) List(sock string) ([]types.ContainerImage, error) {
|
||||
}
|
||||
|
||||
// Exist 检查镜像是否存在
|
||||
func (r *containerImageRepo) Exist(sock string, name string) (bool, error) {
|
||||
func (r *containerImageRepo) Exist(ctx context.Context, sock string, name string) (bool, error) {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ImageInspect(context.Background(), name)
|
||||
_, err = apiClient.ImageInspect(ctx, name)
|
||||
if err != nil {
|
||||
if cerrdefs.IsNotFound(err) {
|
||||
return false, nil
|
||||
@@ -80,7 +80,7 @@ func (r *containerImageRepo) Exist(sock string, name string) (bool, error) {
|
||||
}
|
||||
|
||||
// Pull 拉取镜像
|
||||
func (r *containerImageRepo) Pull(sock string, req *request.ContainerImagePull) error {
|
||||
func (r *containerImageRepo) Pull(ctx context.Context, sock string, req *request.ContainerImagePull) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -101,24 +101,25 @@ func (r *containerImageRepo) Pull(sock string, req *request.ContainerImagePull)
|
||||
options.RegistryAuth = authStr
|
||||
}
|
||||
|
||||
out, err := apiClient.ImagePull(context.Background(), req.Name, options)
|
||||
out, err := apiClient.ImagePull(ctx, req.Name, options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(out client.ImagePullResponse) { _ = out.Close() }(out)
|
||||
|
||||
return out.Wait(context.Background())
|
||||
return out.Wait(ctx)
|
||||
}
|
||||
|
||||
// Remove 删除镜像
|
||||
func (r *containerImageRepo) Remove(sock string, id string) error {
|
||||
func (r *containerImageRepo) Remove(ctx context.Context, sock string, id string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ImageRemove(context.Background(), id, client.ImageRemoveOptions{
|
||||
// 级联删除父层,中途取消会留下删了一半的镜像链
|
||||
_, err = apiClient.ImageRemove(context.WithoutCancel(ctx), id, client.ImageRemoveOptions{
|
||||
Force: true,
|
||||
PruneChildren: true,
|
||||
})
|
||||
@@ -126,14 +127,15 @@ func (r *containerImageRepo) Remove(sock string, id string) error {
|
||||
}
|
||||
|
||||
// Prune 清理未使用的镜像
|
||||
func (r *containerImageRepo) Prune(sock string) error {
|
||||
func (r *containerImageRepo) Prune(ctx context.Context, sock string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.ImagePrune(context.Background(), client.ImagePruneOptions{
|
||||
// 中途取消会留下清理到一半的状态
|
||||
_, err = apiClient.ImagePrune(context.WithoutCancel(ctx), client.ImagePruneOptions{
|
||||
Filters: make(client.Filters).
|
||||
Add("dangling", "false").
|
||||
Add("label", "created_by!=acepanel"),
|
||||
|
||||
@@ -23,14 +23,14 @@ func NewContainerNetworkRepo() biz.ContainerNetworkRepo {
|
||||
}
|
||||
|
||||
// List 列出网络
|
||||
func (r *containerNetworkRepo) List(sock string) ([]types.ContainerNetwork, error) {
|
||||
func (r *containerNetworkRepo) List(ctx context.Context, sock string) ([]types.ContainerNetwork, error) {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
resp, err := apiClient.NetworkList(context.Background(), client.NetworkListOptions{})
|
||||
resp, err := apiClient.NetworkList(ctx, client.NetworkListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -74,7 +74,7 @@ func (r *containerNetworkRepo) List(sock string) ([]types.ContainerNetwork, erro
|
||||
}
|
||||
|
||||
// Create 创建网络
|
||||
func (r *containerNetworkRepo) Create(sock string, req *request.ContainerNetworkCreate) (string, error) {
|
||||
func (r *containerNetworkRepo) Create(ctx context.Context, sock string, req *request.ContainerNetworkCreate) (string, error) {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -140,7 +140,7 @@ func (r *containerNetworkRepo) Create(sock string, req *request.ContainerNetwork
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := apiClient.NetworkCreate(context.Background(), req.Name, options)
|
||||
resp, err := apiClient.NetworkCreate(ctx, req.Name, options)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -149,7 +149,7 @@ func (r *containerNetworkRepo) Create(sock string, req *request.ContainerNetwork
|
||||
}
|
||||
|
||||
// Remove 删除网络
|
||||
func (r *containerNetworkRepo) Remove(sock string, id string) error {
|
||||
func (r *containerNetworkRepo) Remove(ctx context.Context, sock string, id string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -157,7 +157,7 @@ func (r *containerNetworkRepo) Remove(sock string, id string) error {
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
// 拦截受保护网络的删除
|
||||
info, err := apiClient.NetworkInspect(context.Background(), id, client.NetworkInspectOptions{})
|
||||
info, err := apiClient.NetworkInspect(ctx, id, client.NetworkInspectOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -165,19 +165,21 @@ func (r *containerNetworkRepo) Remove(sock string, id string) error {
|
||||
return errors.New("cannot delete acepanel-network")
|
||||
}
|
||||
|
||||
_, err = apiClient.NetworkRemove(context.Background(), id, client.NetworkRemoveOptions{})
|
||||
// 中途取消会留下拆到一半的网络
|
||||
_, err = apiClient.NetworkRemove(context.WithoutCancel(ctx), id, client.NetworkRemoveOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Prune 清理未使用的网络
|
||||
func (r *containerNetworkRepo) Prune(sock string) error {
|
||||
func (r *containerNetworkRepo) Prune(ctx context.Context, sock string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.NetworkPrune(context.Background(), client.NetworkPruneOptions{
|
||||
// 中途取消会留下清理到一半的状态
|
||||
_, err = apiClient.NetworkPrune(context.WithoutCancel(ctx), client.NetworkPruneOptions{
|
||||
Filters: make(client.Filters).Add("label", "created_by!=acepanel"),
|
||||
})
|
||||
return err
|
||||
|
||||
@@ -21,14 +21,14 @@ func NewContainerVolumeRepo() biz.ContainerVolumeRepo {
|
||||
}
|
||||
|
||||
// List 列出存储卷
|
||||
func (r *containerVolumeRepo) List(sock string) ([]types.ContainerVolume, error) {
|
||||
func (r *containerVolumeRepo) List(ctx context.Context, sock string) ([]types.ContainerVolume, error) {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
resp, err := apiClient.VolumeList(context.Background(), client.VolumeListOptions{})
|
||||
resp, err := apiClient.VolumeList(ctx, client.VolumeListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -63,14 +63,14 @@ func (r *containerVolumeRepo) List(sock string) ([]types.ContainerVolume, error)
|
||||
}
|
||||
|
||||
// Create 创建存储卷
|
||||
func (r *containerVolumeRepo) Create(sock string, req *request.ContainerVolumeCreate) (string, error) {
|
||||
func (r *containerVolumeRepo) Create(ctx context.Context, sock string, req *request.ContainerVolumeCreate) (string, error) {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
resp, err := apiClient.VolumeCreate(context.Background(), client.VolumeCreateOptions{
|
||||
resp, err := apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{
|
||||
Name: req.Name,
|
||||
Driver: req.Driver,
|
||||
DriverOpts: types.KVToMap(req.Options),
|
||||
@@ -84,28 +84,30 @@ func (r *containerVolumeRepo) Create(sock string, req *request.ContainerVolumeCr
|
||||
}
|
||||
|
||||
// Remove 删除存储卷
|
||||
func (r *containerVolumeRepo) Remove(sock string, id string) error {
|
||||
func (r *containerVolumeRepo) Remove(ctx context.Context, sock string, id string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.VolumeRemove(context.Background(), id, client.VolumeRemoveOptions{
|
||||
// 中途取消会留下元数据已删但磁盘数据仍在的卷
|
||||
_, err = apiClient.VolumeRemove(context.WithoutCancel(ctx), id, client.VolumeRemoveOptions{
|
||||
Force: true,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// Prune 清理未使用的存储卷
|
||||
func (r *containerVolumeRepo) Prune(sock string) error {
|
||||
func (r *containerVolumeRepo) Prune(ctx context.Context, sock string) error {
|
||||
apiClient, err := getDockerClient(sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(apiClient *client.Client) { _ = apiClient.Close() }(apiClient)
|
||||
|
||||
_, err = apiClient.VolumePrune(context.Background(), client.VolumePruneOptions{
|
||||
// 中途取消会留下清理到一半的状态
|
||||
_, err = apiClient.VolumePrune(context.WithoutCancel(ctx), client.VolumePruneOptions{
|
||||
Filters: make(client.Filters).Add("label", "created_by!=acepanel"),
|
||||
})
|
||||
return err
|
||||
|
||||
@@ -43,7 +43,7 @@ func (r *databaseRepo) DatabasesOf(ctx context.Context, server *biz.DatabaseServ
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if databases, err := mongo.Databases(); err == nil { //nolint:contextcheck
|
||||
if databases, err := mongo.Databases(ctx); err == nil {
|
||||
for item := range slices.Values(databases) {
|
||||
database = append(database, &biz.Database{
|
||||
Type: server.Type,
|
||||
@@ -55,11 +55,11 @@ func (r *databaseRepo) DatabasesOf(ctx context.Context, server *biz.DatabaseServ
|
||||
}
|
||||
mongo.Close()
|
||||
case biz.DatabaseTypeSQLite:
|
||||
sqlite, err := db.NewSQLite(server.Host) //nolint:contextcheck
|
||||
sqlite, err := db.NewSQLite(ctx, server.Host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if tables, err := sqlite.Tables(); err == nil { //nolint:contextcheck
|
||||
if tables, err := sqlite.Tables(ctx); err == nil {
|
||||
for table := range slices.Values(tables) {
|
||||
database = append(database, &biz.Database{
|
||||
Type: server.Type,
|
||||
@@ -75,7 +75,7 @@ func (r *databaseRepo) DatabasesOf(ctx context.Context, server *biz.DatabaseServ
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if databases, err := operator.Databases(); err == nil {
|
||||
if databases, err := operator.Databases(ctx); err == nil {
|
||||
for item := range slices.Values(databases) {
|
||||
database = append(database, &biz.Database{
|
||||
Type: server.Type,
|
||||
|
||||
@@ -35,7 +35,7 @@ func (r *databaseElasticsearchRepo) Indices(ctx context.Context, req *request.Da
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
return client.Indices()
|
||||
return client.Indices(ctx)
|
||||
}
|
||||
|
||||
func (r *databaseElasticsearchRepo) IndexCreate(ctx context.Context, req *request.DatabaseESIndexCreate) error {
|
||||
@@ -45,7 +45,7 @@ func (r *databaseElasticsearchRepo) IndexCreate(ctx context.Context, req *reques
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
return client.IndexCreate(req.Name)
|
||||
return client.IndexCreate(ctx, req.Name)
|
||||
}
|
||||
|
||||
func (r *databaseElasticsearchRepo) IndexDelete(ctx context.Context, req *request.DatabaseESIndexDelete) error {
|
||||
@@ -55,7 +55,7 @@ func (r *databaseElasticsearchRepo) IndexDelete(ctx context.Context, req *reques
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
return client.IndexDelete(req.Name)
|
||||
return client.IndexDelete(ctx, req.Name)
|
||||
}
|
||||
|
||||
func (r *databaseElasticsearchRepo) Data(ctx context.Context, req *request.DatabaseESData) ([]db.ESDocument, int64, error) {
|
||||
@@ -65,7 +65,7 @@ func (r *databaseElasticsearchRepo) Data(ctx context.Context, req *request.Datab
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
return client.Search(req.Index, req.Search, int(req.Page), int(req.Limit))
|
||||
return client.Search(ctx, req.Index, req.Search, int(req.Page), int(req.Limit))
|
||||
}
|
||||
|
||||
func (r *databaseElasticsearchRepo) DocumentGet(ctx context.Context, req *request.DatabaseESDocumentGet) (*db.ESDocument, error) {
|
||||
@@ -75,7 +75,7 @@ func (r *databaseElasticsearchRepo) DocumentGet(ctx context.Context, req *reques
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
return client.DocumentGet(req.Index, req.ID)
|
||||
return client.DocumentGet(ctx, req.Index, req.ID)
|
||||
}
|
||||
|
||||
func (r *databaseElasticsearchRepo) DocumentSet(ctx context.Context, req *request.DatabaseESDocumentSet) error {
|
||||
@@ -86,9 +86,9 @@ func (r *databaseElasticsearchRepo) DocumentSet(ctx context.Context, req *reques
|
||||
defer client.Close()
|
||||
|
||||
if req.ID == "" {
|
||||
return client.DocumentCreate(req.Index, req.Body)
|
||||
return client.DocumentCreate(ctx, req.Index, req.Body)
|
||||
}
|
||||
return client.DocumentUpdate(req.Index, req.ID, req.Body)
|
||||
return client.DocumentUpdate(ctx, req.Index, req.ID, req.Body)
|
||||
}
|
||||
|
||||
func (r *databaseElasticsearchRepo) DocumentDelete(ctx context.Context, req *request.DatabaseESDocumentDelete) error {
|
||||
@@ -98,7 +98,7 @@ func (r *databaseElasticsearchRepo) DocumentDelete(ctx context.Context, req *req
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
return client.DocumentDelete(req.Index, req.ID)
|
||||
return client.DocumentDelete(ctx, req.Index, req.ID)
|
||||
}
|
||||
|
||||
// getClient 根据服务器 ID 创建 Elasticsearch 客户端
|
||||
|
||||
@@ -146,7 +146,7 @@ func (r *databaseServerRepo) CheckServer(ctx context.Context, server *biz.Databa
|
||||
return true
|
||||
}
|
||||
case biz.DatabaseTypeSQLite:
|
||||
sqlite, err := db.NewSQLite(server.Host) //nolint:contextcheck
|
||||
sqlite, err := db.NewSQLite(ctx, server.Host)
|
||||
if err == nil {
|
||||
sqlite.Close()
|
||||
server.Status = biz.DatabaseServerStatusValid
|
||||
|
||||
@@ -152,7 +152,7 @@ func (r *databaseUserRepo) fillUser(ctx context.Context, user *biz.DatabaseUser)
|
||||
|
||||
switch server.Type {
|
||||
case biz.DatabaseTypeMysql:
|
||||
privileges, _ := operator.UserPrivileges(user.Username, user.Host)
|
||||
privileges, _ := operator.UserPrivileges(ctx, user.Username, user.Host)
|
||||
user.Privileges = privileges
|
||||
if mysql2, err := newMySQLOperator(ctx, user.Username, user.Password, server.Host, server.Port); err == nil {
|
||||
mysql2.Close()
|
||||
@@ -161,7 +161,7 @@ func (r *databaseUserRepo) fillUser(ctx context.Context, user *biz.DatabaseUser)
|
||||
user.Status = biz.DatabaseUserStatusInvalid
|
||||
}
|
||||
case biz.DatabaseTypePostgresql:
|
||||
privileges, _ := operator.UserPrivileges(user.Username)
|
||||
privileges, _ := operator.UserPrivileges(ctx, user.Username)
|
||||
user.Privileges = privileges
|
||||
if postgres2, err := db.NewPostgres(ctx, user.Username, user.Password, server.Host, server.Port); err == nil {
|
||||
postgres2.Close()
|
||||
@@ -170,7 +170,7 @@ func (r *databaseUserRepo) fillUser(ctx context.Context, user *biz.DatabaseUser)
|
||||
user.Status = biz.DatabaseUserStatusInvalid
|
||||
}
|
||||
case biz.DatabaseTypeClickHouse:
|
||||
privileges, _ := operator.UserPrivileges(user.Username)
|
||||
privileges, _ := operator.UserPrivileges(ctx, user.Username)
|
||||
user.Privileges = privileges
|
||||
if ch2, err := db.NewClickHouse(ctx, user.Username, user.Password, fmt.Sprintf("%s:%d", server.Host, server.Port)); err == nil {
|
||||
ch2.Close()
|
||||
|
||||
@@ -25,7 +25,7 @@ var _ biz.BackupRepo = &BackupRepo{}
|
||||
// ClearExpiredFunc: func(path string, prefix string, save uint) error {
|
||||
// panic("mock out the ClearExpired method")
|
||||
// },
|
||||
// ClearStorageExpiredFunc: func(account uint, dir string, prefix string, save uint) error {
|
||||
// ClearStorageExpiredFunc: func(ctx context.Context, account uint, dir string, prefix string, save uint) error {
|
||||
// panic("mock out the ClearStorageExpired method")
|
||||
// },
|
||||
// CreateFunc: func(ctx context.Context, typ biz.BackupType, target string, account uint) error {
|
||||
@@ -37,7 +37,7 @@ var _ biz.BackupRepo = &BackupRepo{}
|
||||
// CutoffLogFunc: func(ctx context.Context, path string, target string) (string, error) {
|
||||
// panic("mock out the CutoffLog method")
|
||||
// },
|
||||
// CutoffUploadFunc: func(account uint, typ biz.BackupType, name string, files []string) error {
|
||||
// CutoffUploadFunc: func(ctx context.Context, account uint, typ biz.BackupType, name string, files []string) error {
|
||||
// panic("mock out the CutoffUpload method")
|
||||
// },
|
||||
// DeleteFunc: func(ctx context.Context, typ biz.BackupType, name string) error {
|
||||
@@ -72,7 +72,7 @@ type BackupRepo struct {
|
||||
ClearExpiredFunc func(path string, prefix string, save uint) error
|
||||
|
||||
// ClearStorageExpiredFunc mocks the ClearStorageExpired method.
|
||||
ClearStorageExpiredFunc func(account uint, dir string, prefix string, save uint) error
|
||||
ClearStorageExpiredFunc func(ctx context.Context, account uint, dir string, prefix string, save uint) error
|
||||
|
||||
// CreateFunc mocks the Create method.
|
||||
CreateFunc func(ctx context.Context, typ biz.BackupType, target string, account uint) error
|
||||
@@ -84,7 +84,7 @@ type BackupRepo struct {
|
||||
CutoffLogFunc func(ctx context.Context, path string, target string) (string, error)
|
||||
|
||||
// CutoffUploadFunc mocks the CutoffUpload method.
|
||||
CutoffUploadFunc func(account uint, typ biz.BackupType, name string, files []string) error
|
||||
CutoffUploadFunc func(ctx context.Context, account uint, typ biz.BackupType, name string, files []string) error
|
||||
|
||||
// DeleteFunc mocks the Delete method.
|
||||
DeleteFunc func(ctx context.Context, typ biz.BackupType, name string) error
|
||||
@@ -120,6 +120,8 @@ type BackupRepo struct {
|
||||
}
|
||||
// ClearStorageExpired holds details about calls to the ClearStorageExpired method.
|
||||
ClearStorageExpired []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Account is the account argument value.
|
||||
Account uint
|
||||
// Dir is the dir argument value.
|
||||
@@ -156,6 +158,8 @@ type BackupRepo struct {
|
||||
}
|
||||
// CutoffUpload holds details about calls to the CutoffUpload method.
|
||||
CutoffUpload []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Account is the account argument value.
|
||||
Account uint
|
||||
// Typ is the typ argument value.
|
||||
@@ -275,16 +279,18 @@ func (mock *BackupRepo) ClearExpiredCalls() []struct {
|
||||
}
|
||||
|
||||
// ClearStorageExpired calls ClearStorageExpiredFunc.
|
||||
func (mock *BackupRepo) ClearStorageExpired(account uint, dir string, prefix string, save uint) error {
|
||||
func (mock *BackupRepo) ClearStorageExpired(ctx context.Context, account uint, dir string, prefix string, save uint) error {
|
||||
if mock.ClearStorageExpiredFunc == nil {
|
||||
panic("BackupRepo.ClearStorageExpiredFunc: method is nil but BackupRepo.ClearStorageExpired was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Account uint
|
||||
Dir string
|
||||
Prefix string
|
||||
Save uint
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Account: account,
|
||||
Dir: dir,
|
||||
Prefix: prefix,
|
||||
@@ -293,7 +299,7 @@ func (mock *BackupRepo) ClearStorageExpired(account uint, dir string, prefix str
|
||||
mock.lockClearStorageExpired.Lock()
|
||||
mock.calls.ClearStorageExpired = append(mock.calls.ClearStorageExpired, callInfo)
|
||||
mock.lockClearStorageExpired.Unlock()
|
||||
return mock.ClearStorageExpiredFunc(account, dir, prefix, save)
|
||||
return mock.ClearStorageExpiredFunc(ctx, account, dir, prefix, save)
|
||||
}
|
||||
|
||||
// ClearStorageExpiredCalls gets all the calls that were made to ClearStorageExpired.
|
||||
@@ -301,12 +307,14 @@ func (mock *BackupRepo) ClearStorageExpired(account uint, dir string, prefix str
|
||||
//
|
||||
// len(mockedBackupRepo.ClearStorageExpiredCalls())
|
||||
func (mock *BackupRepo) ClearStorageExpiredCalls() []struct {
|
||||
Ctx context.Context
|
||||
Account uint
|
||||
Dir string
|
||||
Prefix string
|
||||
Save uint
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Account uint
|
||||
Dir string
|
||||
Prefix string
|
||||
@@ -435,16 +443,18 @@ func (mock *BackupRepo) CutoffLogCalls() []struct {
|
||||
}
|
||||
|
||||
// CutoffUpload calls CutoffUploadFunc.
|
||||
func (mock *BackupRepo) CutoffUpload(account uint, typ biz.BackupType, name string, files []string) error {
|
||||
func (mock *BackupRepo) CutoffUpload(ctx context.Context, account uint, typ biz.BackupType, name string, files []string) error {
|
||||
if mock.CutoffUploadFunc == nil {
|
||||
panic("BackupRepo.CutoffUploadFunc: method is nil but BackupRepo.CutoffUpload was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Account uint
|
||||
Typ biz.BackupType
|
||||
Name string
|
||||
Files []string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Account: account,
|
||||
Typ: typ,
|
||||
Name: name,
|
||||
@@ -453,7 +463,7 @@ func (mock *BackupRepo) CutoffUpload(account uint, typ biz.BackupType, name stri
|
||||
mock.lockCutoffUpload.Lock()
|
||||
mock.calls.CutoffUpload = append(mock.calls.CutoffUpload, callInfo)
|
||||
mock.lockCutoffUpload.Unlock()
|
||||
return mock.CutoffUploadFunc(account, typ, name, files)
|
||||
return mock.CutoffUploadFunc(ctx, account, typ, name, files)
|
||||
}
|
||||
|
||||
// CutoffUploadCalls gets all the calls that were made to CutoffUpload.
|
||||
@@ -461,12 +471,14 @@ func (mock *BackupRepo) CutoffUpload(account uint, typ biz.BackupType, name stri
|
||||
//
|
||||
// len(mockedBackupRepo.CutoffUploadCalls())
|
||||
func (mock *BackupRepo) CutoffUploadCalls() []struct {
|
||||
Ctx context.Context
|
||||
Account uint
|
||||
Typ biz.BackupType
|
||||
Name string
|
||||
Files []string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Account uint
|
||||
Typ biz.BackupType
|
||||
Name string
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/acepanel/panel/v3/internal/biz"
|
||||
@@ -22,19 +23,19 @@ var _ biz.ContainerImageRepo = &ContainerImageRepo{}
|
||||
//
|
||||
// // make and configure a mocked biz.ContainerImageRepo
|
||||
// mockedContainerImageRepo := &ContainerImageRepo{
|
||||
// ExistFunc: func(sock string, name string) (bool, error) {
|
||||
// ExistFunc: func(ctx context.Context, sock string, name string) (bool, error) {
|
||||
// panic("mock out the Exist method")
|
||||
// },
|
||||
// ListFunc: func(sock string) ([]types.ContainerImage, error) {
|
||||
// ListFunc: func(ctx context.Context, sock string) ([]types.ContainerImage, error) {
|
||||
// panic("mock out the List method")
|
||||
// },
|
||||
// PruneFunc: func(sock string) error {
|
||||
// PruneFunc: func(ctx context.Context, sock string) error {
|
||||
// panic("mock out the Prune method")
|
||||
// },
|
||||
// PullFunc: func(sock string, req *request.ContainerImagePull) error {
|
||||
// PullFunc: func(ctx context.Context, sock string, req *request.ContainerImagePull) error {
|
||||
// panic("mock out the Pull method")
|
||||
// },
|
||||
// RemoveFunc: func(sock string, id string) error {
|
||||
// RemoveFunc: func(ctx context.Context, sock string, id string) error {
|
||||
// panic("mock out the Remove method")
|
||||
// },
|
||||
// }
|
||||
@@ -45,24 +46,26 @@ var _ biz.ContainerImageRepo = &ContainerImageRepo{}
|
||||
// }
|
||||
type ContainerImageRepo struct {
|
||||
// ExistFunc mocks the Exist method.
|
||||
ExistFunc func(sock string, name string) (bool, error)
|
||||
ExistFunc func(ctx context.Context, sock string, name string) (bool, error)
|
||||
|
||||
// ListFunc mocks the List method.
|
||||
ListFunc func(sock string) ([]types.ContainerImage, error)
|
||||
ListFunc func(ctx context.Context, sock string) ([]types.ContainerImage, error)
|
||||
|
||||
// PruneFunc mocks the Prune method.
|
||||
PruneFunc func(sock string) error
|
||||
PruneFunc func(ctx context.Context, sock string) error
|
||||
|
||||
// PullFunc mocks the Pull method.
|
||||
PullFunc func(sock string, req *request.ContainerImagePull) error
|
||||
PullFunc func(ctx context.Context, sock string, req *request.ContainerImagePull) error
|
||||
|
||||
// RemoveFunc mocks the Remove method.
|
||||
RemoveFunc func(sock string, id string) error
|
||||
RemoveFunc func(ctx context.Context, sock string, id string) error
|
||||
|
||||
// calls tracks calls to the methods.
|
||||
calls struct {
|
||||
// Exist holds details about calls to the Exist method.
|
||||
Exist []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// Name is the name argument value.
|
||||
@@ -70,16 +73,22 @@ type ContainerImageRepo struct {
|
||||
}
|
||||
// List holds details about calls to the List method.
|
||||
List []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
}
|
||||
// Prune holds details about calls to the Prune method.
|
||||
Prune []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
}
|
||||
// Pull holds details about calls to the Pull method.
|
||||
Pull []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// Req is the req argument value.
|
||||
@@ -87,6 +96,8 @@ type ContainerImageRepo struct {
|
||||
}
|
||||
// Remove holds details about calls to the Remove method.
|
||||
Remove []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -101,21 +112,23 @@ type ContainerImageRepo struct {
|
||||
}
|
||||
|
||||
// Exist calls ExistFunc.
|
||||
func (mock *ContainerImageRepo) Exist(sock string, name string) (bool, error) {
|
||||
func (mock *ContainerImageRepo) Exist(ctx context.Context, sock string, name string) (bool, error) {
|
||||
if mock.ExistFunc == nil {
|
||||
panic("ContainerImageRepo.ExistFunc: method is nil but ContainerImageRepo.Exist was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Name string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
Name: name,
|
||||
}
|
||||
mock.lockExist.Lock()
|
||||
mock.calls.Exist = append(mock.calls.Exist, callInfo)
|
||||
mock.lockExist.Unlock()
|
||||
return mock.ExistFunc(sock, name)
|
||||
return mock.ExistFunc(ctx, sock, name)
|
||||
}
|
||||
|
||||
// ExistCalls gets all the calls that were made to Exist.
|
||||
@@ -123,10 +136,12 @@ func (mock *ContainerImageRepo) Exist(sock string, name string) (bool, error) {
|
||||
//
|
||||
// len(mockedContainerImageRepo.ExistCalls())
|
||||
func (mock *ContainerImageRepo) ExistCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Name string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Name string
|
||||
}
|
||||
@@ -137,19 +152,21 @@ func (mock *ContainerImageRepo) ExistCalls() []struct {
|
||||
}
|
||||
|
||||
// List calls ListFunc.
|
||||
func (mock *ContainerImageRepo) List(sock string) ([]types.ContainerImage, error) {
|
||||
func (mock *ContainerImageRepo) List(ctx context.Context, sock string) ([]types.ContainerImage, error) {
|
||||
if mock.ListFunc == nil {
|
||||
panic("ContainerImageRepo.ListFunc: method is nil but ContainerImageRepo.List was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
}
|
||||
mock.lockList.Lock()
|
||||
mock.calls.List = append(mock.calls.List, callInfo)
|
||||
mock.lockList.Unlock()
|
||||
return mock.ListFunc(sock)
|
||||
return mock.ListFunc(ctx, sock)
|
||||
}
|
||||
|
||||
// ListCalls gets all the calls that were made to List.
|
||||
@@ -157,9 +174,11 @@ func (mock *ContainerImageRepo) List(sock string) ([]types.ContainerImage, error
|
||||
//
|
||||
// len(mockedContainerImageRepo.ListCalls())
|
||||
func (mock *ContainerImageRepo) ListCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}
|
||||
mock.lockList.RLock()
|
||||
@@ -169,19 +188,21 @@ func (mock *ContainerImageRepo) ListCalls() []struct {
|
||||
}
|
||||
|
||||
// Prune calls PruneFunc.
|
||||
func (mock *ContainerImageRepo) Prune(sock string) error {
|
||||
func (mock *ContainerImageRepo) Prune(ctx context.Context, sock string) error {
|
||||
if mock.PruneFunc == nil {
|
||||
panic("ContainerImageRepo.PruneFunc: method is nil but ContainerImageRepo.Prune was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
}
|
||||
mock.lockPrune.Lock()
|
||||
mock.calls.Prune = append(mock.calls.Prune, callInfo)
|
||||
mock.lockPrune.Unlock()
|
||||
return mock.PruneFunc(sock)
|
||||
return mock.PruneFunc(ctx, sock)
|
||||
}
|
||||
|
||||
// PruneCalls gets all the calls that were made to Prune.
|
||||
@@ -189,9 +210,11 @@ func (mock *ContainerImageRepo) Prune(sock string) error {
|
||||
//
|
||||
// len(mockedContainerImageRepo.PruneCalls())
|
||||
func (mock *ContainerImageRepo) PruneCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}
|
||||
mock.lockPrune.RLock()
|
||||
@@ -201,21 +224,23 @@ func (mock *ContainerImageRepo) PruneCalls() []struct {
|
||||
}
|
||||
|
||||
// Pull calls PullFunc.
|
||||
func (mock *ContainerImageRepo) Pull(sock string, req *request.ContainerImagePull) error {
|
||||
func (mock *ContainerImageRepo) Pull(ctx context.Context, sock string, req *request.ContainerImagePull) error {
|
||||
if mock.PullFunc == nil {
|
||||
panic("ContainerImageRepo.PullFunc: method is nil but ContainerImageRepo.Pull was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerImagePull
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
Req: req,
|
||||
}
|
||||
mock.lockPull.Lock()
|
||||
mock.calls.Pull = append(mock.calls.Pull, callInfo)
|
||||
mock.lockPull.Unlock()
|
||||
return mock.PullFunc(sock, req)
|
||||
return mock.PullFunc(ctx, sock, req)
|
||||
}
|
||||
|
||||
// PullCalls gets all the calls that were made to Pull.
|
||||
@@ -223,10 +248,12 @@ func (mock *ContainerImageRepo) Pull(sock string, req *request.ContainerImagePul
|
||||
//
|
||||
// len(mockedContainerImageRepo.PullCalls())
|
||||
func (mock *ContainerImageRepo) PullCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerImagePull
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerImagePull
|
||||
}
|
||||
@@ -237,21 +264,23 @@ func (mock *ContainerImageRepo) PullCalls() []struct {
|
||||
}
|
||||
|
||||
// Remove calls RemoveFunc.
|
||||
func (mock *ContainerImageRepo) Remove(sock string, id string) error {
|
||||
func (mock *ContainerImageRepo) Remove(ctx context.Context, sock string, id string) error {
|
||||
if mock.RemoveFunc == nil {
|
||||
panic("ContainerImageRepo.RemoveFunc: method is nil but ContainerImageRepo.Remove was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
}
|
||||
mock.lockRemove.Lock()
|
||||
mock.calls.Remove = append(mock.calls.Remove, callInfo)
|
||||
mock.lockRemove.Unlock()
|
||||
return mock.RemoveFunc(sock, id)
|
||||
return mock.RemoveFunc(ctx, sock, id)
|
||||
}
|
||||
|
||||
// RemoveCalls gets all the calls that were made to Remove.
|
||||
@@ -259,10 +288,12 @@ func (mock *ContainerImageRepo) Remove(sock string, id string) error {
|
||||
//
|
||||
// len(mockedContainerImageRepo.RemoveCalls())
|
||||
func (mock *ContainerImageRepo) RemoveCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/acepanel/panel/v3/internal/biz"
|
||||
@@ -22,16 +23,16 @@ var _ biz.ContainerNetworkRepo = &ContainerNetworkRepo{}
|
||||
//
|
||||
// // make and configure a mocked biz.ContainerNetworkRepo
|
||||
// mockedContainerNetworkRepo := &ContainerNetworkRepo{
|
||||
// CreateFunc: func(sock string, req *request.ContainerNetworkCreate) (string, error) {
|
||||
// CreateFunc: func(ctx context.Context, sock string, req *request.ContainerNetworkCreate) (string, error) {
|
||||
// panic("mock out the Create method")
|
||||
// },
|
||||
// ListFunc: func(sock string) ([]types.ContainerNetwork, error) {
|
||||
// ListFunc: func(ctx context.Context, sock string) ([]types.ContainerNetwork, error) {
|
||||
// panic("mock out the List method")
|
||||
// },
|
||||
// PruneFunc: func(sock string) error {
|
||||
// PruneFunc: func(ctx context.Context, sock string) error {
|
||||
// panic("mock out the Prune method")
|
||||
// },
|
||||
// RemoveFunc: func(sock string, id string) error {
|
||||
// RemoveFunc: func(ctx context.Context, sock string, id string) error {
|
||||
// panic("mock out the Remove method")
|
||||
// },
|
||||
// }
|
||||
@@ -42,21 +43,23 @@ var _ biz.ContainerNetworkRepo = &ContainerNetworkRepo{}
|
||||
// }
|
||||
type ContainerNetworkRepo struct {
|
||||
// CreateFunc mocks the Create method.
|
||||
CreateFunc func(sock string, req *request.ContainerNetworkCreate) (string, error)
|
||||
CreateFunc func(ctx context.Context, sock string, req *request.ContainerNetworkCreate) (string, error)
|
||||
|
||||
// ListFunc mocks the List method.
|
||||
ListFunc func(sock string) ([]types.ContainerNetwork, error)
|
||||
ListFunc func(ctx context.Context, sock string) ([]types.ContainerNetwork, error)
|
||||
|
||||
// PruneFunc mocks the Prune method.
|
||||
PruneFunc func(sock string) error
|
||||
PruneFunc func(ctx context.Context, sock string) error
|
||||
|
||||
// RemoveFunc mocks the Remove method.
|
||||
RemoveFunc func(sock string, id string) error
|
||||
RemoveFunc func(ctx context.Context, sock string, id string) error
|
||||
|
||||
// calls tracks calls to the methods.
|
||||
calls struct {
|
||||
// Create holds details about calls to the Create method.
|
||||
Create []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// Req is the req argument value.
|
||||
@@ -64,16 +67,22 @@ type ContainerNetworkRepo struct {
|
||||
}
|
||||
// List holds details about calls to the List method.
|
||||
List []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
}
|
||||
// Prune holds details about calls to the Prune method.
|
||||
Prune []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
}
|
||||
// Remove holds details about calls to the Remove method.
|
||||
Remove []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -87,21 +96,23 @@ type ContainerNetworkRepo struct {
|
||||
}
|
||||
|
||||
// Create calls CreateFunc.
|
||||
func (mock *ContainerNetworkRepo) Create(sock string, req *request.ContainerNetworkCreate) (string, error) {
|
||||
func (mock *ContainerNetworkRepo) Create(ctx context.Context, sock string, req *request.ContainerNetworkCreate) (string, error) {
|
||||
if mock.CreateFunc == nil {
|
||||
panic("ContainerNetworkRepo.CreateFunc: method is nil but ContainerNetworkRepo.Create was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerNetworkCreate
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
Req: req,
|
||||
}
|
||||
mock.lockCreate.Lock()
|
||||
mock.calls.Create = append(mock.calls.Create, callInfo)
|
||||
mock.lockCreate.Unlock()
|
||||
return mock.CreateFunc(sock, req)
|
||||
return mock.CreateFunc(ctx, sock, req)
|
||||
}
|
||||
|
||||
// CreateCalls gets all the calls that were made to Create.
|
||||
@@ -109,10 +120,12 @@ func (mock *ContainerNetworkRepo) Create(sock string, req *request.ContainerNetw
|
||||
//
|
||||
// len(mockedContainerNetworkRepo.CreateCalls())
|
||||
func (mock *ContainerNetworkRepo) CreateCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerNetworkCreate
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerNetworkCreate
|
||||
}
|
||||
@@ -123,19 +136,21 @@ func (mock *ContainerNetworkRepo) CreateCalls() []struct {
|
||||
}
|
||||
|
||||
// List calls ListFunc.
|
||||
func (mock *ContainerNetworkRepo) List(sock string) ([]types.ContainerNetwork, error) {
|
||||
func (mock *ContainerNetworkRepo) List(ctx context.Context, sock string) ([]types.ContainerNetwork, error) {
|
||||
if mock.ListFunc == nil {
|
||||
panic("ContainerNetworkRepo.ListFunc: method is nil but ContainerNetworkRepo.List was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
}
|
||||
mock.lockList.Lock()
|
||||
mock.calls.List = append(mock.calls.List, callInfo)
|
||||
mock.lockList.Unlock()
|
||||
return mock.ListFunc(sock)
|
||||
return mock.ListFunc(ctx, sock)
|
||||
}
|
||||
|
||||
// ListCalls gets all the calls that were made to List.
|
||||
@@ -143,9 +158,11 @@ func (mock *ContainerNetworkRepo) List(sock string) ([]types.ContainerNetwork, e
|
||||
//
|
||||
// len(mockedContainerNetworkRepo.ListCalls())
|
||||
func (mock *ContainerNetworkRepo) ListCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}
|
||||
mock.lockList.RLock()
|
||||
@@ -155,19 +172,21 @@ func (mock *ContainerNetworkRepo) ListCalls() []struct {
|
||||
}
|
||||
|
||||
// Prune calls PruneFunc.
|
||||
func (mock *ContainerNetworkRepo) Prune(sock string) error {
|
||||
func (mock *ContainerNetworkRepo) Prune(ctx context.Context, sock string) error {
|
||||
if mock.PruneFunc == nil {
|
||||
panic("ContainerNetworkRepo.PruneFunc: method is nil but ContainerNetworkRepo.Prune was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
}
|
||||
mock.lockPrune.Lock()
|
||||
mock.calls.Prune = append(mock.calls.Prune, callInfo)
|
||||
mock.lockPrune.Unlock()
|
||||
return mock.PruneFunc(sock)
|
||||
return mock.PruneFunc(ctx, sock)
|
||||
}
|
||||
|
||||
// PruneCalls gets all the calls that were made to Prune.
|
||||
@@ -175,9 +194,11 @@ func (mock *ContainerNetworkRepo) Prune(sock string) error {
|
||||
//
|
||||
// len(mockedContainerNetworkRepo.PruneCalls())
|
||||
func (mock *ContainerNetworkRepo) PruneCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}
|
||||
mock.lockPrune.RLock()
|
||||
@@ -187,21 +208,23 @@ func (mock *ContainerNetworkRepo) PruneCalls() []struct {
|
||||
}
|
||||
|
||||
// Remove calls RemoveFunc.
|
||||
func (mock *ContainerNetworkRepo) Remove(sock string, id string) error {
|
||||
func (mock *ContainerNetworkRepo) Remove(ctx context.Context, sock string, id string) error {
|
||||
if mock.RemoveFunc == nil {
|
||||
panic("ContainerNetworkRepo.RemoveFunc: method is nil but ContainerNetworkRepo.Remove was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
}
|
||||
mock.lockRemove.Lock()
|
||||
mock.calls.Remove = append(mock.calls.Remove, callInfo)
|
||||
mock.lockRemove.Unlock()
|
||||
return mock.RemoveFunc(sock, id)
|
||||
return mock.RemoveFunc(ctx, sock, id)
|
||||
}
|
||||
|
||||
// RemoveCalls gets all the calls that were made to Remove.
|
||||
@@ -209,10 +232,12 @@ func (mock *ContainerNetworkRepo) Remove(sock string, id string) error {
|
||||
//
|
||||
// len(mockedContainerNetworkRepo.RemoveCalls())
|
||||
func (mock *ContainerNetworkRepo) RemoveCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/acepanel/panel/v3/internal/biz"
|
||||
@@ -22,43 +23,43 @@ var _ biz.ContainerRepo = &ContainerRepo{}
|
||||
//
|
||||
// // make and configure a mocked biz.ContainerRepo
|
||||
// mockedContainerRepo := &ContainerRepo{
|
||||
// CreateFunc: func(sock string, req *request.ContainerCreate) (string, error) {
|
||||
// CreateFunc: func(ctx context.Context, sock string, req *request.ContainerCreate) (string, error) {
|
||||
// panic("mock out the Create method")
|
||||
// },
|
||||
// InspectFunc: func(sock string, id string) (any, error) {
|
||||
// InspectFunc: func(ctx context.Context, sock string, id string) (any, error) {
|
||||
// panic("mock out the Inspect method")
|
||||
// },
|
||||
// KillFunc: func(sock string, id string) error {
|
||||
// KillFunc: func(ctx context.Context, sock string, id string) error {
|
||||
// panic("mock out the Kill method")
|
||||
// },
|
||||
// ListAllFunc: func(sock string) ([]types.Container, error) {
|
||||
// ListAllFunc: func(ctx context.Context, sock string) ([]types.Container, error) {
|
||||
// panic("mock out the ListAll method")
|
||||
// },
|
||||
// LogsFunc: func(sock string, id string, tail int) (string, error) {
|
||||
// LogsFunc: func(ctx context.Context, sock string, id string, tail int) (string, error) {
|
||||
// panic("mock out the Logs method")
|
||||
// },
|
||||
// PauseFunc: func(sock string, id string) error {
|
||||
// PauseFunc: func(ctx context.Context, sock string, id string) error {
|
||||
// panic("mock out the Pause method")
|
||||
// },
|
||||
// PruneFunc: func(sock string) error {
|
||||
// PruneFunc: func(ctx context.Context, sock string) error {
|
||||
// panic("mock out the Prune method")
|
||||
// },
|
||||
// RemoveFunc: func(sock string, id string) error {
|
||||
// RemoveFunc: func(ctx context.Context, sock string, id string) error {
|
||||
// panic("mock out the Remove method")
|
||||
// },
|
||||
// RenameFunc: func(sock string, id string, newName string) error {
|
||||
// RenameFunc: func(ctx context.Context, sock string, id string, newName string) error {
|
||||
// panic("mock out the Rename method")
|
||||
// },
|
||||
// RestartFunc: func(sock string, id string) error {
|
||||
// RestartFunc: func(ctx context.Context, sock string, id string) error {
|
||||
// panic("mock out the Restart method")
|
||||
// },
|
||||
// StartFunc: func(sock string, id string) error {
|
||||
// StartFunc: func(ctx context.Context, sock string, id string) error {
|
||||
// panic("mock out the Start method")
|
||||
// },
|
||||
// StopFunc: func(sock string, id string) error {
|
||||
// StopFunc: func(ctx context.Context, sock string, id string) error {
|
||||
// panic("mock out the Stop method")
|
||||
// },
|
||||
// UnpauseFunc: func(sock string, id string) error {
|
||||
// UnpauseFunc: func(ctx context.Context, sock string, id string) error {
|
||||
// panic("mock out the Unpause method")
|
||||
// },
|
||||
// }
|
||||
@@ -69,48 +70,50 @@ var _ biz.ContainerRepo = &ContainerRepo{}
|
||||
// }
|
||||
type ContainerRepo struct {
|
||||
// CreateFunc mocks the Create method.
|
||||
CreateFunc func(sock string, req *request.ContainerCreate) (string, error)
|
||||
CreateFunc func(ctx context.Context, sock string, req *request.ContainerCreate) (string, error)
|
||||
|
||||
// InspectFunc mocks the Inspect method.
|
||||
InspectFunc func(sock string, id string) (any, error)
|
||||
InspectFunc func(ctx context.Context, sock string, id string) (any, error)
|
||||
|
||||
// KillFunc mocks the Kill method.
|
||||
KillFunc func(sock string, id string) error
|
||||
KillFunc func(ctx context.Context, sock string, id string) error
|
||||
|
||||
// ListAllFunc mocks the ListAll method.
|
||||
ListAllFunc func(sock string) ([]types.Container, error)
|
||||
ListAllFunc func(ctx context.Context, sock string) ([]types.Container, error)
|
||||
|
||||
// LogsFunc mocks the Logs method.
|
||||
LogsFunc func(sock string, id string, tail int) (string, error)
|
||||
LogsFunc func(ctx context.Context, sock string, id string, tail int) (string, error)
|
||||
|
||||
// PauseFunc mocks the Pause method.
|
||||
PauseFunc func(sock string, id string) error
|
||||
PauseFunc func(ctx context.Context, sock string, id string) error
|
||||
|
||||
// PruneFunc mocks the Prune method.
|
||||
PruneFunc func(sock string) error
|
||||
PruneFunc func(ctx context.Context, sock string) error
|
||||
|
||||
// RemoveFunc mocks the Remove method.
|
||||
RemoveFunc func(sock string, id string) error
|
||||
RemoveFunc func(ctx context.Context, sock string, id string) error
|
||||
|
||||
// RenameFunc mocks the Rename method.
|
||||
RenameFunc func(sock string, id string, newName string) error
|
||||
RenameFunc func(ctx context.Context, sock string, id string, newName string) error
|
||||
|
||||
// RestartFunc mocks the Restart method.
|
||||
RestartFunc func(sock string, id string) error
|
||||
RestartFunc func(ctx context.Context, sock string, id string) error
|
||||
|
||||
// StartFunc mocks the Start method.
|
||||
StartFunc func(sock string, id string) error
|
||||
StartFunc func(ctx context.Context, sock string, id string) error
|
||||
|
||||
// StopFunc mocks the Stop method.
|
||||
StopFunc func(sock string, id string) error
|
||||
StopFunc func(ctx context.Context, sock string, id string) error
|
||||
|
||||
// UnpauseFunc mocks the Unpause method.
|
||||
UnpauseFunc func(sock string, id string) error
|
||||
UnpauseFunc func(ctx context.Context, sock string, id string) error
|
||||
|
||||
// calls tracks calls to the methods.
|
||||
calls struct {
|
||||
// Create holds details about calls to the Create method.
|
||||
Create []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// Req is the req argument value.
|
||||
@@ -118,6 +121,8 @@ type ContainerRepo struct {
|
||||
}
|
||||
// Inspect holds details about calls to the Inspect method.
|
||||
Inspect []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -125,6 +130,8 @@ type ContainerRepo struct {
|
||||
}
|
||||
// Kill holds details about calls to the Kill method.
|
||||
Kill []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -132,11 +139,15 @@ type ContainerRepo struct {
|
||||
}
|
||||
// ListAll holds details about calls to the ListAll method.
|
||||
ListAll []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
}
|
||||
// Logs holds details about calls to the Logs method.
|
||||
Logs []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -146,6 +157,8 @@ type ContainerRepo struct {
|
||||
}
|
||||
// Pause holds details about calls to the Pause method.
|
||||
Pause []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -153,11 +166,15 @@ type ContainerRepo struct {
|
||||
}
|
||||
// Prune holds details about calls to the Prune method.
|
||||
Prune []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
}
|
||||
// Remove holds details about calls to the Remove method.
|
||||
Remove []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -165,6 +182,8 @@ type ContainerRepo struct {
|
||||
}
|
||||
// Rename holds details about calls to the Rename method.
|
||||
Rename []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -174,6 +193,8 @@ type ContainerRepo struct {
|
||||
}
|
||||
// Restart holds details about calls to the Restart method.
|
||||
Restart []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -181,6 +202,8 @@ type ContainerRepo struct {
|
||||
}
|
||||
// Start holds details about calls to the Start method.
|
||||
Start []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -188,6 +211,8 @@ type ContainerRepo struct {
|
||||
}
|
||||
// Stop holds details about calls to the Stop method.
|
||||
Stop []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -195,6 +220,8 @@ type ContainerRepo struct {
|
||||
}
|
||||
// Unpause holds details about calls to the Unpause method.
|
||||
Unpause []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -217,21 +244,23 @@ type ContainerRepo struct {
|
||||
}
|
||||
|
||||
// Create calls CreateFunc.
|
||||
func (mock *ContainerRepo) Create(sock string, req *request.ContainerCreate) (string, error) {
|
||||
func (mock *ContainerRepo) Create(ctx context.Context, sock string, req *request.ContainerCreate) (string, error) {
|
||||
if mock.CreateFunc == nil {
|
||||
panic("ContainerRepo.CreateFunc: method is nil but ContainerRepo.Create was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerCreate
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
Req: req,
|
||||
}
|
||||
mock.lockCreate.Lock()
|
||||
mock.calls.Create = append(mock.calls.Create, callInfo)
|
||||
mock.lockCreate.Unlock()
|
||||
return mock.CreateFunc(sock, req)
|
||||
return mock.CreateFunc(ctx, sock, req)
|
||||
}
|
||||
|
||||
// CreateCalls gets all the calls that were made to Create.
|
||||
@@ -239,10 +268,12 @@ func (mock *ContainerRepo) Create(sock string, req *request.ContainerCreate) (st
|
||||
//
|
||||
// len(mockedContainerRepo.CreateCalls())
|
||||
func (mock *ContainerRepo) CreateCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerCreate
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerCreate
|
||||
}
|
||||
@@ -253,21 +284,23 @@ func (mock *ContainerRepo) CreateCalls() []struct {
|
||||
}
|
||||
|
||||
// Inspect calls InspectFunc.
|
||||
func (mock *ContainerRepo) Inspect(sock string, id string) (any, error) {
|
||||
func (mock *ContainerRepo) Inspect(ctx context.Context, sock string, id string) (any, error) {
|
||||
if mock.InspectFunc == nil {
|
||||
panic("ContainerRepo.InspectFunc: method is nil but ContainerRepo.Inspect was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
}
|
||||
mock.lockInspect.Lock()
|
||||
mock.calls.Inspect = append(mock.calls.Inspect, callInfo)
|
||||
mock.lockInspect.Unlock()
|
||||
return mock.InspectFunc(sock, id)
|
||||
return mock.InspectFunc(ctx, sock, id)
|
||||
}
|
||||
|
||||
// InspectCalls gets all the calls that were made to Inspect.
|
||||
@@ -275,10 +308,12 @@ func (mock *ContainerRepo) Inspect(sock string, id string) (any, error) {
|
||||
//
|
||||
// len(mockedContainerRepo.InspectCalls())
|
||||
func (mock *ContainerRepo) InspectCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}
|
||||
@@ -289,21 +324,23 @@ func (mock *ContainerRepo) InspectCalls() []struct {
|
||||
}
|
||||
|
||||
// Kill calls KillFunc.
|
||||
func (mock *ContainerRepo) Kill(sock string, id string) error {
|
||||
func (mock *ContainerRepo) Kill(ctx context.Context, sock string, id string) error {
|
||||
if mock.KillFunc == nil {
|
||||
panic("ContainerRepo.KillFunc: method is nil but ContainerRepo.Kill was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
}
|
||||
mock.lockKill.Lock()
|
||||
mock.calls.Kill = append(mock.calls.Kill, callInfo)
|
||||
mock.lockKill.Unlock()
|
||||
return mock.KillFunc(sock, id)
|
||||
return mock.KillFunc(ctx, sock, id)
|
||||
}
|
||||
|
||||
// KillCalls gets all the calls that were made to Kill.
|
||||
@@ -311,10 +348,12 @@ func (mock *ContainerRepo) Kill(sock string, id string) error {
|
||||
//
|
||||
// len(mockedContainerRepo.KillCalls())
|
||||
func (mock *ContainerRepo) KillCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}
|
||||
@@ -325,19 +364,21 @@ func (mock *ContainerRepo) KillCalls() []struct {
|
||||
}
|
||||
|
||||
// ListAll calls ListAllFunc.
|
||||
func (mock *ContainerRepo) ListAll(sock string) ([]types.Container, error) {
|
||||
func (mock *ContainerRepo) ListAll(ctx context.Context, sock string) ([]types.Container, error) {
|
||||
if mock.ListAllFunc == nil {
|
||||
panic("ContainerRepo.ListAllFunc: method is nil but ContainerRepo.ListAll was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
}
|
||||
mock.lockListAll.Lock()
|
||||
mock.calls.ListAll = append(mock.calls.ListAll, callInfo)
|
||||
mock.lockListAll.Unlock()
|
||||
return mock.ListAllFunc(sock)
|
||||
return mock.ListAllFunc(ctx, sock)
|
||||
}
|
||||
|
||||
// ListAllCalls gets all the calls that were made to ListAll.
|
||||
@@ -345,9 +386,11 @@ func (mock *ContainerRepo) ListAll(sock string) ([]types.Container, error) {
|
||||
//
|
||||
// len(mockedContainerRepo.ListAllCalls())
|
||||
func (mock *ContainerRepo) ListAllCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}
|
||||
mock.lockListAll.RLock()
|
||||
@@ -357,15 +400,17 @@ func (mock *ContainerRepo) ListAllCalls() []struct {
|
||||
}
|
||||
|
||||
// Logs calls LogsFunc.
|
||||
func (mock *ContainerRepo) Logs(sock string, id string, tail int) (string, error) {
|
||||
func (mock *ContainerRepo) Logs(ctx context.Context, sock string, id string, tail int) (string, error) {
|
||||
if mock.LogsFunc == nil {
|
||||
panic("ContainerRepo.LogsFunc: method is nil but ContainerRepo.Logs was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
Tail int
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
Tail: tail,
|
||||
@@ -373,7 +418,7 @@ func (mock *ContainerRepo) Logs(sock string, id string, tail int) (string, error
|
||||
mock.lockLogs.Lock()
|
||||
mock.calls.Logs = append(mock.calls.Logs, callInfo)
|
||||
mock.lockLogs.Unlock()
|
||||
return mock.LogsFunc(sock, id, tail)
|
||||
return mock.LogsFunc(ctx, sock, id, tail)
|
||||
}
|
||||
|
||||
// LogsCalls gets all the calls that were made to Logs.
|
||||
@@ -381,11 +426,13 @@ func (mock *ContainerRepo) Logs(sock string, id string, tail int) (string, error
|
||||
//
|
||||
// len(mockedContainerRepo.LogsCalls())
|
||||
func (mock *ContainerRepo) LogsCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
Tail int
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
Tail int
|
||||
@@ -397,21 +444,23 @@ func (mock *ContainerRepo) LogsCalls() []struct {
|
||||
}
|
||||
|
||||
// Pause calls PauseFunc.
|
||||
func (mock *ContainerRepo) Pause(sock string, id string) error {
|
||||
func (mock *ContainerRepo) Pause(ctx context.Context, sock string, id string) error {
|
||||
if mock.PauseFunc == nil {
|
||||
panic("ContainerRepo.PauseFunc: method is nil but ContainerRepo.Pause was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
}
|
||||
mock.lockPause.Lock()
|
||||
mock.calls.Pause = append(mock.calls.Pause, callInfo)
|
||||
mock.lockPause.Unlock()
|
||||
return mock.PauseFunc(sock, id)
|
||||
return mock.PauseFunc(ctx, sock, id)
|
||||
}
|
||||
|
||||
// PauseCalls gets all the calls that were made to Pause.
|
||||
@@ -419,10 +468,12 @@ func (mock *ContainerRepo) Pause(sock string, id string) error {
|
||||
//
|
||||
// len(mockedContainerRepo.PauseCalls())
|
||||
func (mock *ContainerRepo) PauseCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}
|
||||
@@ -433,19 +484,21 @@ func (mock *ContainerRepo) PauseCalls() []struct {
|
||||
}
|
||||
|
||||
// Prune calls PruneFunc.
|
||||
func (mock *ContainerRepo) Prune(sock string) error {
|
||||
func (mock *ContainerRepo) Prune(ctx context.Context, sock string) error {
|
||||
if mock.PruneFunc == nil {
|
||||
panic("ContainerRepo.PruneFunc: method is nil but ContainerRepo.Prune was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
}
|
||||
mock.lockPrune.Lock()
|
||||
mock.calls.Prune = append(mock.calls.Prune, callInfo)
|
||||
mock.lockPrune.Unlock()
|
||||
return mock.PruneFunc(sock)
|
||||
return mock.PruneFunc(ctx, sock)
|
||||
}
|
||||
|
||||
// PruneCalls gets all the calls that were made to Prune.
|
||||
@@ -453,9 +506,11 @@ func (mock *ContainerRepo) Prune(sock string) error {
|
||||
//
|
||||
// len(mockedContainerRepo.PruneCalls())
|
||||
func (mock *ContainerRepo) PruneCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}
|
||||
mock.lockPrune.RLock()
|
||||
@@ -465,21 +520,23 @@ func (mock *ContainerRepo) PruneCalls() []struct {
|
||||
}
|
||||
|
||||
// Remove calls RemoveFunc.
|
||||
func (mock *ContainerRepo) Remove(sock string, id string) error {
|
||||
func (mock *ContainerRepo) Remove(ctx context.Context, sock string, id string) error {
|
||||
if mock.RemoveFunc == nil {
|
||||
panic("ContainerRepo.RemoveFunc: method is nil but ContainerRepo.Remove was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
}
|
||||
mock.lockRemove.Lock()
|
||||
mock.calls.Remove = append(mock.calls.Remove, callInfo)
|
||||
mock.lockRemove.Unlock()
|
||||
return mock.RemoveFunc(sock, id)
|
||||
return mock.RemoveFunc(ctx, sock, id)
|
||||
}
|
||||
|
||||
// RemoveCalls gets all the calls that were made to Remove.
|
||||
@@ -487,10 +544,12 @@ func (mock *ContainerRepo) Remove(sock string, id string) error {
|
||||
//
|
||||
// len(mockedContainerRepo.RemoveCalls())
|
||||
func (mock *ContainerRepo) RemoveCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}
|
||||
@@ -501,15 +560,17 @@ func (mock *ContainerRepo) RemoveCalls() []struct {
|
||||
}
|
||||
|
||||
// Rename calls RenameFunc.
|
||||
func (mock *ContainerRepo) Rename(sock string, id string, newName string) error {
|
||||
func (mock *ContainerRepo) Rename(ctx context.Context, sock string, id string, newName string) error {
|
||||
if mock.RenameFunc == nil {
|
||||
panic("ContainerRepo.RenameFunc: method is nil but ContainerRepo.Rename was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
NewName string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
NewName: newName,
|
||||
@@ -517,7 +578,7 @@ func (mock *ContainerRepo) Rename(sock string, id string, newName string) error
|
||||
mock.lockRename.Lock()
|
||||
mock.calls.Rename = append(mock.calls.Rename, callInfo)
|
||||
mock.lockRename.Unlock()
|
||||
return mock.RenameFunc(sock, id, newName)
|
||||
return mock.RenameFunc(ctx, sock, id, newName)
|
||||
}
|
||||
|
||||
// RenameCalls gets all the calls that were made to Rename.
|
||||
@@ -525,11 +586,13 @@ func (mock *ContainerRepo) Rename(sock string, id string, newName string) error
|
||||
//
|
||||
// len(mockedContainerRepo.RenameCalls())
|
||||
func (mock *ContainerRepo) RenameCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
NewName string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
NewName string
|
||||
@@ -541,21 +604,23 @@ func (mock *ContainerRepo) RenameCalls() []struct {
|
||||
}
|
||||
|
||||
// Restart calls RestartFunc.
|
||||
func (mock *ContainerRepo) Restart(sock string, id string) error {
|
||||
func (mock *ContainerRepo) Restart(ctx context.Context, sock string, id string) error {
|
||||
if mock.RestartFunc == nil {
|
||||
panic("ContainerRepo.RestartFunc: method is nil but ContainerRepo.Restart was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
}
|
||||
mock.lockRestart.Lock()
|
||||
mock.calls.Restart = append(mock.calls.Restart, callInfo)
|
||||
mock.lockRestart.Unlock()
|
||||
return mock.RestartFunc(sock, id)
|
||||
return mock.RestartFunc(ctx, sock, id)
|
||||
}
|
||||
|
||||
// RestartCalls gets all the calls that were made to Restart.
|
||||
@@ -563,10 +628,12 @@ func (mock *ContainerRepo) Restart(sock string, id string) error {
|
||||
//
|
||||
// len(mockedContainerRepo.RestartCalls())
|
||||
func (mock *ContainerRepo) RestartCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}
|
||||
@@ -577,21 +644,23 @@ func (mock *ContainerRepo) RestartCalls() []struct {
|
||||
}
|
||||
|
||||
// Start calls StartFunc.
|
||||
func (mock *ContainerRepo) Start(sock string, id string) error {
|
||||
func (mock *ContainerRepo) Start(ctx context.Context, sock string, id string) error {
|
||||
if mock.StartFunc == nil {
|
||||
panic("ContainerRepo.StartFunc: method is nil but ContainerRepo.Start was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
}
|
||||
mock.lockStart.Lock()
|
||||
mock.calls.Start = append(mock.calls.Start, callInfo)
|
||||
mock.lockStart.Unlock()
|
||||
return mock.StartFunc(sock, id)
|
||||
return mock.StartFunc(ctx, sock, id)
|
||||
}
|
||||
|
||||
// StartCalls gets all the calls that were made to Start.
|
||||
@@ -599,10 +668,12 @@ func (mock *ContainerRepo) Start(sock string, id string) error {
|
||||
//
|
||||
// len(mockedContainerRepo.StartCalls())
|
||||
func (mock *ContainerRepo) StartCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}
|
||||
@@ -613,21 +684,23 @@ func (mock *ContainerRepo) StartCalls() []struct {
|
||||
}
|
||||
|
||||
// Stop calls StopFunc.
|
||||
func (mock *ContainerRepo) Stop(sock string, id string) error {
|
||||
func (mock *ContainerRepo) Stop(ctx context.Context, sock string, id string) error {
|
||||
if mock.StopFunc == nil {
|
||||
panic("ContainerRepo.StopFunc: method is nil but ContainerRepo.Stop was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
}
|
||||
mock.lockStop.Lock()
|
||||
mock.calls.Stop = append(mock.calls.Stop, callInfo)
|
||||
mock.lockStop.Unlock()
|
||||
return mock.StopFunc(sock, id)
|
||||
return mock.StopFunc(ctx, sock, id)
|
||||
}
|
||||
|
||||
// StopCalls gets all the calls that were made to Stop.
|
||||
@@ -635,10 +708,12 @@ func (mock *ContainerRepo) Stop(sock string, id string) error {
|
||||
//
|
||||
// len(mockedContainerRepo.StopCalls())
|
||||
func (mock *ContainerRepo) StopCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}
|
||||
@@ -649,21 +724,23 @@ func (mock *ContainerRepo) StopCalls() []struct {
|
||||
}
|
||||
|
||||
// Unpause calls UnpauseFunc.
|
||||
func (mock *ContainerRepo) Unpause(sock string, id string) error {
|
||||
func (mock *ContainerRepo) Unpause(ctx context.Context, sock string, id string) error {
|
||||
if mock.UnpauseFunc == nil {
|
||||
panic("ContainerRepo.UnpauseFunc: method is nil but ContainerRepo.Unpause was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
}
|
||||
mock.lockUnpause.Lock()
|
||||
mock.calls.Unpause = append(mock.calls.Unpause, callInfo)
|
||||
mock.lockUnpause.Unlock()
|
||||
return mock.UnpauseFunc(sock, id)
|
||||
return mock.UnpauseFunc(ctx, sock, id)
|
||||
}
|
||||
|
||||
// UnpauseCalls gets all the calls that were made to Unpause.
|
||||
@@ -671,10 +748,12 @@ func (mock *ContainerRepo) Unpause(sock string, id string) error {
|
||||
//
|
||||
// len(mockedContainerRepo.UnpauseCalls())
|
||||
func (mock *ContainerRepo) UnpauseCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/acepanel/panel/v3/internal/biz"
|
||||
@@ -22,16 +23,16 @@ var _ biz.ContainerVolumeRepo = &ContainerVolumeRepo{}
|
||||
//
|
||||
// // make and configure a mocked biz.ContainerVolumeRepo
|
||||
// mockedContainerVolumeRepo := &ContainerVolumeRepo{
|
||||
// CreateFunc: func(sock string, req *request.ContainerVolumeCreate) (string, error) {
|
||||
// CreateFunc: func(ctx context.Context, sock string, req *request.ContainerVolumeCreate) (string, error) {
|
||||
// panic("mock out the Create method")
|
||||
// },
|
||||
// ListFunc: func(sock string) ([]types.ContainerVolume, error) {
|
||||
// ListFunc: func(ctx context.Context, sock string) ([]types.ContainerVolume, error) {
|
||||
// panic("mock out the List method")
|
||||
// },
|
||||
// PruneFunc: func(sock string) error {
|
||||
// PruneFunc: func(ctx context.Context, sock string) error {
|
||||
// panic("mock out the Prune method")
|
||||
// },
|
||||
// RemoveFunc: func(sock string, id string) error {
|
||||
// RemoveFunc: func(ctx context.Context, sock string, id string) error {
|
||||
// panic("mock out the Remove method")
|
||||
// },
|
||||
// }
|
||||
@@ -42,21 +43,23 @@ var _ biz.ContainerVolumeRepo = &ContainerVolumeRepo{}
|
||||
// }
|
||||
type ContainerVolumeRepo struct {
|
||||
// CreateFunc mocks the Create method.
|
||||
CreateFunc func(sock string, req *request.ContainerVolumeCreate) (string, error)
|
||||
CreateFunc func(ctx context.Context, sock string, req *request.ContainerVolumeCreate) (string, error)
|
||||
|
||||
// ListFunc mocks the List method.
|
||||
ListFunc func(sock string) ([]types.ContainerVolume, error)
|
||||
ListFunc func(ctx context.Context, sock string) ([]types.ContainerVolume, error)
|
||||
|
||||
// PruneFunc mocks the Prune method.
|
||||
PruneFunc func(sock string) error
|
||||
PruneFunc func(ctx context.Context, sock string) error
|
||||
|
||||
// RemoveFunc mocks the Remove method.
|
||||
RemoveFunc func(sock string, id string) error
|
||||
RemoveFunc func(ctx context.Context, sock string, id string) error
|
||||
|
||||
// calls tracks calls to the methods.
|
||||
calls struct {
|
||||
// Create holds details about calls to the Create method.
|
||||
Create []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// Req is the req argument value.
|
||||
@@ -64,16 +67,22 @@ type ContainerVolumeRepo struct {
|
||||
}
|
||||
// List holds details about calls to the List method.
|
||||
List []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
}
|
||||
// Prune holds details about calls to the Prune method.
|
||||
Prune []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
}
|
||||
// Remove holds details about calls to the Remove method.
|
||||
Remove []struct {
|
||||
// Ctx is the ctx argument value.
|
||||
Ctx context.Context
|
||||
// Sock is the sock argument value.
|
||||
Sock string
|
||||
// ID is the id argument value.
|
||||
@@ -87,21 +96,23 @@ type ContainerVolumeRepo struct {
|
||||
}
|
||||
|
||||
// Create calls CreateFunc.
|
||||
func (mock *ContainerVolumeRepo) Create(sock string, req *request.ContainerVolumeCreate) (string, error) {
|
||||
func (mock *ContainerVolumeRepo) Create(ctx context.Context, sock string, req *request.ContainerVolumeCreate) (string, error) {
|
||||
if mock.CreateFunc == nil {
|
||||
panic("ContainerVolumeRepo.CreateFunc: method is nil but ContainerVolumeRepo.Create was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerVolumeCreate
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
Req: req,
|
||||
}
|
||||
mock.lockCreate.Lock()
|
||||
mock.calls.Create = append(mock.calls.Create, callInfo)
|
||||
mock.lockCreate.Unlock()
|
||||
return mock.CreateFunc(sock, req)
|
||||
return mock.CreateFunc(ctx, sock, req)
|
||||
}
|
||||
|
||||
// CreateCalls gets all the calls that were made to Create.
|
||||
@@ -109,10 +120,12 @@ func (mock *ContainerVolumeRepo) Create(sock string, req *request.ContainerVolum
|
||||
//
|
||||
// len(mockedContainerVolumeRepo.CreateCalls())
|
||||
func (mock *ContainerVolumeRepo) CreateCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerVolumeCreate
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
Req *request.ContainerVolumeCreate
|
||||
}
|
||||
@@ -123,19 +136,21 @@ func (mock *ContainerVolumeRepo) CreateCalls() []struct {
|
||||
}
|
||||
|
||||
// List calls ListFunc.
|
||||
func (mock *ContainerVolumeRepo) List(sock string) ([]types.ContainerVolume, error) {
|
||||
func (mock *ContainerVolumeRepo) List(ctx context.Context, sock string) ([]types.ContainerVolume, error) {
|
||||
if mock.ListFunc == nil {
|
||||
panic("ContainerVolumeRepo.ListFunc: method is nil but ContainerVolumeRepo.List was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
}
|
||||
mock.lockList.Lock()
|
||||
mock.calls.List = append(mock.calls.List, callInfo)
|
||||
mock.lockList.Unlock()
|
||||
return mock.ListFunc(sock)
|
||||
return mock.ListFunc(ctx, sock)
|
||||
}
|
||||
|
||||
// ListCalls gets all the calls that were made to List.
|
||||
@@ -143,9 +158,11 @@ func (mock *ContainerVolumeRepo) List(sock string) ([]types.ContainerVolume, err
|
||||
//
|
||||
// len(mockedContainerVolumeRepo.ListCalls())
|
||||
func (mock *ContainerVolumeRepo) ListCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}
|
||||
mock.lockList.RLock()
|
||||
@@ -155,19 +172,21 @@ func (mock *ContainerVolumeRepo) ListCalls() []struct {
|
||||
}
|
||||
|
||||
// Prune calls PruneFunc.
|
||||
func (mock *ContainerVolumeRepo) Prune(sock string) error {
|
||||
func (mock *ContainerVolumeRepo) Prune(ctx context.Context, sock string) error {
|
||||
if mock.PruneFunc == nil {
|
||||
panic("ContainerVolumeRepo.PruneFunc: method is nil but ContainerVolumeRepo.Prune was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
}
|
||||
mock.lockPrune.Lock()
|
||||
mock.calls.Prune = append(mock.calls.Prune, callInfo)
|
||||
mock.lockPrune.Unlock()
|
||||
return mock.PruneFunc(sock)
|
||||
return mock.PruneFunc(ctx, sock)
|
||||
}
|
||||
|
||||
// PruneCalls gets all the calls that were made to Prune.
|
||||
@@ -175,9 +194,11 @@ func (mock *ContainerVolumeRepo) Prune(sock string) error {
|
||||
//
|
||||
// len(mockedContainerVolumeRepo.PruneCalls())
|
||||
func (mock *ContainerVolumeRepo) PruneCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
}
|
||||
mock.lockPrune.RLock()
|
||||
@@ -187,21 +208,23 @@ func (mock *ContainerVolumeRepo) PruneCalls() []struct {
|
||||
}
|
||||
|
||||
// Remove calls RemoveFunc.
|
||||
func (mock *ContainerVolumeRepo) Remove(sock string, id string) error {
|
||||
func (mock *ContainerVolumeRepo) Remove(ctx context.Context, sock string, id string) error {
|
||||
if mock.RemoveFunc == nil {
|
||||
panic("ContainerVolumeRepo.RemoveFunc: method is nil but ContainerVolumeRepo.Remove was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}{
|
||||
Ctx: ctx,
|
||||
Sock: sock,
|
||||
ID: id,
|
||||
}
|
||||
mock.lockRemove.Lock()
|
||||
mock.calls.Remove = append(mock.calls.Remove, callInfo)
|
||||
mock.lockRemove.Unlock()
|
||||
return mock.RemoveFunc(sock, id)
|
||||
return mock.RemoveFunc(ctx, sock, id)
|
||||
}
|
||||
|
||||
// RemoveCalls gets all the calls that were made to Remove.
|
||||
@@ -209,10 +232,12 @@ func (mock *ContainerVolumeRepo) Remove(sock string, id string) error {
|
||||
//
|
||||
// len(mockedContainerVolumeRepo.RemoveCalls())
|
||||
func (mock *ContainerVolumeRepo) RemoveCalls() []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
} {
|
||||
var calls []struct {
|
||||
Ctx context.Context
|
||||
Sock string
|
||||
ID string
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
@@ -51,7 +52,7 @@ func (s *BackupStorageService) Create(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.validateStorage(req.Type, req.Info); err != nil {
|
||||
if err = s.validateStorage(r.Context(), req.Type, req.Info); err != nil {
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -72,7 +73,7 @@ func (s *BackupStorageService) Update(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.validateStorage(req.Type, req.Info); err != nil {
|
||||
if err = s.validateStorage(r.Context(), req.Type, req.Info); err != nil {
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -117,7 +118,7 @@ func (s *BackupStorageService) Delete(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// validateStorage 验证存储配置是否正确
|
||||
func (s *BackupStorageService) validateStorage(accountType string, info types.BackupStorageInfo) error {
|
||||
func (s *BackupStorageService) validateStorage(ctx context.Context, accountType string, info types.BackupStorageInfo) error {
|
||||
var err error
|
||||
var client storage.Storage
|
||||
|
||||
@@ -159,7 +160,7 @@ func (s *BackupStorageService) validateStorage(accountType string, info types.Ba
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err = client.List(""); err != nil {
|
||||
if _, err = client.List(ctx, ""); err != nil {
|
||||
return errors.New(s.t.Get("storage connection error: %v", err))
|
||||
}
|
||||
|
||||
|
||||
@@ -1194,7 +1194,7 @@ func (s *CliService) BackupClear(ctx context.Context, cmd *cli.Command) error {
|
||||
fmt.Println(s.t.Get("|-Keep count: %d", cmd.Uint("keep")))
|
||||
|
||||
if cmd.Uint("storage") != 0 {
|
||||
if err := s.backupRepo.ClearStorageExpired(cmd.Uint("storage"), cmd.String("type"), cmd.String("file"), cmd.Uint("keep")); err != nil {
|
||||
if err := s.backupRepo.ClearStorageExpired(ctx, cmd.Uint("storage"), cmd.String("type"), cmd.String("file"), cmd.Uint("keep")); err != nil {
|
||||
return errors.New(s.t.Get("Cleaning failed: %v", err))
|
||||
}
|
||||
} else {
|
||||
@@ -1250,7 +1250,7 @@ func (s *CliService) CutoffWebsite(ctx context.Context, cmd *cli.Command) error
|
||||
|
||||
// 上传到远程存储
|
||||
if cmd.Uint("storage") != 0 {
|
||||
if err = s.backupRepo.CutoffUpload(cmd.Uint("storage"), biz.BackupTypeWebsite, website.Name, files); err != nil {
|
||||
if err = s.backupRepo.CutoffUpload(ctx, cmd.Uint("storage"), biz.BackupTypeWebsite, website.Name, files); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -1289,7 +1289,7 @@ func (s *CliService) CutoffContainer(ctx context.Context, cmd *cli.Command) erro
|
||||
|
||||
// 上传到远程存储
|
||||
if cmd.Uint("storage") != 0 {
|
||||
if err = s.backupRepo.CutoffUpload(cmd.Uint("storage"), "container", name, []string{zipPath}); err != nil {
|
||||
if err = s.backupRepo.CutoffUpload(ctx, cmd.Uint("storage"), "container", name, []string{zipPath}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -1337,7 +1337,7 @@ func (s *CliService) CutoffClear(ctx context.Context, cmd *cli.Command) error {
|
||||
}
|
||||
// 清理远程存储过期日志,切割日志上传在 cutoff/<类型>/<目标> 下
|
||||
if storageID != 0 {
|
||||
if err := s.backupRepo.ClearStorageExpired(storageID, filepath.Join("cutoff", typ, name), prefix, keep); err != nil {
|
||||
if err := s.backupRepo.ClearStorageExpired(ctx, storageID, filepath.Join("cutoff", typ, name), prefix, keep); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func NewContainerService(containerUsecase *biz.ContainerUsecase) *ContainerServi
|
||||
}
|
||||
|
||||
func (s *ContainerService) List(w http.ResponseWriter, r *http.Request) {
|
||||
containers, err := s.containerRepo.ListAll()
|
||||
containers, err := s.containerRepo.ListAll(r.Context())
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
}
|
||||
@@ -35,7 +35,7 @@ func (s *ContainerService) List(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *ContainerService) Search(w http.ResponseWriter, r *http.Request) {
|
||||
containers, err := s.containerRepo.ListByName(r.FormValue("name"))
|
||||
containers, err := s.containerRepo.ListByName(r.Context(), r.FormValue("name"))
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -48,7 +48,7 @@ func (s *ContainerService) Search(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *ContainerService) Inspect(w http.ResponseWriter, r *http.Request) {
|
||||
data, err := s.containerRepo.Inspect(chi.URLParam(r, "id"))
|
||||
data, err := s.containerRepo.Inspect(r.Context(), chi.URLParam(r, "id"))
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -74,7 +74,7 @@ func (s *ContainerService) Update(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
id, err := s.containerRepo.Update(idParam, req)
|
||||
id, err := s.containerRepo.Update(r.Context(), idParam, req)
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -99,7 +99,7 @@ func (s *ContainerService) Create(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
id, err := s.containerRepo.Create(req)
|
||||
id, err := s.containerRepo.Create(r.Context(), req)
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -115,7 +115,7 @@ func (s *ContainerService) Remove(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerRepo.Remove(req.ID); err != nil {
|
||||
if err = s.containerRepo.Remove(r.Context(), req.ID); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -130,7 +130,7 @@ func (s *ContainerService) Start(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerRepo.Start(req.ID); err != nil {
|
||||
if err = s.containerRepo.Start(r.Context(), req.ID); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -145,7 +145,7 @@ func (s *ContainerService) Stop(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerRepo.Stop(req.ID); err != nil {
|
||||
if err = s.containerRepo.Stop(r.Context(), req.ID); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -160,7 +160,7 @@ func (s *ContainerService) Restart(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerRepo.Restart(req.ID); err != nil {
|
||||
if err = s.containerRepo.Restart(r.Context(), req.ID); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -175,7 +175,7 @@ func (s *ContainerService) Pause(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerRepo.Pause(req.ID); err != nil {
|
||||
if err = s.containerRepo.Pause(r.Context(), req.ID); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -190,7 +190,7 @@ func (s *ContainerService) Unpause(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerRepo.Unpause(req.ID); err != nil {
|
||||
if err = s.containerRepo.Unpause(r.Context(), req.ID); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -205,7 +205,7 @@ func (s *ContainerService) Kill(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerRepo.Kill(req.ID); err != nil {
|
||||
if err = s.containerRepo.Kill(r.Context(), req.ID); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -220,7 +220,7 @@ func (s *ContainerService) Rename(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerRepo.Rename(req.ID, req.Name); err != nil {
|
||||
if err = s.containerRepo.Rename(r.Context(), req.ID, req.Name); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -229,7 +229,7 @@ func (s *ContainerService) Rename(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *ContainerService) Prune(w http.ResponseWriter, r *http.Request) {
|
||||
if err := s.containerRepo.Prune(); err != nil {
|
||||
if err := s.containerRepo.Prune(r.Context()); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func NewContainerImageService(containerImageUsecase *biz.ContainerImageUsecase)
|
||||
}
|
||||
|
||||
func (s *ContainerImageService) List(w http.ResponseWriter, r *http.Request) {
|
||||
images, err := s.containerImageRepo.List()
|
||||
images, err := s.containerImageRepo.List(r.Context())
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -41,7 +41,7 @@ func (s *ContainerImageService) Exist(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
exist, err := s.containerImageRepo.Exist(req.Name)
|
||||
exist, err := s.containerImageRepo.Exist(r.Context(), req.Name)
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -66,7 +66,7 @@ func (s *ContainerImageService) Pull(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerImageRepo.Pull(req); err != nil {
|
||||
if err = s.containerImageRepo.Pull(r.Context(), req); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -81,7 +81,7 @@ func (s *ContainerImageService) Remove(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerImageRepo.Remove(req.ID); err != nil {
|
||||
if err = s.containerImageRepo.Remove(r.Context(), req.ID); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -90,7 +90,7 @@ func (s *ContainerImageService) Remove(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *ContainerImageService) Prune(w http.ResponseWriter, r *http.Request) {
|
||||
if err := s.containerImageRepo.Prune(); err != nil {
|
||||
if err := s.containerImageRepo.Prune(r.Context()); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func NewContainerNetworkService(containerNetworkUsecase *biz.ContainerNetworkUse
|
||||
}
|
||||
|
||||
func (s *ContainerNetworkService) List(w http.ResponseWriter, r *http.Request) {
|
||||
networks, err := s.containerNetworkRepo.List()
|
||||
networks, err := s.containerNetworkRepo.List(r.Context())
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -41,7 +41,7 @@ func (s *ContainerNetworkService) Create(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
id, err := s.containerNetworkRepo.Create(req)
|
||||
id, err := s.containerNetworkRepo.Create(r.Context(), req)
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -57,7 +57,7 @@ func (s *ContainerNetworkService) Remove(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerNetworkRepo.Remove(req.ID); err != nil {
|
||||
if err = s.containerNetworkRepo.Remove(r.Context(), req.ID); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -66,7 +66,7 @@ func (s *ContainerNetworkService) Remove(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
func (s *ContainerNetworkService) Prune(w http.ResponseWriter, r *http.Request) {
|
||||
if err := s.containerNetworkRepo.Prune(); err != nil {
|
||||
if err := s.containerNetworkRepo.Prune(r.Context()); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func NewContainerVolumeService(containerVolumeUsecase *biz.ContainerVolumeUsecas
|
||||
}
|
||||
|
||||
func (s *ContainerVolumeService) List(w http.ResponseWriter, r *http.Request) {
|
||||
volumes, err := s.containerVolumeRepo.List()
|
||||
volumes, err := s.containerVolumeRepo.List(r.Context())
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -41,7 +41,7 @@ func (s *ContainerVolumeService) Create(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
name, err := s.containerVolumeRepo.Create(req)
|
||||
name, err := s.containerVolumeRepo.Create(r.Context(), req)
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -57,7 +57,7 @@ func (s *ContainerVolumeService) Remove(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.containerVolumeRepo.Remove(req.ID); err != nil {
|
||||
if err = s.containerVolumeRepo.Remove(r.Context(), req.ID); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -66,7 +66,7 @@ func (s *ContainerVolumeService) Remove(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
func (s *ContainerVolumeService) Prune(w http.ResponseWriter, r *http.Request) {
|
||||
if err := s.containerVolumeRepo.Prune(); err != nil {
|
||||
if err := s.containerVolumeRepo.Prune(r.Context()); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ func (s *FileService) Tail(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if req.Container != "" {
|
||||
s.tailContainer(w, req)
|
||||
s.tailContainer(r.Context(), w, req)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1058,10 +1058,10 @@ func formatJournalLine(ts, hostname, ident, comm, pid, message string) string {
|
||||
}
|
||||
|
||||
// tailContainer 反向读取容器末尾日志
|
||||
func (s *FileService) tailContainer(w http.ResponseWriter, req *request.FileTail) {
|
||||
func (s *FileService) tailContainer(ctx context.Context, w http.ResponseWriter, req *request.FileTail) {
|
||||
// 容器日志只能整段拉取再切片,回溯深度由 Tail 顶部统一钳制
|
||||
total := req.Offset + req.Limit
|
||||
out, err := s.containerRepo.Logs(req.Container, total)
|
||||
out, err := s.containerRepo.Logs(ctx, req.Container, total)
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
|
||||
@@ -184,7 +184,7 @@ func (s *HomeService) CountInfo(w http.ResponseWriter, r *http.Request) {
|
||||
mysql, err := db.NewMySQL(r.Context(), "root", rootPassword, db.MySQLSocket(app.Root), "unix")
|
||||
if err == nil {
|
||||
defer mysql.Close()
|
||||
databases, err := mysql.Databases()
|
||||
databases, err := mysql.Databases(r.Context())
|
||||
if err == nil {
|
||||
databaseCount += len(databases)
|
||||
}
|
||||
@@ -194,7 +194,7 @@ func (s *HomeService) CountInfo(w http.ResponseWriter, r *http.Request) {
|
||||
if server, err := s.databaseServerRepo.GetByName(r.Context(), "local_postgresql"); err == nil {
|
||||
if postgres, err := db.NewPostgres(r.Context(), server.Username, server.Password, server.Host, server.Port); err == nil {
|
||||
defer postgres.Close()
|
||||
if databases, err := postgres.Databases(); err == nil {
|
||||
if databases, err := postgres.Databases(r.Context()); err == nil {
|
||||
databaseCount += len(databases)
|
||||
}
|
||||
}
|
||||
@@ -212,7 +212,7 @@ func (s *HomeService) CountInfo(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
containerCount := -1
|
||||
containers, err := s.containerRepo.ListAll()
|
||||
containers, err := s.containerRepo.ListAll(r.Context())
|
||||
if err == nil {
|
||||
containerCount = len(containers)
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func (s *ToolboxLogService) Scan(w http.ResponseWriter, r *http.Request) {
|
||||
case "mysql":
|
||||
items = s.scanMySQLLogs()
|
||||
case "docker":
|
||||
items = s.scanDockerLogs()
|
||||
items = s.scanDockerLogs(r.Context())
|
||||
case "system":
|
||||
items = s.scanSystemLogs(r.Context())
|
||||
default:
|
||||
@@ -237,11 +237,11 @@ func (s *ToolboxLogService) scanMySQLLogs() []LogItem {
|
||||
}
|
||||
|
||||
// scanDockerLogs 扫描 Docker/Podman 相关内容
|
||||
func (s *ToolboxLogService) scanDockerLogs() []LogItem {
|
||||
func (s *ToolboxLogService) scanDockerLogs(ctx context.Context) []LogItem {
|
||||
items := make([]LogItem, 0)
|
||||
|
||||
// 未使用的容器镜像 (Docker)
|
||||
images, err := s.containerImageRepo.List()
|
||||
images, err := s.containerImageRepo.List(ctx)
|
||||
if err == nil {
|
||||
// 计算未使用的镜像
|
||||
var unusedCount int
|
||||
@@ -532,7 +532,7 @@ func (s *ToolboxLogService) cleanDockerLogs(ctx context.Context) int64 {
|
||||
var cleaned int64
|
||||
|
||||
// 清理未使用的镜像 (Docker)
|
||||
_ = s.containerImageRepo.Prune()
|
||||
_ = s.containerImageRepo.Prune(ctx)
|
||||
|
||||
// 清理 Docker 容器日志
|
||||
dockerLogPath := "/var/lib/docker/containers"
|
||||
|
||||
+33
-37
@@ -32,7 +32,7 @@ func NewClickHouse(ctx context.Context, username, password, address string) (*Cl
|
||||
}
|
||||
|
||||
// 测试连接
|
||||
if err := ch.ping(ctx); err != nil {
|
||||
if err := ch.Ping(ctx); err != nil {
|
||||
_ = client.Close()
|
||||
return nil, fmt.Errorf("connect to clickhouse failed: %w", err)
|
||||
}
|
||||
@@ -44,12 +44,7 @@ func (r *ClickHouse) Close() {
|
||||
_ = r.client.Close()
|
||||
}
|
||||
|
||||
func (r *ClickHouse) Ping() error {
|
||||
return r.ping(context.Background())
|
||||
}
|
||||
|
||||
// ping 带 context 的连通性检查,供构造时使用
|
||||
func (r *ClickHouse) ping(ctx context.Context) error {
|
||||
func (r *ClickHouse) Ping(ctx context.Context) error {
|
||||
resp, err := r.client.R().
|
||||
SetContext(ctx).
|
||||
SetQueryParam("user", r.username).
|
||||
@@ -66,45 +61,45 @@ func (r *ClickHouse) ping(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ClickHouse) Query(query string, args ...any) (*sql.Rows, error) {
|
||||
func (r *ClickHouse) Query(ctx context.Context, query string, args ...any) (*sql.Rows, error) {
|
||||
return nil, errors.New("clickhouse HTTP API does not support sql.Rows")
|
||||
}
|
||||
|
||||
func (r *ClickHouse) QueryRow(query string, args ...any) *sql.Row {
|
||||
func (r *ClickHouse) QueryRow(ctx context.Context, query string, args ...any) *sql.Row {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ClickHouse) Exec(query string, args ...any) (sql.Result, error) {
|
||||
_, err := r.exec(query)
|
||||
func (r *ClickHouse) Exec(ctx context.Context, query string, args ...any) (sql.Result, error) {
|
||||
_, err := r.exec(ctx, query)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (r *ClickHouse) Prepare(query string) (*sql.Stmt, error) {
|
||||
func (r *ClickHouse) Prepare(ctx context.Context, query string) (*sql.Stmt, error) {
|
||||
return nil, errors.New("clickhouse HTTP API does not support Prepare")
|
||||
}
|
||||
|
||||
func (r *ClickHouse) DatabaseCreate(name string) error {
|
||||
func (r *ClickHouse) DatabaseCreate(ctx context.Context, name string) error {
|
||||
name = strings.ReplaceAll(name, "`", "``")
|
||||
_, err := r.exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", name))
|
||||
_, err := r.exec(ctx, fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", name))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *ClickHouse) DatabaseDrop(name string) error {
|
||||
func (r *ClickHouse) DatabaseDrop(ctx context.Context, name string) error {
|
||||
name = strings.ReplaceAll(name, "`", "``")
|
||||
_, err := r.exec(fmt.Sprintf("DROP DATABASE IF EXISTS `%s`", name))
|
||||
_, err := r.exec(ctx, fmt.Sprintf("DROP DATABASE IF EXISTS `%s`", name))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *ClickHouse) DatabaseExists(name string) (bool, error) {
|
||||
result, err := r.exec(fmt.Sprintf("SELECT count() FROM system.databases WHERE name = '%s'", name))
|
||||
func (r *ClickHouse) DatabaseExists(ctx context.Context, name string) (bool, error) {
|
||||
result, err := r.exec(ctx, fmt.Sprintf("SELECT count() FROM system.databases WHERE name = '%s'", name))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return strings.TrimSpace(result) != "0", nil
|
||||
}
|
||||
|
||||
func (r *ClickHouse) DatabaseSize(name string) (int64, error) {
|
||||
result, err := r.exec(fmt.Sprintf("SELECT COALESCE(sum(bytes_on_disk), 0) FROM system.parts WHERE database = '%s'", name))
|
||||
func (r *ClickHouse) DatabaseSize(ctx context.Context, name string) (int64, error) {
|
||||
result, err := r.exec(ctx, fmt.Sprintf("SELECT COALESCE(sum(bytes_on_disk), 0) FROM system.parts WHERE database = '%s'", name))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -115,27 +110,27 @@ func (r *ClickHouse) DatabaseSize(name string) (int64, error) {
|
||||
return size, nil
|
||||
}
|
||||
|
||||
func (r *ClickHouse) UserCreate(user, password string, host ...string) error {
|
||||
func (r *ClickHouse) UserCreate(ctx context.Context, user, password string, host ...string) error {
|
||||
user = strings.ReplaceAll(user, "`", "``")
|
||||
_, err := r.exec(fmt.Sprintf("CREATE USER IF NOT EXISTS `%s` IDENTIFIED BY '%s'", user, password))
|
||||
_, err := r.exec(ctx, fmt.Sprintf("CREATE USER IF NOT EXISTS `%s` IDENTIFIED BY '%s'", user, password))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *ClickHouse) UserDrop(user string, host ...string) error {
|
||||
func (r *ClickHouse) UserDrop(ctx context.Context, user string, host ...string) error {
|
||||
user = strings.ReplaceAll(user, "`", "``")
|
||||
_, err := r.exec(fmt.Sprintf("DROP USER IF EXISTS `%s`", user))
|
||||
_, err := r.exec(ctx, fmt.Sprintf("DROP USER IF EXISTS `%s`", user))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *ClickHouse) UserPassword(user, password string, host ...string) error {
|
||||
func (r *ClickHouse) UserPassword(ctx context.Context, user, password string, host ...string) error {
|
||||
user = strings.ReplaceAll(user, "`", "``")
|
||||
_, err := r.exec(fmt.Sprintf("ALTER USER `%s` IDENTIFIED BY '%s'", user, password))
|
||||
_, err := r.exec(ctx, fmt.Sprintf("ALTER USER `%s` IDENTIFIED BY '%s'", user, password))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *ClickHouse) UserPrivileges(user string, host ...string) ([]string, error) {
|
||||
func (r *ClickHouse) UserPrivileges(ctx context.Context, user string, host ...string) ([]string, error) {
|
||||
user = strings.ReplaceAll(user, "`", "``")
|
||||
result, err := r.exec(fmt.Sprintf("SHOW GRANTS FOR `%s`", user))
|
||||
result, err := r.exec(ctx, fmt.Sprintf("SHOW GRANTS FOR `%s`", user))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -161,22 +156,22 @@ func (r *ClickHouse) UserPrivileges(user string, host ...string) ([]string, erro
|
||||
return databases, nil
|
||||
}
|
||||
|
||||
func (r *ClickHouse) PrivilegesGrant(user, database string, host ...string) error {
|
||||
func (r *ClickHouse) PrivilegesGrant(ctx context.Context, user, database string, host ...string) error {
|
||||
user = strings.ReplaceAll(user, "`", "``")
|
||||
database = strings.ReplaceAll(database, "`", "``")
|
||||
_, err := r.exec(fmt.Sprintf("GRANT ALL ON `%s`.* TO `%s`", database, user))
|
||||
_, err := r.exec(ctx, fmt.Sprintf("GRANT ALL ON `%s`.* TO `%s`", database, user))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *ClickHouse) PrivilegesRevoke(user, database string, host ...string) error {
|
||||
func (r *ClickHouse) PrivilegesRevoke(ctx context.Context, user, database string, host ...string) error {
|
||||
user = strings.ReplaceAll(user, "`", "``")
|
||||
database = strings.ReplaceAll(database, "`", "``")
|
||||
_, err := r.exec(fmt.Sprintf("REVOKE ALL ON `%s`.* FROM `%s`", database, user))
|
||||
_, err := r.exec(ctx, fmt.Sprintf("REVOKE ALL ON `%s`.* FROM `%s`", database, user))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *ClickHouse) Users() ([]User, error) {
|
||||
result, err := r.exec("SELECT name FROM system.users FORMAT TabSeparated")
|
||||
func (r *ClickHouse) Users(ctx context.Context) ([]User, error) {
|
||||
result, err := r.exec(ctx, "SELECT name FROM system.users FORMAT TabSeparated")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -193,8 +188,8 @@ func (r *ClickHouse) Users() ([]User, error) {
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (r *ClickHouse) Databases() ([]Database, error) {
|
||||
result, err := r.exec("SELECT name FROM system.databases WHERE name NOT IN ('system', 'INFORMATION_SCHEMA', 'information_schema') FORMAT TabSeparated")
|
||||
func (r *ClickHouse) Databases(ctx context.Context) ([]Database, error) {
|
||||
result, err := r.exec(ctx, "SELECT name FROM system.databases WHERE name NOT IN ('system', 'INFORMATION_SCHEMA', 'information_schema') FORMAT TabSeparated")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -212,8 +207,9 @@ func (r *ClickHouse) Databases() ([]Database, error) {
|
||||
}
|
||||
|
||||
// exec 通过 HTTP API 执行 SQL
|
||||
func (r *ClickHouse) exec(query string) (string, error) {
|
||||
func (r *ClickHouse) exec(ctx context.Context, query string) (string, error) {
|
||||
resp, err := r.client.R().
|
||||
SetContext(ctx).
|
||||
SetQueryParam("user", r.username).
|
||||
SetQueryParam("password", r.password).
|
||||
SetBody(query).
|
||||
|
||||
+21
-18
@@ -1,29 +1,32 @@
|
||||
package db
|
||||
|
||||
import "database/sql"
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
type Operator interface {
|
||||
Close()
|
||||
Ping() error
|
||||
Ping(ctx context.Context) error
|
||||
|
||||
Query(query string, args ...any) (*sql.Rows, error)
|
||||
QueryRow(query string, args ...any) *sql.Row
|
||||
Exec(query string, args ...any) (sql.Result, error)
|
||||
Prepare(query string) (*sql.Stmt, error)
|
||||
Query(ctx context.Context, query string, args ...any) (*sql.Rows, error)
|
||||
QueryRow(ctx context.Context, query string, args ...any) *sql.Row
|
||||
Exec(ctx context.Context, query string, args ...any) (sql.Result, error)
|
||||
Prepare(ctx context.Context, query string) (*sql.Stmt, error)
|
||||
|
||||
DatabaseCreate(name string) error
|
||||
DatabaseDrop(name string) error
|
||||
DatabaseExists(name string) (bool, error)
|
||||
DatabaseSize(name string) (int64, error)
|
||||
DatabaseCreate(ctx context.Context, name string) error
|
||||
DatabaseDrop(ctx context.Context, name string) error
|
||||
DatabaseExists(ctx context.Context, name string) (bool, error)
|
||||
DatabaseSize(ctx context.Context, name string) (int64, error)
|
||||
|
||||
UserCreate(user, password string, host ...string) error
|
||||
UserDrop(user string, host ...string) error
|
||||
UserPassword(user, password string, host ...string) error
|
||||
UserPrivileges(user string, host ...string) ([]string, error)
|
||||
UserCreate(ctx context.Context, user, password string, host ...string) error
|
||||
UserDrop(ctx context.Context, user string, host ...string) error
|
||||
UserPassword(ctx context.Context, user, password string, host ...string) error
|
||||
UserPrivileges(ctx context.Context, user string, host ...string) ([]string, error)
|
||||
|
||||
PrivilegesGrant(user, database string, host ...string) error
|
||||
PrivilegesRevoke(user, database string, host ...string) error
|
||||
PrivilegesGrant(ctx context.Context, user, database string, host ...string) error
|
||||
PrivilegesRevoke(ctx context.Context, user, database string, host ...string) error
|
||||
|
||||
Users() ([]User, error)
|
||||
Databases() ([]Database, error)
|
||||
Users(ctx context.Context) ([]User, error)
|
||||
Databases(ctx context.Context) ([]Database, error)
|
||||
}
|
||||
|
||||
+18
-18
@@ -40,7 +40,7 @@ func NewElasticsearch(ctx context.Context, address, username, password string) (
|
||||
}
|
||||
|
||||
es := &Elasticsearch{client: client}
|
||||
if err := es.ping(ctx); err != nil {
|
||||
if err := es.Ping(ctx); err != nil {
|
||||
_ = client.Close()
|
||||
return nil, fmt.Errorf("connect to elasticsearch failed: %w", err)
|
||||
}
|
||||
@@ -52,12 +52,7 @@ func (r *Elasticsearch) Close() {
|
||||
_ = r.client.Close()
|
||||
}
|
||||
|
||||
func (r *Elasticsearch) Ping() error {
|
||||
return r.ping(context.Background())
|
||||
}
|
||||
|
||||
// ping 带 context 的连通性检查,供构造时使用
|
||||
func (r *Elasticsearch) ping(ctx context.Context) error {
|
||||
func (r *Elasticsearch) Ping(ctx context.Context) error {
|
||||
resp, err := r.client.R().SetContext(ctx).Get("/")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -70,8 +65,8 @@ func (r *Elasticsearch) ping(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// Indices 获取所有索引
|
||||
func (r *Elasticsearch) Indices() ([]ESIndex, error) {
|
||||
resp, err := r.client.R().Get("/_cat/indices?format=json&h=index,health,status,docs.count,store.size")
|
||||
func (r *Elasticsearch) Indices(ctx context.Context) ([]ESIndex, error) {
|
||||
resp, err := r.client.R().SetContext(ctx).Get("/_cat/indices?format=json&h=index,health,status,docs.count,store.size")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get indices: %w", err)
|
||||
}
|
||||
@@ -109,8 +104,9 @@ func (r *Elasticsearch) Indices() ([]ESIndex, error) {
|
||||
}
|
||||
|
||||
// IndexCreate 创建索引
|
||||
func (r *Elasticsearch) IndexCreate(name string) error {
|
||||
func (r *Elasticsearch) IndexCreate(ctx context.Context, name string) error {
|
||||
resp, err := r.client.R().
|
||||
SetContext(ctx).
|
||||
SetHeader("Content-Type", "application/json").
|
||||
Put("/" + name)
|
||||
if err != nil {
|
||||
@@ -123,8 +119,8 @@ func (r *Elasticsearch) IndexCreate(name string) error {
|
||||
}
|
||||
|
||||
// IndexDelete 删除索引
|
||||
func (r *Elasticsearch) IndexDelete(name string) error {
|
||||
resp, err := r.client.R().Delete("/" + name)
|
||||
func (r *Elasticsearch) IndexDelete(ctx context.Context, name string) error {
|
||||
resp, err := r.client.R().SetContext(ctx).Delete("/" + name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete index: %w", err)
|
||||
}
|
||||
@@ -135,7 +131,7 @@ func (r *Elasticsearch) IndexDelete(name string) error {
|
||||
}
|
||||
|
||||
// Search 搜索文档
|
||||
func (r *Elasticsearch) Search(index, query string, page, pageSize int) ([]ESDocument, int64, error) {
|
||||
func (r *Elasticsearch) Search(ctx context.Context, index, query string, page, pageSize int) ([]ESDocument, int64, error) {
|
||||
from := (page - 1) * pageSize
|
||||
body := map[string]any{
|
||||
"from": from,
|
||||
@@ -150,6 +146,7 @@ func (r *Elasticsearch) Search(index, query string, page, pageSize int) ([]ESDoc
|
||||
}
|
||||
|
||||
resp, err := r.client.R().
|
||||
SetContext(ctx).
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetBody(body).
|
||||
Post("/" + index + "/_search")
|
||||
@@ -189,8 +186,8 @@ func (r *Elasticsearch) Search(index, query string, page, pageSize int) ([]ESDoc
|
||||
}
|
||||
|
||||
// DocumentGet 获取文档
|
||||
func (r *Elasticsearch) DocumentGet(index, id string) (*ESDocument, error) {
|
||||
resp, err := r.client.R().Get("/" + index + "/_doc/" + id)
|
||||
func (r *Elasticsearch) DocumentGet(ctx context.Context, index, id string) (*ESDocument, error) {
|
||||
resp, err := r.client.R().SetContext(ctx).Get("/" + index + "/_doc/" + id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get document: %w", err)
|
||||
}
|
||||
@@ -215,8 +212,9 @@ func (r *Elasticsearch) DocumentGet(index, id string) (*ESDocument, error) {
|
||||
}
|
||||
|
||||
// DocumentCreate 创建文档(自动生成 ID)
|
||||
func (r *Elasticsearch) DocumentCreate(index, body string) error {
|
||||
func (r *Elasticsearch) DocumentCreate(ctx context.Context, index, body string) error {
|
||||
resp, err := r.client.R().
|
||||
SetContext(ctx).
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetQueryParam("refresh", "true").
|
||||
SetBody(body).
|
||||
@@ -231,8 +229,9 @@ func (r *Elasticsearch) DocumentCreate(index, body string) error {
|
||||
}
|
||||
|
||||
// DocumentUpdate 更新文档
|
||||
func (r *Elasticsearch) DocumentUpdate(index, id, body string) error {
|
||||
func (r *Elasticsearch) DocumentUpdate(ctx context.Context, index, id, body string) error {
|
||||
resp, err := r.client.R().
|
||||
SetContext(ctx).
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetQueryParam("refresh", "true").
|
||||
SetBody(body).
|
||||
@@ -247,8 +246,9 @@ func (r *Elasticsearch) DocumentUpdate(index, id, body string) error {
|
||||
}
|
||||
|
||||
// DocumentDelete 删除文档
|
||||
func (r *Elasticsearch) DocumentDelete(index, id string) error {
|
||||
func (r *Elasticsearch) DocumentDelete(ctx context.Context, index, id string) error {
|
||||
resp, err := r.client.R().
|
||||
SetContext(ctx).
|
||||
SetQueryParam("refresh", "true").
|
||||
Delete("/" + index + "/_doc/" + id)
|
||||
if err != nil {
|
||||
|
||||
+19
-29
@@ -24,7 +24,7 @@ func NewMongoDB(ctx context.Context, username, password, address string) (*Mongo
|
||||
address: address,
|
||||
}
|
||||
|
||||
if err := m.ping(ctx); err != nil {
|
||||
if err := m.Ping(ctx); err != nil {
|
||||
return nil, fmt.Errorf("connect to mongodb failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -33,31 +33,26 @@ func NewMongoDB(ctx context.Context, username, password, address string) (*Mongo
|
||||
|
||||
func (r *MongoDB) Close() {}
|
||||
|
||||
func (r *MongoDB) Ping() error {
|
||||
return r.ping(context.Background())
|
||||
}
|
||||
|
||||
// ping 带 context 的连通性检查,供构造时使用
|
||||
func (r *MongoDB) ping(ctx context.Context) error {
|
||||
_, err := r.mongoshContext(ctx, `db.runCommand({ping:1})`)
|
||||
func (r *MongoDB) Ping(ctx context.Context) error {
|
||||
_, err := r.mongosh(ctx, `db.runCommand({ping:1})`)
|
||||
return err
|
||||
}
|
||||
|
||||
// DatabaseCreate 创建数据库(MongoDB 通过创建集合来显式创建数据库)
|
||||
func (r *MongoDB) DatabaseCreate(name string) error {
|
||||
_, err := r.mongosh(fmt.Sprintf(`db.getSiblingDB('%s').createCollection('_init')`, name))
|
||||
func (r *MongoDB) DatabaseCreate(ctx context.Context, name string) error {
|
||||
_, err := r.mongosh(ctx, fmt.Sprintf(`db.getSiblingDB('%s').createCollection('_init')`, name))
|
||||
return err
|
||||
}
|
||||
|
||||
// DatabaseDrop 删除数据库
|
||||
func (r *MongoDB) DatabaseDrop(name string) error {
|
||||
_, err := r.mongosh(fmt.Sprintf(`db.getSiblingDB('%s').dropDatabase()`, name))
|
||||
func (r *MongoDB) DatabaseDrop(ctx context.Context, name string) error {
|
||||
_, err := r.mongosh(ctx, fmt.Sprintf(`db.getSiblingDB('%s').dropDatabase()`, name))
|
||||
return err
|
||||
}
|
||||
|
||||
// Databases 获取数据库列表
|
||||
func (r *MongoDB) Databases() ([]MongoDatabase, error) {
|
||||
raw, err := r.mongosh(`JSON.stringify(db.adminCommand({listDatabases:1,nameOnly:false}))`)
|
||||
func (r *MongoDB) Databases(ctx context.Context) ([]MongoDatabase, error) {
|
||||
raw, err := r.mongosh(ctx, `JSON.stringify(db.adminCommand({listDatabases:1,nameOnly:false}))`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -101,26 +96,26 @@ func mongoLongToInt64(v any) int64 {
|
||||
}
|
||||
|
||||
// UserCreate 创建用户
|
||||
func (r *MongoDB) UserCreate(user, password, database string) error {
|
||||
_, err := r.mongosh(fmt.Sprintf(`db.getSiblingDB('%s').createUser({user:'%s',pwd:'%s',roles:[{role:'readWrite',db:'%s'}]})`, database, user, password, database))
|
||||
func (r *MongoDB) UserCreate(ctx context.Context, user, password, database string) error {
|
||||
_, err := r.mongosh(ctx, fmt.Sprintf(`db.getSiblingDB('%s').createUser({user:'%s',pwd:'%s',roles:[{role:'readWrite',db:'%s'}]})`, database, user, password, database))
|
||||
return err
|
||||
}
|
||||
|
||||
// UserDrop 删除用户
|
||||
func (r *MongoDB) UserDrop(user, database string) error {
|
||||
_, err := r.mongosh(fmt.Sprintf(`db.getSiblingDB('%s').dropUser('%s')`, database, user))
|
||||
func (r *MongoDB) UserDrop(ctx context.Context, user, database string) error {
|
||||
_, err := r.mongosh(ctx, fmt.Sprintf(`db.getSiblingDB('%s').dropUser('%s')`, database, user))
|
||||
return err
|
||||
}
|
||||
|
||||
// UserPassword 修改用户密码
|
||||
func (r *MongoDB) UserPassword(user, password string) error {
|
||||
_, err := r.mongosh(fmt.Sprintf(`db.getSiblingDB('admin').changeUserPassword('%s','%s')`, user, password))
|
||||
func (r *MongoDB) UserPassword(ctx context.Context, user, password string) error {
|
||||
_, err := r.mongosh(ctx, fmt.Sprintf(`db.getSiblingDB('admin').changeUserPassword('%s','%s')`, user, password))
|
||||
return err
|
||||
}
|
||||
|
||||
// Users 获取用户列表
|
||||
func (r *MongoDB) Users() ([]MongoUser, error) {
|
||||
raw, err := r.mongosh(`JSON.stringify(db.getSiblingDB('admin').system.users.find({},{user:1,db:1,roles:1}).toArray())`)
|
||||
func (r *MongoDB) Users(ctx context.Context) ([]MongoUser, error) {
|
||||
raw, err := r.mongosh(ctx, `JSON.stringify(db.getSiblingDB('admin').system.users.find({},{user:1,db:1,roles:1}).toArray())`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -153,13 +148,8 @@ func (r *MongoDB) Users() ([]MongoUser, error) {
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// mongosh 执行 mongosh 命令
|
||||
func (r *MongoDB) mongosh(eval string) (string, error) {
|
||||
return r.mongoshContext(context.Background(), eval)
|
||||
}
|
||||
|
||||
// mongoshContext 执行 mongosh 命令,ctx 取消时终止进程
|
||||
func (r *MongoDB) mongoshContext(ctx context.Context, eval string) (string, error) {
|
||||
// mongosh 执行 mongosh 命令,ctx 取消时终止进程
|
||||
func (r *MongoDB) mongosh(ctx context.Context, eval string) (string, error) {
|
||||
// serverSelectionTimeoutMS 限制建连耗时,避免不可达地址长时间挂起
|
||||
cmd := fmt.Sprintf(`mongosh --quiet --eval "%s" "mongodb://%s:%s@%s/admin?serverSelectionTimeoutMS=10000" 2>/dev/null`,
|
||||
strings.ReplaceAll(eval, `"`, `\"`),
|
||||
|
||||
+47
-46
@@ -44,42 +44,42 @@ func (r *MySQL) Close() {
|
||||
_ = r.db.Close()
|
||||
}
|
||||
|
||||
func (r *MySQL) Ping() error {
|
||||
return r.db.PingContext(context.Background())
|
||||
func (r *MySQL) Ping(ctx context.Context) error {
|
||||
return r.db.PingContext(ctx)
|
||||
}
|
||||
|
||||
func (r *MySQL) Query(query string, args ...any) (*sql.Rows, error) {
|
||||
return r.db.QueryContext(context.Background(), query, args...)
|
||||
func (r *MySQL) Query(ctx context.Context, query string, args ...any) (*sql.Rows, error) {
|
||||
return r.db.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (r *MySQL) QueryRow(query string, args ...any) *sql.Row {
|
||||
return r.db.QueryRowContext(context.Background(), query, args...)
|
||||
func (r *MySQL) QueryRow(ctx context.Context, query string, args ...any) *sql.Row {
|
||||
return r.db.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (r *MySQL) Exec(query string, args ...any) (sql.Result, error) {
|
||||
return r.db.ExecContext(context.Background(), query, args...)
|
||||
func (r *MySQL) Exec(ctx context.Context, query string, args ...any) (sql.Result, error) {
|
||||
return r.db.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (r *MySQL) Prepare(query string) (*sql.Stmt, error) {
|
||||
return r.db.PrepareContext(context.Background(), query)
|
||||
func (r *MySQL) Prepare(ctx context.Context, query string) (*sql.Stmt, error) {
|
||||
return r.db.PrepareContext(ctx, query)
|
||||
}
|
||||
|
||||
func (r *MySQL) DatabaseCreate(name string) error {
|
||||
func (r *MySQL) DatabaseCreate(ctx context.Context, name string) error {
|
||||
name = strings.ReplaceAll(name, "`", "``")
|
||||
_, err := r.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", name))
|
||||
r.flushPrivileges()
|
||||
_, err := r.Exec(ctx, fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", name))
|
||||
r.flushPrivileges(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *MySQL) DatabaseDrop(name string) error {
|
||||
func (r *MySQL) DatabaseDrop(ctx context.Context, name string) error {
|
||||
name = strings.ReplaceAll(name, "`", "``")
|
||||
_, err := r.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS `%s`", name))
|
||||
r.flushPrivileges()
|
||||
_, err := r.Exec(ctx, fmt.Sprintf("DROP DATABASE IF EXISTS `%s`", name))
|
||||
r.flushPrivileges(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *MySQL) DatabaseExists(name string) (bool, error) {
|
||||
rows, err := r.Query("SHOW DATABASES")
|
||||
func (r *MySQL) DatabaseExists(ctx context.Context, name string) (bool, error) {
|
||||
rows, err := r.Query(ctx, "SHOW DATABASES")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -97,45 +97,45 @@ func (r *MySQL) DatabaseExists(name string) (bool, error) {
|
||||
return false, rows.Err()
|
||||
}
|
||||
|
||||
func (r *MySQL) DatabaseSize(name string) (int64, error) {
|
||||
func (r *MySQL) DatabaseSize(ctx context.Context, name string) (int64, error) {
|
||||
var size int64
|
||||
err := r.QueryRow("SELECT COALESCE(SUM(data_length) + SUM(index_length), 0) FROM information_schema.tables WHERE table_schema = ?", name).Scan(&size)
|
||||
err := r.QueryRow(ctx, "SELECT COALESCE(SUM(data_length) + SUM(index_length), 0) FROM information_schema.tables WHERE table_schema = ?", name).Scan(&size)
|
||||
return size, err
|
||||
}
|
||||
|
||||
func (r *MySQL) UserCreate(user, password string, host ...string) error {
|
||||
func (r *MySQL) UserCreate(ctx context.Context, user, password string, host ...string) error {
|
||||
if len(host) == 0 || host[0] == "" {
|
||||
host = []string{"%"}
|
||||
}
|
||||
_, err := r.Exec(fmt.Sprintf("CREATE USER IF NOT EXISTS '%s'@'%s' IDENTIFIED BY '%s'", user, host[0], password))
|
||||
r.flushPrivileges()
|
||||
_, err := r.Exec(ctx, fmt.Sprintf("CREATE USER IF NOT EXISTS '%s'@'%s' IDENTIFIED BY '%s'", user, host[0], password))
|
||||
r.flushPrivileges(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *MySQL) UserDrop(user string, host ...string) error {
|
||||
func (r *MySQL) UserDrop(ctx context.Context, user string, host ...string) error {
|
||||
if len(host) == 0 || host[0] == "" {
|
||||
host = []string{"%"}
|
||||
}
|
||||
_, err := r.Exec(fmt.Sprintf("DROP USER IF EXISTS '%s'@'%s'", user, host[0]))
|
||||
r.flushPrivileges()
|
||||
_, err := r.Exec(ctx, fmt.Sprintf("DROP USER IF EXISTS '%s'@'%s'", user, host[0]))
|
||||
r.flushPrivileges(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *MySQL) UserPassword(user, password string, host ...string) error {
|
||||
func (r *MySQL) UserPassword(ctx context.Context, user, password string, host ...string) error {
|
||||
if len(host) == 0 || host[0] == "" {
|
||||
host = []string{"%"}
|
||||
}
|
||||
_, err := r.Exec(fmt.Sprintf("ALTER USER '%s'@'%s' IDENTIFIED BY '%s'", user, host[0], password))
|
||||
r.flushPrivileges()
|
||||
_, err := r.Exec(ctx, fmt.Sprintf("ALTER USER '%s'@'%s' IDENTIFIED BY '%s'", user, host[0], password))
|
||||
r.flushPrivileges(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *MySQL) UserPrivileges(user string, host ...string) ([]string, error) {
|
||||
func (r *MySQL) UserPrivileges(ctx context.Context, user string, host ...string) ([]string, error) {
|
||||
if len(host) == 0 || host[0] == "" {
|
||||
host = []string{"%"}
|
||||
}
|
||||
|
||||
rows, err := r.Query(fmt.Sprintf("SHOW GRANTS FOR '%s'@'%s'", user, host[0]))
|
||||
rows, err := r.Query(ctx, fmt.Sprintf("SHOW GRANTS FOR '%s'@'%s'", user, host[0]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -167,28 +167,28 @@ func (r *MySQL) UserPrivileges(user string, host ...string) ([]string, error) {
|
||||
return slices.Compact(databases), nil
|
||||
}
|
||||
|
||||
func (r *MySQL) PrivilegesGrant(user, database string, host ...string) error {
|
||||
func (r *MySQL) PrivilegesGrant(ctx context.Context, user, database string, host ...string) error {
|
||||
if len(host) == 0 || host[0] == "" {
|
||||
host = []string{"%"}
|
||||
}
|
||||
database = strings.ReplaceAll(database, "`", "``")
|
||||
_, err := r.Exec(fmt.Sprintf("GRANT ALL PRIVILEGES ON `%s`.* TO '%s'@'%s'", database, user, host[0]))
|
||||
r.flushPrivileges()
|
||||
_, err := r.Exec(ctx, fmt.Sprintf("GRANT ALL PRIVILEGES ON `%s`.* TO '%s'@'%s'", database, user, host[0]))
|
||||
r.flushPrivileges(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *MySQL) PrivilegesRevoke(user, database string, host ...string) error {
|
||||
func (r *MySQL) PrivilegesRevoke(ctx context.Context, user, database string, host ...string) error {
|
||||
if len(host) == 0 || host[0] == "" {
|
||||
host = []string{"%"}
|
||||
}
|
||||
database = strings.ReplaceAll(database, "`", "``")
|
||||
_, err := r.Exec(fmt.Sprintf("REVOKE ALL PRIVILEGES ON `%s`.* FROM '%s'@'%s'", database, user, host[0]))
|
||||
r.flushPrivileges()
|
||||
_, err := r.Exec(ctx, fmt.Sprintf("REVOKE ALL PRIVILEGES ON `%s`.* FROM '%s'@'%s'", database, user, host[0]))
|
||||
r.flushPrivileges(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *MySQL) Users() ([]User, error) {
|
||||
rows, err := r.Query("SELECT user, host FROM mysql.user")
|
||||
func (r *MySQL) Users(ctx context.Context) ([]User, error) {
|
||||
rows, err := r.Query(ctx, "SELECT user, host FROM mysql.user")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -200,7 +200,7 @@ func (r *MySQL) Users() ([]User, error) {
|
||||
if err := rows.Scan(&user, &host); err != nil {
|
||||
continue
|
||||
}
|
||||
grants, err := r.userGrants(user, host)
|
||||
grants, err := r.userGrants(ctx, user, host)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
@@ -215,7 +215,7 @@ func (r *MySQL) Users() ([]User, error) {
|
||||
return users, rows.Err()
|
||||
}
|
||||
|
||||
func (r *MySQL) Databases() ([]Database, error) {
|
||||
func (r *MySQL) Databases(ctx context.Context) ([]Database, error) {
|
||||
query := `
|
||||
SELECT
|
||||
SCHEMA_NAME,
|
||||
@@ -225,7 +225,7 @@ func (r *MySQL) Databases() ([]Database, error) {
|
||||
WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys')
|
||||
`
|
||||
|
||||
rows, err := r.Query(query)
|
||||
rows, err := r.Query(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -247,8 +247,8 @@ func (r *MySQL) Databases() ([]Database, error) {
|
||||
return databases, nil
|
||||
}
|
||||
|
||||
func (r *MySQL) userGrants(user, host string) ([]string, error) {
|
||||
rows, err := r.Query(fmt.Sprintf("SHOW GRANTS FOR '%s'@'%s'", user, host))
|
||||
func (r *MySQL) userGrants(ctx context.Context, user, host string) ([]string, error) {
|
||||
rows, err := r.Query(ctx, fmt.Sprintf("SHOW GRANTS FOR '%s'@'%s'", user, host))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -265,6 +265,7 @@ func (r *MySQL) userGrants(user, host string) ([]string, error) {
|
||||
return grants, rows.Err()
|
||||
}
|
||||
|
||||
func (r *MySQL) flushPrivileges() {
|
||||
_, _ = r.Exec("FLUSH PRIVILEGES")
|
||||
func (r *MySQL) flushPrivileges(ctx context.Context) {
|
||||
// 权限变更后必须刷新,取消时跳过会让新用户或授权不生效
|
||||
_, _ = r.Exec(context.WithoutCancel(ctx), "FLUSH PRIVILEGES")
|
||||
}
|
||||
|
||||
+44
-40
@@ -54,29 +54,29 @@ func (r *Postgres) Close() {
|
||||
_ = r.db.Close()
|
||||
}
|
||||
|
||||
func (r *Postgres) Ping() error {
|
||||
return r.db.PingContext(context.Background())
|
||||
func (r *Postgres) Ping(ctx context.Context) error {
|
||||
return r.db.PingContext(ctx)
|
||||
}
|
||||
|
||||
func (r *Postgres) Query(query string, args ...any) (*sql.Rows, error) {
|
||||
return r.db.QueryContext(context.Background(), query, args...)
|
||||
func (r *Postgres) Query(ctx context.Context, query string, args ...any) (*sql.Rows, error) {
|
||||
return r.db.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (r *Postgres) QueryRow(query string, args ...any) *sql.Row {
|
||||
return r.db.QueryRowContext(context.Background(), query, args...)
|
||||
func (r *Postgres) QueryRow(ctx context.Context, query string, args ...any) *sql.Row {
|
||||
return r.db.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (r *Postgres) Exec(query string, args ...any) (sql.Result, error) {
|
||||
return r.db.ExecContext(context.Background(), query, args...)
|
||||
func (r *Postgres) Exec(ctx context.Context, query string, args ...any) (sql.Result, error) {
|
||||
return r.db.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (r *Postgres) Prepare(query string) (*sql.Stmt, error) {
|
||||
return r.db.PrepareContext(context.Background(), query)
|
||||
func (r *Postgres) Prepare(ctx context.Context, query string) (*sql.Stmt, error) {
|
||||
return r.db.PrepareContext(ctx, query)
|
||||
}
|
||||
|
||||
func (r *Postgres) DatabaseCreate(name string) error {
|
||||
func (r *Postgres) DatabaseCreate(ctx context.Context, name string) error {
|
||||
// postgres 不支持 CREATE DATABASE IF NOT EXISTS,但是为了保持与 MySQL 一致,先检查数据库是否存在
|
||||
exist, err := r.DatabaseExists(name)
|
||||
exist, err := r.DatabaseExists(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -84,41 +84,41 @@ func (r *Postgres) DatabaseCreate(name string) error {
|
||||
return nil
|
||||
}
|
||||
name = strings.ReplaceAll(name, `"`, `""`)
|
||||
_, err = r.Exec(fmt.Sprintf(`CREATE DATABASE "%s"`, name))
|
||||
_, err = r.Exec(ctx, fmt.Sprintf(`CREATE DATABASE "%s"`, name))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Postgres) DatabaseDrop(name string) error {
|
||||
func (r *Postgres) DatabaseDrop(ctx context.Context, name string) error {
|
||||
name = strings.ReplaceAll(name, `"`, `""`)
|
||||
_, err := r.Exec(fmt.Sprintf(`DROP DATABASE IF EXISTS "%s"`, name))
|
||||
_, err := r.Exec(ctx, fmt.Sprintf(`DROP DATABASE IF EXISTS "%s"`, name))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Postgres) DatabaseExists(name string) (bool, error) {
|
||||
func (r *Postgres) DatabaseExists(ctx context.Context, name string) (bool, error) {
|
||||
var count int
|
||||
if err := r.QueryRow("SELECT COUNT(*) FROM pg_database WHERE datname = $1", name).Scan(&count); err != nil {
|
||||
if err := r.QueryRow(ctx, "SELECT COUNT(*) FROM pg_database WHERE datname = $1", name).Scan(&count); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
func (r *Postgres) DatabaseSize(name string) (int64, error) {
|
||||
func (r *Postgres) DatabaseSize(ctx context.Context, name string) (int64, error) {
|
||||
var size int64
|
||||
if err := r.QueryRow("SELECT pg_database_size($1)", name).Scan(&size); err != nil {
|
||||
if err := r.QueryRow(ctx, "SELECT pg_database_size($1)", name).Scan(&size); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return size, nil
|
||||
}
|
||||
|
||||
func (r *Postgres) DatabaseComment(name, comment string) error {
|
||||
func (r *Postgres) DatabaseComment(ctx context.Context, name, comment string) error {
|
||||
name = strings.ReplaceAll(name, `"`, `""`)
|
||||
_, err := r.Exec(fmt.Sprintf(`COMMENT ON DATABASE "%s" IS '%s'`, name, comment))
|
||||
_, err := r.Exec(ctx, fmt.Sprintf(`COMMENT ON DATABASE "%s" IS '%s'`, name, comment))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Postgres) UserCreate(user, password string, host ...string) error {
|
||||
func (r *Postgres) UserCreate(ctx context.Context, user, password string, host ...string) error {
|
||||
user = strings.ReplaceAll(user, `"`, `""`)
|
||||
_, err := r.Exec(fmt.Sprintf(`CREATE USER "%s" WITH PASSWORD '%s'`, user, password))
|
||||
_, err := r.Exec(ctx, fmt.Sprintf(`CREATE USER "%s" WITH PASSWORD '%s'`, user, password))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -126,18 +126,20 @@ func (r *Postgres) UserCreate(user, password string, host ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Postgres) UserDrop(user string, host ...string) error {
|
||||
func (r *Postgres) UserDrop(ctx context.Context, user string, host ...string) error {
|
||||
// PostgreSQL 中,如果用户拥有数据库对象或权限,直接 DROP USER 会失败
|
||||
// 必须先转移所有权并撤销权限
|
||||
// 三步是一个整体,中途取消会留下丢了所有权却没被删掉的用户
|
||||
ctx = context.WithoutCancel(ctx)
|
||||
user = strings.ReplaceAll(user, `"`, `""`)
|
||||
username := strings.ReplaceAll(r.username, `"`, `""`)
|
||||
if _, err := r.Exec(fmt.Sprintf(`REASSIGN OWNED BY "%s" TO "%s"`, user, username)); err != nil {
|
||||
if _, err := r.Exec(ctx, fmt.Sprintf(`REASSIGN OWNED BY "%s" TO "%s"`, user, username)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := r.Exec(fmt.Sprintf(`DROP OWNED BY "%s"`, user)); err != nil {
|
||||
if _, err := r.Exec(ctx, fmt.Sprintf(`DROP OWNED BY "%s"`, user)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := r.Exec(fmt.Sprintf(`DROP USER IF EXISTS "%s"`, user))
|
||||
_, err := r.Exec(ctx, fmt.Sprintf(`DROP USER IF EXISTS "%s"`, user))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -145,13 +147,13 @@ func (r *Postgres) UserDrop(user string, host ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Postgres) UserPassword(user, password string, host ...string) error {
|
||||
func (r *Postgres) UserPassword(ctx context.Context, user, password string, host ...string) error {
|
||||
user = strings.ReplaceAll(user, `"`, `""`)
|
||||
_, err := r.Exec(fmt.Sprintf(`ALTER USER "%s" WITH PASSWORD '%s'`, user, password))
|
||||
_, err := r.Exec(ctx, fmt.Sprintf(`ALTER USER "%s" WITH PASSWORD '%s'`, user, password))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Postgres) UserPrivileges(user string, host ...string) ([]string, error) {
|
||||
func (r *Postgres) UserPrivileges(ctx context.Context, user string, host ...string) ([]string, error) {
|
||||
query := `
|
||||
SELECT d.datname
|
||||
FROM pg_catalog.pg_database d
|
||||
@@ -162,7 +164,7 @@ func (r *Postgres) UserPrivileges(user string, host ...string) ([]string, error)
|
||||
ORDER BY d.datname;
|
||||
`
|
||||
|
||||
rows, err := r.Query(query, user)
|
||||
rows, err := r.Query(ctx, query, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -185,27 +187,29 @@ func (r *Postgres) UserPrivileges(user string, host ...string) ([]string, error)
|
||||
return databases, nil
|
||||
}
|
||||
|
||||
func (r *Postgres) PrivilegesGrant(user, database string, host ...string) error {
|
||||
func (r *Postgres) PrivilegesGrant(ctx context.Context, user, database string, host ...string) error {
|
||||
// 改属主和授权是一个整体,中途取消会留下换了属主却没有权限的库
|
||||
ctx = context.WithoutCancel(ctx)
|
||||
user = strings.ReplaceAll(user, `"`, `""`)
|
||||
database = strings.ReplaceAll(database, `"`, `""`)
|
||||
if _, err := r.Exec(fmt.Sprintf(`ALTER DATABASE "%s" OWNER TO "%s"`, database, user)); err != nil {
|
||||
if _, err := r.Exec(ctx, fmt.Sprintf(`ALTER DATABASE "%s" OWNER TO "%s"`, database, user)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := r.Exec(fmt.Sprintf(`GRANT ALL PRIVILEGES ON DATABASE "%s" TO "%s"`, database, user)); err != nil {
|
||||
if _, err := r.Exec(ctx, fmt.Sprintf(`GRANT ALL PRIVILEGES ON DATABASE "%s" TO "%s"`, database, user)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Postgres) PrivilegesRevoke(user, database string, host ...string) error {
|
||||
func (r *Postgres) PrivilegesRevoke(ctx context.Context, user, database string, host ...string) error {
|
||||
user = strings.ReplaceAll(user, `"`, `""`)
|
||||
database = strings.ReplaceAll(database, `"`, `""`)
|
||||
_, err := r.Exec(fmt.Sprintf(`REVOKE ALL PRIVILEGES ON DATABASE "%s" FROM "%s"`, database, user))
|
||||
_, err := r.Exec(ctx, fmt.Sprintf(`REVOKE ALL PRIVILEGES ON DATABASE "%s" FROM "%s"`, database, user))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Postgres) Users() ([]User, error) {
|
||||
func (r *Postgres) Users(ctx context.Context) ([]User, error) {
|
||||
query := `
|
||||
SELECT rolname,
|
||||
rolsuper,
|
||||
@@ -216,7 +220,7 @@ func (r *Postgres) Users() ([]User, error) {
|
||||
FROM pg_roles
|
||||
WHERE rolcanlogin = true;
|
||||
`
|
||||
rows, err := r.Query(query)
|
||||
rows, err := r.Query(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -257,7 +261,7 @@ func (r *Postgres) Users() ([]User, error) {
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (r *Postgres) Databases() ([]Database, error) {
|
||||
func (r *Postgres) Databases(ctx context.Context) ([]Database, error) {
|
||||
query := `
|
||||
SELECT
|
||||
d.datname,
|
||||
@@ -267,7 +271,7 @@ func (r *Postgres) Databases() ([]Database, error) {
|
||||
FROM pg_catalog.pg_database d
|
||||
WHERE datistemplate = false;
|
||||
`
|
||||
rows, err := r.Query(query)
|
||||
rows, err := r.Query(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+8
-8
@@ -15,12 +15,12 @@ type SQLite struct {
|
||||
}
|
||||
|
||||
// NewSQLite 打开 SQLite 数据库文件
|
||||
func NewSQLite(path string) (*SQLite, error) {
|
||||
func NewSQLite(ctx context.Context, path string) (*SQLite, error) {
|
||||
db, err := sql.Open("sqlite", path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open sqlite failed: %w", err)
|
||||
}
|
||||
if err = db.PingContext(context.Background()); err != nil {
|
||||
if err = db.PingContext(ctx); err != nil {
|
||||
return nil, fmt.Errorf("connect to sqlite failed: %w", err)
|
||||
}
|
||||
return &SQLite{db: db, path: path}, nil
|
||||
@@ -30,13 +30,13 @@ func (r *SQLite) Close() {
|
||||
_ = r.db.Close()
|
||||
}
|
||||
|
||||
func (r *SQLite) Ping() error {
|
||||
return r.db.PingContext(context.Background())
|
||||
func (r *SQLite) Ping(ctx context.Context) error {
|
||||
return r.db.PingContext(ctx)
|
||||
}
|
||||
|
||||
// Tables 获取所有表
|
||||
func (r *SQLite) Tables() ([]string, error) {
|
||||
rows, err := r.db.QueryContext(context.Background(), "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name")
|
||||
func (r *SQLite) Tables(ctx context.Context) ([]string, error) {
|
||||
rows, err := r.db.QueryContext(ctx, "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -64,8 +64,8 @@ type SQLiteColumn struct {
|
||||
}
|
||||
|
||||
// TableInfo 获取表结构
|
||||
func (r *SQLite) TableInfo(name string) ([]SQLiteColumn, error) {
|
||||
rows, err := r.db.QueryContext(context.Background(), fmt.Sprintf("PRAGMA table_info('%s')", name))
|
||||
func (r *SQLite) TableInfo(ctx context.Context, name string) ([]SQLiteColumn, error) {
|
||||
rows, err := r.db.QueryContext(ctx, fmt.Sprintf("PRAGMA table_info('%s')", name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+10
-10
@@ -30,7 +30,7 @@ func NewLocal(basePath string) (Storage, error) {
|
||||
}
|
||||
|
||||
// Delete 删除文件
|
||||
func (l *Local) Delete(files ...string) error {
|
||||
func (l *Local) Delete(_ context.Context, files ...string) error {
|
||||
for _, file := range files {
|
||||
fullPath := l.fullPath(file)
|
||||
if err := os.Remove(fullPath); err != nil && !os.IsNotExist(err) {
|
||||
@@ -41,14 +41,14 @@ func (l *Local) Delete(files ...string) error {
|
||||
}
|
||||
|
||||
// Exists 检查文件是否存在
|
||||
func (l *Local) Exists(file string) bool {
|
||||
func (l *Local) Exists(_ context.Context, file string) bool {
|
||||
fullPath := l.fullPath(file)
|
||||
_, err := os.Stat(fullPath)
|
||||
return !os.IsNotExist(err)
|
||||
}
|
||||
|
||||
// LastModified 获取文件最后修改时间
|
||||
func (l *Local) LastModified(file string) (time.Time, error) {
|
||||
func (l *Local) LastModified(_ context.Context, file string) (time.Time, error) {
|
||||
fullPath := l.fullPath(file)
|
||||
info, err := os.Stat(fullPath)
|
||||
if err != nil {
|
||||
@@ -58,7 +58,7 @@ func (l *Local) LastModified(file string) (time.Time, error) {
|
||||
}
|
||||
|
||||
// List 列出目录下的所有文件
|
||||
func (l *Local) List(path string) ([]string, error) {
|
||||
func (l *Local) List(_ context.Context, path string) ([]string, error) {
|
||||
fullPath := l.fullPath(path)
|
||||
entries, err := os.ReadDir(fullPath)
|
||||
if err != nil {
|
||||
@@ -75,7 +75,7 @@ func (l *Local) List(path string) ([]string, error) {
|
||||
}
|
||||
|
||||
// Put 写入文件内容
|
||||
func (l *Local) Put(file string, content io.Reader) error {
|
||||
func (l *Local) Put(ctx context.Context, file string, content io.Reader) error {
|
||||
fullPath := l.fullPath(file)
|
||||
|
||||
// 确保目录存在
|
||||
@@ -84,7 +84,7 @@ func (l *Local) Put(file string, content io.Reader) error {
|
||||
}
|
||||
|
||||
// 预检查空间
|
||||
if err := l.preCheckPath(filepath.Dir(fullPath)); err != nil {
|
||||
if err := l.preCheckPath(ctx, filepath.Dir(fullPath)); err != nil {
|
||||
return fmt.Errorf("pre check path failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ func (l *Local) Put(file string, content io.Reader) error {
|
||||
}
|
||||
|
||||
// Size 获取文件大小
|
||||
func (l *Local) Size(file string) (int64, error) {
|
||||
func (l *Local) Size(_ context.Context, file string) (int64, error) {
|
||||
fullPath := l.fullPath(file)
|
||||
info, err := os.Stat(fullPath)
|
||||
if err != nil {
|
||||
@@ -120,12 +120,12 @@ func (l *Local) fullPath(path string) string {
|
||||
return filepath.Join(l.basePath, path)
|
||||
}
|
||||
|
||||
func (l *Local) preCheckPath(path string) error {
|
||||
size, err := pkgio.SizeX(context.Background(), path)
|
||||
func (l *Local) preCheckPath(ctx context.Context, path string) error {
|
||||
size, err := pkgio.SizeX(ctx, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
files, err := pkgio.CountX(context.Background(), path)
|
||||
files, err := pkgio.CountX(ctx, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+13
-12
@@ -1,6 +1,7 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
@@ -55,25 +56,25 @@ func NewS3(cfg S3Config) Storage {
|
||||
}
|
||||
|
||||
// Delete 删除文件
|
||||
func (s *S3) Delete(files ...string) error {
|
||||
func (s *S3) Delete(ctx context.Context, files ...string) error {
|
||||
if len(files) == 0 {
|
||||
return nil
|
||||
}
|
||||
keys := lo.Map(files, func(file string, _ int) string {
|
||||
return s.getKey(file)
|
||||
})
|
||||
return s.client.Delete(keys...)
|
||||
return s.client.Delete(ctx, keys...)
|
||||
}
|
||||
|
||||
// Exists 检查文件是否存在
|
||||
func (s *S3) Exists(file string) bool {
|
||||
_, err := s.client.Stat(s.getKey(file))
|
||||
func (s *S3) Exists(ctx context.Context, file string) bool {
|
||||
_, err := s.client.Stat(ctx, s.getKey(file))
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// LastModified 获取文件最后修改时间
|
||||
func (s *S3) LastModified(file string) (time.Time, error) {
|
||||
info, err := s.client.Stat(s.getKey(file))
|
||||
func (s *S3) LastModified(ctx context.Context, file string) (time.Time, error) {
|
||||
info, err := s.client.Stat(ctx, s.getKey(file))
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
@@ -81,14 +82,14 @@ func (s *S3) LastModified(file string) (time.Time, error) {
|
||||
}
|
||||
|
||||
// List 列出目录下的所有文件
|
||||
func (s *S3) List(path string) ([]string, error) {
|
||||
func (s *S3) List(ctx context.Context, path string) ([]string, error) {
|
||||
prefix := s.getKey(path)
|
||||
if prefix != "" && !strings.HasSuffix(prefix, "/") {
|
||||
prefix += "/"
|
||||
}
|
||||
|
||||
var files []string
|
||||
for obj, err := range s.client.List(prefix, "/") {
|
||||
for obj, err := range s.client.List(ctx, prefix, "/") {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -103,13 +104,13 @@ func (s *S3) List(path string) ([]string, error) {
|
||||
}
|
||||
|
||||
// Put 写入文件内容
|
||||
func (s *S3) Put(file string, content io.Reader) error {
|
||||
return s.client.Put(s.getKey(file), content, "application/octet-stream")
|
||||
func (s *S3) Put(ctx context.Context, file string, content io.Reader) error {
|
||||
return s.client.Put(ctx, s.getKey(file), content, "application/octet-stream")
|
||||
}
|
||||
|
||||
// Size 获取文件大小
|
||||
func (s *S3) Size(file string) (int64, error) {
|
||||
info, err := s.client.Stat(s.getKey(file))
|
||||
func (s *S3) Size(ctx context.Context, file string) (int64, error) {
|
||||
info, err := s.client.Stat(ctx, s.getKey(file))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@ type Object struct {
|
||||
// List 返回一个自动翻页、产出 prefix 下所有对象的迭代器
|
||||
// delimiter 非空(通常为 "/")时按目录层级分组
|
||||
// 迭代中若出错,会以 (零值 Object, err) 产出一次随后结束
|
||||
func (c *S3) List(prefix, delimiter string) iter.Seq2[Object, error] {
|
||||
func (c *S3) List(ctx context.Context, prefix, delimiter string) iter.Seq2[Object, error] {
|
||||
return func(yield func(Object, error) bool) {
|
||||
token := ""
|
||||
for {
|
||||
page, err := c.listPage(prefix, delimiter, token)
|
||||
page, err := c.listPage(ctx, prefix, delimiter, token)
|
||||
if err != nil {
|
||||
yield(Object{}, err)
|
||||
return
|
||||
@@ -50,7 +50,7 @@ type listPage struct {
|
||||
nextToken string
|
||||
}
|
||||
|
||||
func (c *S3) listPage(prefix, delimiter, token string) (listPage, error) {
|
||||
func (c *S3) listPage(ctx context.Context, prefix, delimiter, token string) (listPage, error) {
|
||||
query := url.Values{"list-type": {"2"}}
|
||||
if prefix != "" {
|
||||
query.Set("prefix", prefix)
|
||||
@@ -62,7 +62,6 @@ func (c *S3) listPage(prefix, delimiter, token string) (listPage, error) {
|
||||
query.Set("continuation-token", token)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.base+"?"+query.Encode(), nil)
|
||||
if err != nil {
|
||||
return listPage{}, err
|
||||
|
||||
@@ -24,8 +24,7 @@ type ObjectInfo struct {
|
||||
}
|
||||
|
||||
// Stat 通过 HEAD 获取对象元数据;对象不存在时返回的错误可用 IsNotFound 判断
|
||||
func (c *S3) Stat(key string) (ObjectInfo, error) {
|
||||
ctx := context.Background()
|
||||
func (c *S3) Stat(ctx context.Context, key string) (ObjectInfo, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodHead, c.objectURL(key), nil)
|
||||
if err != nil {
|
||||
return ObjectInfo{}, err
|
||||
@@ -58,16 +57,16 @@ func (c *S3) Stat(key string) (ObjectInfo, error) {
|
||||
}
|
||||
|
||||
// Delete 删除一个或多个对象,自动按每批 1000 个分批请求
|
||||
func (c *S3) Delete(keys ...string) error {
|
||||
func (c *S3) Delete(ctx context.Context, keys ...string) error {
|
||||
for batch := range slices.Chunk(keys, 1000) {
|
||||
if err := c.deleteBatch(batch); err != nil {
|
||||
if err := c.deleteBatch(ctx, batch); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *S3) deleteBatch(keys []string) error {
|
||||
func (c *S3) deleteBatch(ctx context.Context, keys []string) error {
|
||||
type object struct {
|
||||
Key string `xml:"Key"`
|
||||
}
|
||||
@@ -86,7 +85,6 @@ func (c *S3) deleteBatch(keys []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.base+"?delete", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -29,7 +29,7 @@ func TestDoRetry(t *testing.T) {
|
||||
defer srv.Close()
|
||||
|
||||
c := New(Config{Region: "us-east-1", Bucket: "b", Endpoint: srv.URL, PathStyle: true})
|
||||
if err := c.putObject("k", []byte("hello"), "text/plain"); err != nil {
|
||||
if err := c.putObject(t.Context(), "k", []byte("hello"), "text/plain"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
+17
-19
@@ -31,7 +31,7 @@ const (
|
||||
)
|
||||
|
||||
// Put 上传一个对象:内容不足一个分片时走单次 PUT,否则流式分片上传
|
||||
func (c *S3) Put(key string, body io.Reader, contentType string) error {
|
||||
func (c *S3) Put(ctx context.Context, key string, body io.Reader, contentType string) error {
|
||||
// 用动态 buffer 读取首块,避免小对象也分配整个 partSize
|
||||
var first bytes.Buffer
|
||||
n, err := io.CopyN(&first, body, c.partSize)
|
||||
@@ -40,14 +40,13 @@ func (c *S3) Put(key string, body io.Reader, contentType string) error {
|
||||
}
|
||||
if n < c.partSize {
|
||||
// 全部内容不足一个分片 → 单次 PUT(含空对象)
|
||||
return c.putObject(key, first.Bytes(), contentType)
|
||||
return c.putObject(ctx, key, first.Bytes(), contentType)
|
||||
}
|
||||
// 已读满一个分片,可能还有更多 → 流式分片上传
|
||||
return c.uploadMultipart(key, first.Bytes(), body, contentType)
|
||||
return c.uploadMultipart(ctx, key, first.Bytes(), body, contentType)
|
||||
}
|
||||
|
||||
func (c *S3) putObject(key string, data []byte, contentType string) error {
|
||||
ctx := context.Background()
|
||||
func (c *S3) putObject(ctx context.Context, key string, data []byte, contentType string) error {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, c.objectURL(key), bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -67,19 +66,19 @@ type completedPart struct {
|
||||
ETag string `xml:"ETag"`
|
||||
}
|
||||
|
||||
func (c *S3) uploadMultipart(key string, first []byte, body io.Reader, contentType string) error {
|
||||
uploadID, err := c.initiate(key, contentType)
|
||||
func (c *S3) uploadMultipart(ctx context.Context, key string, first []byte, body io.Reader, contentType string) error {
|
||||
uploadID, err := c.initiate(ctx, key, contentType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parts, err := c.uploadParts(key, uploadID, first, body)
|
||||
parts, err := c.uploadParts(ctx, key, uploadID, first, body)
|
||||
if err != nil {
|
||||
_ = c.abort(key, uploadID)
|
||||
_ = c.abort(ctx, key, uploadID)
|
||||
return err
|
||||
}
|
||||
if err := c.complete(key, uploadID, parts); err != nil {
|
||||
_ = c.abort(key, uploadID)
|
||||
if err := c.complete(ctx, key, uploadID, parts); err != nil {
|
||||
_ = c.abort(ctx, key, uploadID)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -87,8 +86,8 @@ func (c *S3) uploadMultipart(key string, first []byte, body io.Reader, contentTy
|
||||
|
||||
// uploadParts 顺序读取、并发上传分片。errgroup 的并发上限会对读取形成背压,
|
||||
// 因此常驻内存约为 concurrency × partSize,而非整个文件大小
|
||||
func (c *S3) uploadParts(key, uploadID string, first []byte, body io.Reader) ([]completedPart, error) {
|
||||
g, ctx := errgroup.WithContext(context.Background())
|
||||
func (c *S3) uploadParts(ctx context.Context, key, uploadID string, first []byte, body io.Reader) ([]completedPart, error) {
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
g.SetLimit(c.concurrency)
|
||||
|
||||
var mu sync.Mutex
|
||||
@@ -166,8 +165,7 @@ func isRetryable(err error) bool {
|
||||
return errors.As(err, &ne)
|
||||
}
|
||||
|
||||
func (c *S3) initiate(key, contentType string) (string, error) {
|
||||
ctx := context.Background()
|
||||
func (c *S3) initiate(ctx context.Context, key, contentType string) (string, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.objectURL(key)+"?uploads", nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -193,7 +191,7 @@ func (c *S3) initiate(key, contentType string) (string, error) {
|
||||
return result.UploadID, nil
|
||||
}
|
||||
|
||||
func (c *S3) complete(key, uploadID string, parts []completedPart) error {
|
||||
func (c *S3) complete(ctx context.Context, key, uploadID string, parts []completedPart) error {
|
||||
payload := struct {
|
||||
XMLName xml.Name `xml:"CompleteMultipartUpload"`
|
||||
XMLNS string `xml:"xmlns,attr"`
|
||||
@@ -205,7 +203,6 @@ func (c *S3) complete(key, uploadID string, parts []completedPart) error {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.objectURL(key)+"?uploadId="+url.QueryEscape(uploadID), bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -220,8 +217,9 @@ func (c *S3) complete(key, uploadID string, parts []completedPart) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *S3) abort(key, uploadID string) error {
|
||||
ctx := context.Background()
|
||||
// abort 清理未完成的分片上传,取消导致的失败也要清,否则残片会一直占用存储
|
||||
func (c *S3) abort(ctx context.Context, key, uploadID string) error {
|
||||
ctx = context.WithoutCancel(ctx)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, c.objectURL(key)+"?uploadId="+url.QueryEscape(uploadID), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -54,7 +54,7 @@ func TestPut(t *testing.T) {
|
||||
|
||||
t.Run("small file uses single PUT", func(t *testing.T) {
|
||||
data := bytes.Repeat([]byte("x"), 1024)
|
||||
if err := c.Put("small.txt", bytes.NewReader(data), "text/plain"); err != nil {
|
||||
if err := c.Put(t.Context(), "small.txt", bytes.NewReader(data), "text/plain"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(simpleBody, data) {
|
||||
@@ -76,7 +76,7 @@ func TestPut(t *testing.T) {
|
||||
for i := range data {
|
||||
data[i] = byte(i)
|
||||
}
|
||||
if err := c.Put("big.bin", bytes.NewReader(data), "application/octet-stream"); err != nil {
|
||||
if err := c.Put(t.Context(), "big.bin", bytes.NewReader(data), "application/octet-stream"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(parts) != 3 {
|
||||
|
||||
+22
-14
@@ -1,9 +1,11 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -45,7 +47,7 @@ func NewSFTP(config SFTPConfig) (Storage, error) {
|
||||
}
|
||||
|
||||
// connect 建立 SFTP 连接,返回 client 和 cleanup 函数
|
||||
func (s *SFTP) connect() (*sftp.Client, func(), error) {
|
||||
func (s *SFTP) connect(ctx context.Context) (*sftp.Client, func(), error) {
|
||||
var auth []ssh.AuthMethod
|
||||
// 密码认证
|
||||
if s.config.Password != "" {
|
||||
@@ -68,10 +70,16 @@ func (s *SFTP) connect() (*sftp.Client, func(), error) {
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", s.config.Host, s.config.Port)
|
||||
sshClient, err := ssh.Dial("tcp", addr, clientConfig)
|
||||
conn, err := (&net.Dialer{Timeout: s.config.Timeout}).DialContext(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to connect to SSH server: %w", err)
|
||||
}
|
||||
sshConn, chans, reqs, err := ssh.NewClientConn(conn, addr, clientConfig)
|
||||
if err != nil {
|
||||
_ = conn.Close()
|
||||
return nil, nil, fmt.Errorf("failed to connect to SSH server: %w", err)
|
||||
}
|
||||
sshClient := ssh.NewClient(sshConn, chans, reqs)
|
||||
|
||||
sftpClient, err := sftp.NewClient(sshClient)
|
||||
if err != nil {
|
||||
@@ -88,8 +96,8 @@ func (s *SFTP) connect() (*sftp.Client, func(), error) {
|
||||
}
|
||||
|
||||
// Delete 删除文件
|
||||
func (s *SFTP) Delete(files ...string) error {
|
||||
client, cleanup, err := s.connect()
|
||||
func (s *SFTP) Delete(ctx context.Context, files ...string) error {
|
||||
client, cleanup, err := s.connect(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -105,8 +113,8 @@ func (s *SFTP) Delete(files ...string) error {
|
||||
}
|
||||
|
||||
// Exists 检查文件是否存在
|
||||
func (s *SFTP) Exists(file string) bool {
|
||||
client, cleanup, err := s.connect()
|
||||
func (s *SFTP) Exists(ctx context.Context, file string) bool {
|
||||
client, cleanup, err := s.connect(ctx)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -118,8 +126,8 @@ func (s *SFTP) Exists(file string) bool {
|
||||
}
|
||||
|
||||
// LastModified 获取文件最后修改时间
|
||||
func (s *SFTP) LastModified(file string) (time.Time, error) {
|
||||
client, cleanup, err := s.connect()
|
||||
func (s *SFTP) LastModified(ctx context.Context, file string) (time.Time, error) {
|
||||
client, cleanup, err := s.connect(ctx)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
@@ -135,8 +143,8 @@ func (s *SFTP) LastModified(file string) (time.Time, error) {
|
||||
}
|
||||
|
||||
// List 列出目录下的所有文件
|
||||
func (s *SFTP) List(path string) ([]string, error) {
|
||||
client, cleanup, err := s.connect()
|
||||
func (s *SFTP) List(ctx context.Context, path string) ([]string, error) {
|
||||
client, cleanup, err := s.connect(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -163,8 +171,8 @@ func (s *SFTP) List(path string) ([]string, error) {
|
||||
}
|
||||
|
||||
// Put 写入文件内容
|
||||
func (s *SFTP) Put(file string, content io.Reader) error {
|
||||
client, cleanup, err := s.connect()
|
||||
func (s *SFTP) Put(ctx context.Context, file string, content io.Reader) error {
|
||||
client, cleanup, err := s.connect(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -194,8 +202,8 @@ func (s *SFTP) Put(file string, content io.Reader) error {
|
||||
}
|
||||
|
||||
// Size 获取文件大小
|
||||
func (s *SFTP) Size(file string) (int64, error) {
|
||||
client, cleanup, err := s.connect()
|
||||
func (s *SFTP) Size(ctx context.Context, file string) (int64, error) {
|
||||
client, cleanup, err := s.connect(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Storage interface {
|
||||
// Delete deletes the given file(s).
|
||||
Delete(file ...string) error
|
||||
Delete(ctx context.Context, file ...string) error
|
||||
// Exists determines if a file exists.
|
||||
Exists(file string) bool
|
||||
Exists(ctx context.Context, file string) bool
|
||||
// LastModified gets the file's last modified time.
|
||||
LastModified(file string) (time.Time, error)
|
||||
LastModified(ctx context.Context, file string) (time.Time, error)
|
||||
// List lists all files (not directories) in the given path.
|
||||
List(path string) ([]string, error)
|
||||
List(ctx context.Context, path string) ([]string, error)
|
||||
// Put writes the contents of a file.
|
||||
Put(file string, content io.Reader) error
|
||||
Put(ctx context.Context, file string, content io.Reader) error
|
||||
// Size gets the file size of a given file.
|
||||
Size(file string) (int64, error)
|
||||
Size(ctx context.Context, file string) (int64, error)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@@ -53,7 +54,7 @@ func NewWebDav(config WebDavConfig) (Storage, error) {
|
||||
}
|
||||
|
||||
// Delete 删除文件
|
||||
func (w *WebDav) Delete(files ...string) error {
|
||||
func (w *WebDav) Delete(_ context.Context, files ...string) error {
|
||||
for _, file := range files {
|
||||
remotePath := w.fullPath(file)
|
||||
if err := w.client.Remove(remotePath); err != nil {
|
||||
@@ -64,14 +65,14 @@ func (w *WebDav) Delete(files ...string) error {
|
||||
}
|
||||
|
||||
// Exists 检查文件是否存在
|
||||
func (w *WebDav) Exists(file string) bool {
|
||||
func (w *WebDav) Exists(_ context.Context, file string) bool {
|
||||
remotePath := w.fullPath(file)
|
||||
_, err := w.client.Stat(remotePath)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// LastModified 获取文件最后修改时间
|
||||
func (w *WebDav) LastModified(file string) (time.Time, error) {
|
||||
func (w *WebDav) LastModified(_ context.Context, file string) (time.Time, error) {
|
||||
remotePath := w.fullPath(file)
|
||||
stat, err := w.client.Stat(remotePath)
|
||||
if err != nil {
|
||||
@@ -82,7 +83,7 @@ func (w *WebDav) LastModified(file string) (time.Time, error) {
|
||||
}
|
||||
|
||||
// Put 写入文件内容
|
||||
func (w *WebDav) Put(file string, content io.Reader) error {
|
||||
func (w *WebDav) Put(_ context.Context, file string, content io.Reader) error {
|
||||
remotePath := w.fullPath(file)
|
||||
|
||||
// 确保目录存在
|
||||
@@ -101,7 +102,7 @@ func (w *WebDav) Put(file string, content io.Reader) error {
|
||||
}
|
||||
|
||||
// Size 获取文件大小
|
||||
func (w *WebDav) Size(file string) (int64, error) {
|
||||
func (w *WebDav) Size(_ context.Context, file string) (int64, error) {
|
||||
remotePath := w.fullPath(file)
|
||||
stat, err := w.client.Stat(remotePath)
|
||||
if err != nil {
|
||||
@@ -112,7 +113,7 @@ func (w *WebDav) Size(file string) (int64, error) {
|
||||
}
|
||||
|
||||
// List 列出目录下的所有文件
|
||||
func (w *WebDav) List(path string) ([]string, error) {
|
||||
func (w *WebDav) List(_ context.Context, path string) ([]string, error) {
|
||||
remotePath := w.fullPath(path)
|
||||
entries, err := w.client.ReadDir(remotePath)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user