Skip to content

Commit c8520c6

Browse files
Merge pull request #51 from lisongmin/support-volume_mount
support volume_mount in task
2 parents 4ab1c8f + 9ffe5d4 commit c8520c6

File tree

5 files changed

+180
-1
lines changed

5 files changed

+180
-1
lines changed

containerd/driver.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,22 @@ func NewPlugin(logger log.Logger) drivers.DriverPlugin {
229229
}
230230
}
231231

232+
func (tc *TaskConfig) setVolumeMounts(cfg *drivers.TaskConfig) {
233+
for _, m := range cfg.Mounts {
234+
hm := Mount{
235+
Type: "bind",
236+
Target: m.TaskPath,
237+
Source: m.HostPath,
238+
Options: []string{"rbind"},
239+
}
240+
if m.Readonly {
241+
hm.Options = append(hm.Options, "ro")
242+
}
243+
244+
tc.Mounts = append(tc.Mounts, hm)
245+
}
246+
}
247+
232248
// PluginInfo returns information describing the plugin.
233249
func (d *Driver) PluginInfo() (*base.PluginInfoResponse, error) {
234250
return pluginInfo, nil
@@ -345,6 +361,8 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive
345361
return nil, nil, fmt.Errorf("host_network and bridge network mode are mutually exclusive, and only one of them should be set")
346362
}
347363

364+
driverConfig.setVolumeMounts(cfg)
365+
348366
d.logger.Info("starting task", "driver_cfg", hclog.Fmt("%+v", driverConfig))
349367
handle := drivers.NewTaskHandle(taskHandleVersion)
350368
handle.Config = cfg

example/agent_tests.hcl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
log_level = "INFO"
2+
3+
plugin "containerd-driver" {
4+
config {
5+
enabled = true
6+
containerd_runtime = "io.containerd.runc.v2"
7+
stats_interval = "5s"
8+
}
9+
}
10+
11+
client {
12+
host_volume "s1" {
13+
path = "/tmp/host_volume/s1"
14+
read_only = false
15+
}
16+
}

example/volume_mount.nomad

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
job "volume_mount" {
2+
datacenters = ["dc1"]
3+
4+
group "volume_mount-group" {
5+
6+
volume "data" {
7+
type = "host"
8+
source = "s1"
9+
read_only = false
10+
}
11+
12+
volume "read_only_data" {
13+
type = "host"
14+
source = "s1"
15+
read_only = true
16+
}
17+
18+
task "volume_mount-task" {
19+
driver = "containerd-driver"
20+
config {
21+
image = "docker.io/library/ubuntu:16.04"
22+
command = "sleep"
23+
args = ["600s"]
24+
}
25+
26+
volume_mount {
27+
destination = "/tmp/t1"
28+
volume = "data"
29+
}
30+
31+
volume_mount {
32+
destination = "/tmp/read_only_target"
33+
volume = "read_only_data"
34+
}
35+
36+
resources {
37+
cpu = 500
38+
memory = 256
39+
}
40+
}
41+
}
42+
}

