Stream snapshot file listings
This commit is contained in:
@@ -268,7 +268,7 @@ func (s *Server) repositoryStats(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, 200, s.service.RepositoryStats(ctx))
|
||||
}
|
||||
func (s *Server) snapshotFiles(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Minute)
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 20*time.Minute)
|
||||
defer cancel()
|
||||
items, err := s.service.SnapshotFiles(ctx, r.PathValue("id"), r.PathValue("snapshot"), r.URL.Query().Get("path"))
|
||||
if err != nil {
|
||||
|
||||
@@ -274,20 +274,16 @@ func (r *Runner) List(ctx context.Context, repo model.Repository, snapshot, path
|
||||
if path != "" {
|
||||
args = append(args, path)
|
||||
}
|
||||
var output []byte
|
||||
if err := r.run(ctx, repo, args, nil, &output); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items := []map[string]any{}
|
||||
scanner := bufio.NewScanner(strings.NewReader(string(output)))
|
||||
scanner.Buffer(make([]byte, 0, 64*1024), 2*1024*1024)
|
||||
for scanner.Scan() {
|
||||
if err := r.run(ctx, repo, args, func(line []byte) {
|
||||
var item map[string]any
|
||||
if json.Unmarshal(scanner.Bytes(), &item) == nil && item["struct_type"] == "node" {
|
||||
if json.Unmarshal(line, &item) == nil && item["struct_type"] == "node" {
|
||||
items = append(items, item)
|
||||
}
|
||||
}, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, scanner.Err()
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (r *Runner) Diff(ctx context.Context, repo model.Repository, before, after string, limit int) (DiffResult, error) {
|
||||
@@ -466,6 +462,9 @@ func (r *Runner) runWithInputEnvPassword(ctx context.Context, repo model.Reposit
|
||||
if errors.Is(ctx.Err(), context.Canceled) {
|
||||
return fmt.Errorf("cancelled: %w", ctx.Err())
|
||||
}
|
||||
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
||||
return fmt.Errorf("environment: Restic-Aufruf hat das Zeitlimit überschritten: %w", ctx.Err())
|
||||
}
|
||||
return resticError(message, err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -233,6 +233,36 @@ printf '%%s\n' 'Files: 1 new, 1 removed, 2 changed'
|
||||
}
|
||||
}
|
||||
|
||||
func TestListStreamsSnapshotNodes(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
argsPath := filepath.Join(dir, "args")
|
||||
script := filepath.Join(dir, "restic")
|
||||
body := fmt.Sprintf(`#!/bin/sh
|
||||
printf '%%s\n' "$@" > '%s'
|
||||
printf '%%s\n' '{"struct_type":"snapshot","id":"snap"}'
|
||||
printf '%%s\n' '{"struct_type":"node","path":"/mnt/user","type":"dir"}'
|
||||
printf '%%s\n' '{"struct_type":"node","path":"/mnt/user/file.txt","type":"file","size":12}'
|
||||
`, argsPath)
|
||||
if err := os.WriteFile(script, []byte(body), 0700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runner := &Runner{Binary: script, RuntimeDir: dir, Secrets: fakeSecrets{"password": "secret"}}
|
||||
repo := model.Repository{Type: model.RepositoryLocal, Location: "/repo", PasswordRef: "password"}
|
||||
items, err := runner.List(context.Background(), repo, "snap", "/mnt/user")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(items) != 2 || items[0]["path"] != "/mnt/user" || items[1]["path"] != "/mnt/user/file.txt" {
|
||||
t.Fatalf("unexpected items: %+v", items)
|
||||
}
|
||||
args, _ := os.ReadFile(argsPath)
|
||||
for _, expected := range []string{"ls", "snap", "--json", "/mnt/user"} {
|
||||
if !strings.Contains(string(args), expected) {
|
||||
t.Fatalf("arguments missing %q: %s", expected, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatsUsesRequestedRepositoryCountingMode(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
argsPath := filepath.Join(dir, "args")
|
||||
|
||||
Reference in New Issue
Block a user