feat: storage writes via storage-agent, accepts_uploads and write_template (M5.5)
ci / api / api (push) Successful in 33s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 43s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m11s
ci / ts / ts (packages + web) (push) Successful in 1m10s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 51s
ci / api / api (push) Successful in 33s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 43s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m11s
ci / ts / ts (packages + web) (push) Successful in 1m10s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 51s
- storage-agent: POST /internal/files copies a staged file into a source
(temp file, fsync, SHA-256 check, hard link so nothing is overwritten,
" (2)" suffix on conflict, owner PIPU_FILE_UID/GID) and
POST /internal/files/test. NFS sources that accept uploads are mounted
rw in an agent-only /library-rw and bind-mounted read-only for others;
local sources are written through /library-host-rw.
- meta: write templates ({track:02}, {disc:1-}, [optional]) with name
sanitising and length limits, suggestion from the source's regexes
and a reversibility check against 50 catalogue tracks.
- API and admin UI: accepts_uploads / write_template on sources,
write-template suggest and check endpoints, write test result.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9b50038bb4
commit
f66be2ba0a
27 files changed
+2422
-213
No files matched your search
@@ -13,11 +13,14 @@ import (
|
||||
"pipu/api/internal/storageagent"
|
||||
)
|
||||
|
||||
// Agent — клиент storage-agent (монтирование NFS).
|
||||
// Agent — клиент storage-agent (монтирование NFS, запись импортированных файлов).
|
||||
type Agent interface {
|
||||
Mount(ctx context.Context, sourceID uuid.UUID, spec storageagent.NFSSpec) (storageagent.MountResult, error)
|
||||
// Mount монтирует NFS; writable — источник принимает загрузки (ещё rw-точка, видимая только агенту).
|
||||
Mount(ctx context.Context, sourceID uuid.UUID, spec storageagent.NFSSpec, writable bool) (storageagent.MountResult, error)
|
||||
Unmount(ctx context.Context, sourceID uuid.UUID) error
|
||||
Test(ctx context.Context, spec storageagent.NFSSpec) (storageagent.MountResult, error)
|
||||
TestWrite(ctx context.Context, req storageagent.WriteTestRequest) (storageagent.WriteTestResult, error)
|
||||
WriteFile(ctx context.Context, req storageagent.WriteRequest) (storageagent.WriteResult, error)
|
||||
}
|
||||
|
||||
// HTTPAgent ходит в storage-agent по внутренней сети с общим секретом.
|
||||
@@ -86,9 +89,28 @@ func (a *HTTPAgent) do(ctx context.Context, method, path string, body any, out a
|
||||
}
|
||||
|
||||
// Mount реализует Agent.
|
||||
func (a *HTTPAgent) Mount(ctx context.Context, id uuid.UUID, spec storageagent.NFSSpec) (storageagent.MountResult, error) {
|
||||
func (a *HTTPAgent) Mount(ctx context.Context, id uuid.UUID, spec storageagent.NFSSpec, writable bool) (storageagent.MountResult, error) {
|
||||
var res storageagent.MountResult
|
||||
err := a.do(ctx, http.MethodPost, "/internal/mounts", storageagent.MountRequest{SourceID: id.String(), NFSSpec: spec}, &res)
|
||||
err := a.do(ctx, http.MethodPost, "/internal/mounts",
|
||||
storageagent.MountRequest{SourceID: id.String(), NFSSpec: spec, Writable: writable}, &res)
|
||||
return res, err
|
||||
}
|
||||
|
||||
// TestWrite реализует Agent.
|
||||
func (a *HTTPAgent) TestWrite(ctx context.Context, req storageagent.WriteTestRequest) (storageagent.WriteTestResult, error) {
|
||||
var res storageagent.WriteTestResult
|
||||
err := a.do(ctx, http.MethodPost, "/internal/files/test", req, &res)
|
||||
return res, err
|
||||
}
|
||||
|
||||
// WriteFile реализует Agent. Копирование большого файла по NFS может идти минуты — отдельный таймаут.
|
||||
func (a *HTTPAgent) WriteFile(ctx context.Context, req storageagent.WriteRequest) (storageagent.WriteResult, error) {
|
||||
var res storageagent.WriteResult
|
||||
ctx, cancel := context.WithTimeout(ctx, 30*time.Minute)
|
||||
defer cancel()
|
||||
c := *a
|
||||
c.Client = &http.Client{}
|
||||
err := c.do(ctx, http.MethodPost, "/internal/files", req, &res)
|
||||
return res, err
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user