tests/005-test-volume_mount.sh

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/bin/bash
2+
3+
job_name=volume_mount
4+
host_volume_path=/tmp/host_volume/s1
5+
6+
# test volume_mount
7+
test_volume_mount_nomad_job() {
8+
pushd ~/go/src/github.com/Roblox/nomad-driver-containerd/example
9+
10+
setup_bind_source
11+
12+
echo "INFO: Starting nomad $job_name job using nomad-driver-containerd."
13+
nomad job run $job_name.nomad
14+
15+
# Even though $(nomad job status) reports job status as "running"
16+
# The actual container process might not be running yet.
17+
# We need to wait for actual container to start running before trying exec.
18+
echo "INFO: Wait for ${job_name} container to get into RUNNING state, before trying exec."
19+
is_${job_name}_container_active
20+
21+
echo "INFO: Checking status of $job_name job."
22+
job_status=$(nomad job status -short $job_name|grep Status|awk '{split($0,a,"="); print a[2]}'|tr -d ' ')
23+
if [ "$job_status" != "running" ];then
24+
echo "ERROR: Error in getting ${job_name} job status."
25+
exit 1
26+
fi
27+
28+
# Check if bind mount exists.
29+
echo "INFO: Checking if bind mount exists."
30+
for mountpoint in t1 read_only_target ; do
31+
output=$(nomad alloc exec -job ${job_name} cat /tmp/${mountpoint}/bind.txt)
32+
if [ "$output" != "hello" ]; then
33+
echo "ERROR: bind mount /tmp/${mountpoint} does not exist in container rootfs."
34+
exit 1
35+
fi
36+
done
37+
38+
# Check read only mount can not write.
39+
echo "INFO: Checking read only mount is not writable."
40+
nomad alloc exec -job ${job_name} touch /tmp/read_only_target/writable_test.txt &>/dev/null
41+
if [ -e ${host_volume_path}/writable_test.txt ];then
42+
echo "ERROR: Read only bind mount in /tmp/read_only_target should not be writable."
43+
exit 1
44+
fi
45+
46+
# Check writable mount can write.
47+
echo "INFO: Checking non read_only mount is writable."
48+
nomad alloc exec -job ${job_name} touch /tmp/t1/writable_test.txt
49+
if [ ! -e ${host_volume_path}/writable_test.txt ];then
50+
echo "ERROR: bind mount in /tmp/t1 should be writable."
51+
exit 1
52+
fi
53+
54+
echo "INFO: Stopping nomad ${job_name} job."
55+
nomad job stop ${job_name}
56+
job_status=$(nomad job status -short ${job_name}|grep Status|awk '{split($0,a,"="); print a[2]}'|tr -d ' ')
57+
if [ $job_status != "dead(stopped)" ];then
58+
echo "ERROR: Error in stopping ${job_name} job."
59+
exit 1
60+
fi
61+
62+
echo "INFO: purge nomad ${job_name} job."
63+
nomad job stop -purge ${job_name}
64+
popd
65+
}
66+
67+
setup_bind_source() {
68+
rm -f ${host_volume_path}/bind.txt
69+
rm -f ${host_volume_path}/writable_test.txt
70+
71+
echo hello > ${host_volume_path}/bind.txt
72+
}
73+
74+
is_volume_mount_container_active() {
75+
i="0"
76+
while test $i -lt 5
77+
do
78+
sudo CONTAINERD_NAMESPACE=nomad ctr task ls|grep -q RUNNING
79+
if [ $? -eq 0 ]; then
80+
echo "INFO: ${job_name} container is up and running"
81+
sleep 5s
82+
break
83+
fi
84+
echo "INFO: ${job_name} container is down, sleep for 4 seconds."
85+
sleep 4s
86+
i=$[$i+1]
87+
done
88+
89+
if [ $i -ge 5 ]; then
90+
echo "ERROR: ${job_name} container didn't come up. exit 1."
91+
exit 1
92+
fi
93+
}
94+
95+
test_volume_mount_nomad_job

tests/run_tests.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ Documentation=https://nomadproject.io
152152
After=network.target
153153
154154
[Service]
155-
ExecStart=/usr/local/bin/nomad agent -dev -config=/home/circleci/go/src/github.com/Roblox/nomad-driver-containerd/example/agent.hcl -plugin-dir=/tmp/nomad-driver-containerd
155+
ExecStart=/usr/local/bin/nomad agent -dev -config=/home/circleci/go/src/github.com/Roblox/nomad-driver-containerd/example/agent_tests.hcl -plugin-dir=/tmp/nomad-driver-containerd
156156
KillMode=process
157157
Delegate=yes
158158
LimitNOFILE=1048576
@@ -165,12 +165,20 @@ WantedBy=multi-user.target
165165
EOF
166166
sudo mv nomad.service /lib/systemd/system/nomad.service
167167
sudo systemctl daemon-reload
168+
169+
prepare_nomad_host_volume
170+
168171
echo "INFO: Starting nomad server and nomad-driver-containerd."
169172
sudo systemctl start nomad
170173
is_systemd_service_active "nomad.service"
171174
popd
172175
}
173176

177+
prepare_nomad_host_volume() {
178+
echo "INFO: Prepare nomad host volume."
179+
mkdir -p /tmp/host_volume/s1
180+
}
181+
174182
is_containerd_driver_active() {
175183
i="0"
176184
while test $i -lt 5

0 commit comments

Comments
 (0)