forked from RSE-Cambridge/data-acc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
196 lines (186 loc) · 4.67 KB
/
main.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package main
import (
"github.com/RSE-Cambridge/data-acc/pkg/version"
"github.com/urfave/cli"
"log"
"os"
"strings"
)
func stripFunctionArg(systemArgs []string) []string {
if len(systemArgs) > 2 && systemArgs[1] == "--function" {
return append(systemArgs[0:1], systemArgs[2:]...)
}
return systemArgs
}
var token = cli.StringFlag{
Name: "token, t",
Usage: "Job ID or Persistent Buffer name",
}
var job = cli.StringFlag{
Name: "job, j",
Usage: "Path to burst buffer request file.",
}
var caller = cli.StringFlag{
Name: "caller, c",
Usage: "The system that called the CLI, e.g. Slurm.",
}
var user = cli.IntFlag{
Name: "user, u",
Usage: "Linux user id that owns the buffer.",
}
var groupid = cli.IntFlag{
Name: "groupid, group, g",
Usage: "Linux group id that owns the buffer, defaults to match the user.",
}
var capacity = cli.StringFlag{
Name: "capacity, C",
Usage: "A request of the form <pool>:<int><units> where units could be GiB or TiB.",
}
func runCli(args []string) error {
app := cli.NewApp()
app.Name = "dacclt"
app.Usage = "This CLI is used to orchestrate the Data Accelerator with Slurm's Burst Buffer plugin."
app.Version = version.VERSION
app.Commands = []cli.Command{
{
Name: "pools",
Usage: "List all the buffer pools",
Action: listPools,
},
{
Name: "show_instances",
Usage: "List the buffer instances.",
Action: showInstances,
},
{
Name: "show_sessions",
Usage: "List the buffer sessions.",
Action: showSessions,
},
{
Name: "teardown",
Usage: "Destroy the given buffer.",
Flags: []cli.Flag{token, job,
cli.BoolFlag{
Name: "hurry",
},
},
Action: teardown,
},
{
Name: "job_process",
Usage: "Initial call to validate buffer script",
Flags: []cli.Flag{job},
Action: jobProcess,
},
{
Name: "setup",
Usage: "Create transient buffer, called after waiting for enough free capacity.",
Flags: []cli.Flag{token, job, caller, user, groupid, capacity,
cli.StringFlag{
Name: "nodehostnamefile",
Usage: "Path to file containing list of scheduled compute nodes.",
},
},
Action: setup,
},
{
Name: "real_size",
Usage: "Report actual size of created buffer.",
Flags: []cli.Flag{token},
Action: realSize,
},
{
Name: "data_in",
Usage: "Copy data into given buffer.",
Flags: []cli.Flag{token, job},
Action: dataIn,
},
{
Name: "paths",
Usage: "Environment variables describing where the buffer will be mounted.",
Flags: []cli.Flag{token, job,
cli.StringFlag{
Name: "pathfile",
Usage: "Path of where to write the enviroment variables file.",
},
},
Action: paths,
},
{
Name: "pre_run",
Usage: "Attach given buffers to compute nodes specified.",
Flags: []cli.Flag{token, job,
cli.StringFlag{
Name: "nodehostnamefile",
Usage: "Path to file containing list of compute nodes for job.",
},
// TODO: required when SetExecHost flag set, but currently we just ignore this param!
cli.StringFlag{
Name: "jobexecutionnodefile",
Usage: "Path to file containing list of login nodes.",
},
},
Action: preRun,
},
{
Name: "post_run",
Usage: "Detach buffers before releasing compute nodes.",
Flags: []cli.Flag{token, job},
Action: postRun,
},
{
Name: "data_out",
Usage: "Copy data out of buffer.",
Flags: []cli.Flag{token, job},
Action: dataOut,
},
{
Name: "create_persistent",
Usage: "Create a persistent buffer.",
Flags: []cli.Flag{token, caller, capacity, user, groupid,
cli.StringFlag{
Name: "access, a",
Usage: "Access mode, e.g. striped or private.",
},
cli.StringFlag{
Name: "type, T",
Usage: "Type of buffer, e.d. scratch or cache.",
},
},
Action: createPersistent,
},
{
Name: "show_configurations",
Usage: "Returns fake data to keep burst buffer plugin happy.",
Action: showConfigurations,
},
}
return app.Run(stripFunctionArg(args))
}
func main() {
logFilename := os.Getenv("DACCTL_LOG")
if logFilename == "" {
logFilename = "/var/log/dacctl.log"
}
f, err := os.OpenFile(logFilename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("error opening file: %v", err)
}
defer f.Close()
// be sure to log any panic
defer func() {
if r := recover(); r != nil {
log.Println("Panic detected:", r)
panic(r)
}
}()
log.SetOutput(f)
log.Println("dacctl start, called with:", strings.Join(os.Args, " "))
if err := runCli(os.Args); err != nil {
log.Println("dacctl error, called with:", strings.Join(os.Args, " "))
log.Fatal(err)
} else {
log.Println("dacctl complete, called with:", strings.Join(os.Args, " "))
}
}