forked from hashicorp/nomad
/
device_hook.go
94 lines (78 loc) · 2.16 KB
/
device_hook.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
package taskrunner
import (
"context"
"fmt"
log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/nomad/client/allocrunner/interfaces"
"github.com/hashicorp/nomad/client/devicemanager"
"github.com/hashicorp/nomad/plugins/device"
"github.com/hashicorp/nomad/plugins/drivers"
)
const (
// HookNameDevices is the name of the devices hook
HookNameDevices = "devices"
)
// deviceHook is used to retrieve device mounting information.
type deviceHook struct {
logger log.Logger
dm devicemanager.Manager
}
func newDeviceHook(dm devicemanager.Manager, logger log.Logger) *deviceHook {
h := &deviceHook{
dm: dm,
}
h.logger = logger.Named(h.Name())
return h
}
func (*deviceHook) Name() string {
return HookNameDevices
}
func (h *deviceHook) Prestart(ctx context.Context, req *interfaces.TaskPrestartRequest, resp *interfaces.TaskPrestartResponse) error {
//TODO Can the nil check be removed once the TODO in NewTaskRunner
// where this is set is addressed?
if req.TaskResources == nil || len(req.TaskResources.Devices) == 0 {
resp.Done = true
return nil
}
// Capture the responses
var reservations []*device.ContainerReservation
for _, req := range req.TaskResources.Devices {
// Ask the device manager for the reservation information
res, err := h.dm.Reserve(req)
if err != nil {
return fmt.Errorf("failed to reserve device %s: %v", req.ID(), err)
}
reservations = append(reservations, res)
}
// Build the response
for _, res := range reservations {
for k, v := range res.Envs {
if resp.Env == nil {
resp.Env = make(map[string]string)
}
resp.Env[k] = v
}
for _, m := range res.Mounts {
resp.Mounts = append(resp.Mounts, convertMount(m))
}
for _, d := range res.Devices {
resp.Devices = append(resp.Devices, convertDevice(d))
}
}
resp.Done = true
return nil
}
func convertMount(in *device.Mount) *drivers.MountConfig {
return &drivers.MountConfig{
TaskPath: in.TaskPath,
HostPath: in.HostPath,
Readonly: in.ReadOnly,
}
}
func convertDevice(in *device.DeviceSpec) *drivers.DeviceConfig {
return &drivers.DeviceConfig{
TaskPath: in.TaskPath,
HostPath: in.HostPath,
Permissions: in.CgroupPerms,
}
}