forked from vmware-archive/atc
/
container.go
123 lines (93 loc) · 2.78 KB
/
container.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
package worker
import (
"errors"
"sync"
"code.cloudfoundry.org/garden"
"code.cloudfoundry.org/lager"
"github.com/concourse/atc/db"
)
var ErrMissingVolume = errors.New("volume mounted to container is missing")
type gardenWorkerContainer struct {
garden.Container
dbContainer db.CreatedContainer
dbVolumes []db.CreatedVolume
gardenClient garden.Client
volumeMounts []VolumeMount
user string
releaseOnce sync.Once
workerName string
}
func newGardenWorkerContainer(
logger lager.Logger,
container garden.Container,
dbContainer db.CreatedContainer,
dbContainerVolumes []db.CreatedVolume,
gardenClient garden.Client,
volumeClient VolumeClient,
workerName string,
) (Container, error) {
logger = logger.WithData(lager.Data{"container": container.Handle()})
workerContainer := &gardenWorkerContainer{
Container: container,
dbContainer: dbContainer,
dbVolumes: dbContainerVolumes,
gardenClient: gardenClient,
workerName: workerName,
}
err := workerContainer.initializeVolumes(logger, volumeClient)
if err != nil {
return nil, err
}
properties, err := workerContainer.Properties()
if err != nil {
return nil, err
}
if properties["user"] != "" {
workerContainer.user = properties["user"]
} else {
workerContainer.user = "root"
}
return workerContainer, nil
}
func (container *gardenWorkerContainer) Destroy() error {
return container.gardenClient.Destroy(container.Handle())
}
func (container *gardenWorkerContainer) WorkerName() string {
return container.workerName
}
func (container *gardenWorkerContainer) MarkAsHijacked() error {
return container.dbContainer.MarkAsHijacked()
}
func (container *gardenWorkerContainer) Run(spec garden.ProcessSpec, io garden.ProcessIO) (garden.Process, error) {
spec.User = container.user
return container.Container.Run(spec, io)
}
func (container *gardenWorkerContainer) VolumeMounts() []VolumeMount {
return container.volumeMounts
}
func (container *gardenWorkerContainer) initializeVolumes(
logger lager.Logger,
volumeClient VolumeClient,
) error {
volumeMounts := []VolumeMount{}
for _, dbVolume := range container.dbVolumes {
volumeLogger := logger.Session("volume", lager.Data{
"handle": dbVolume.Handle(),
})
volume, volumeFound, err := volumeClient.LookupVolume(logger, dbVolume.Handle())
if err != nil {
volumeLogger.Error("failed-to-lookup-volume", err)
return err
}
if !volumeFound {
volumeLogger.Error("volume-is-missing-on-worker", ErrMissingVolume, lager.Data{"handle": dbVolume.Handle()})
return errors.New("volume mounted to container is missing " + dbVolume.Handle() + " from worker " + container.workerName)
}
volumeMounts = append(volumeMounts, VolumeMount{
Volume: volume,
MountPath: dbVolume.Path(),
})
}
container.volumeMounts = volumeMounts
return nil
}