This repository has been archived by the owner on Feb 17, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
export.go
99 lines (86 loc) · 2.26 KB
/
export.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main
import (
"context"
"errors"
"io"
"os"
"github.com/stealthrocket/timecraft/format"
"github.com/stealthrocket/timecraft/internal/timecraft"
)
const exportUsage = `
Usage: timecraft export <resource type> <resource id> <output file> [options]
The export command reads resources from the time machine registry and writes
them to local files. This command is useful to extract data generated by
timecraft and visualize it with other tools.
The last argument is the location where the resource is exported, typically
a path on the file system. The special value "-" may be set to write the
resource to stdout.
Options:
-c, --config path Path to the timecraft configuration file (overrides TIMECRAFTCONFIG)
-h, --help Show this usage information
`
func export(ctx context.Context, args []string) error {
flagSet := newFlagSet("timecraft export", exportUsage)
args, err := parseFlags(flagSet, args)
if err != nil {
return err
}
if len(args) != 3 {
perrorf(`Expected resource type, id, and output file as argument` + useCmd("export"))
return exitCode(2)
}
resource, err := findResource("describe", args[0])
if err != nil {
perror(err)
return exitCode(2)
}
config, err := timecraft.LoadConfig()
if err != nil {
return err
}
registry, err := timecraft.OpenRegistry(config)
if err != nil {
return err
}
if resource.typ == "log" {
// How should we handle logs?
// - write the manifest.json + segments to a tar archive?
// - combines the segments into a single log file?
// - ???
return errors.New(`TODO`)
}
var hash format.Hash
if resource.typ == "process" {
processID, err := parseProcessID(args[1])
if err != nil {
return err
}
manifest, err := registry.LookupLogManifest(ctx, processID)
if err != nil {
return err
}
hash = manifest.Process.Digest
} else {
desc, err := registry.LookupDescriptor(ctx, format.ParseHash(args[1]))
if err != nil {
return err
}
hash = desc.Digest
}
r, err := registry.LookupResource(ctx, hash)
if err != nil {
return err
}
defer r.Close()
w := io.Writer(os.Stdout)
if outputFile := args[2]; outputFile != "-" {
f, err := os.Create(outputFile)
if err != nil {
return err
}
defer f.Close()
w = f
}
_, err = io.Copy(w, r)
return err
}