Skip to content

Commit 8827676

Browse files
author
Joe LeVeque
committed
Add 'docker-wait-any' script, use it to wait for containers to exit
1 parent 613fe0d commit 8827676

3 files changed

Lines changed: 69 additions & 2 deletions

File tree

files/build_templates/sonic_debian_extension.j2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ sudo cp $IMAGE_CONFIGS/hostname/hostname-config.service $FILESYSTEM_ROOT/etc/sy
163163
sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable hostname-config.service
164164
sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/
165165

166+
# Copy miscellaneous scripts
167+
sudo cp $IMAGE_CONFIGS/misc/docker-wait-any $FILESYSTEM_ROOT/usr/bin/
168+
166169
# Copy updategraph script and service file
167170
j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/updategraph.service
168171
sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable updategraph.service

files/build_templates/swss.service.j2

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ ExecStartPre=/etc/init.d/xpnet.sh start
4141

4242
ExecStartPre=/usr/bin/{{docker_container_name}}.sh start
4343
ExecStartPre=/usr/bin/syncd.sh start
44-
ExecStartPre=/usr/bin/{{docker_container_name}}.sh start
45-
ExecStart=/bin/bash -c "sleep 5; while true; do if [ x\"$(docker inspect -f {{'{{'}}.State.Running{{'}}'}} {{docker_container_name}})\" != x\"true\" ] || [ x\"$(docker inspect -f {{'{{'}}.State.Running{{'}}'}} syncd)\" != x\"true\" ]; then break; fi; sleep 1; done"
44+
ExecStart=/bin/bash -c "sleep 5; /usr/bin/docker-wait-any {{docker_container_name}} syncd"
4645

4746
ExecStop=/usr/bin/{{docker_container_name}}.sh stop
4847
ExecStopPost=/usr/bin/syncd.sh stop
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env python
2+
3+
"""
4+
docker-wait-any
5+
6+
This script takes one or more Docker container names as arguments,
7+
and it will block indefinitely while all of the specified containers
8+
are running. If any of the specified containers stop, the script will
9+
exit.
10+
11+
This script was created because the 'docker wait' command is lacking
12+
this functionality. It will block until ALL specified containers have
13+
stopped running. Here, we spawn multiple threads and wait on one
14+
container per thread. If any of the threads exit, the entire
15+
application will exit.
16+
17+
NOTE: This script is written against docker-py version 1.6.0. Newer
18+
versions of docker-py have a different API.
19+
"""
20+
21+
import sys
22+
import threading
23+
from docker import Client
24+
25+
# Instantiate a global event to share among our threads
26+
g_thread_exit_event = threading.Event()
27+
28+
29+
def usage():
30+
print("Usage: {} <container_name> [<container_name> ...]".format(sys.argv[0]))
31+
sys.exit(1)
32+
33+
34+
def wait_for_container(docker_client, container_name):
35+
docker_client.wait(container_name)
36+
37+
print("No longer waiting on container '{}'".format(container_name))
38+
39+
# Signal the main thread to exit
40+
g_thread_exit_event.set()
41+
42+
43+
def main():
44+
thread_list = []
45+
46+
docker_client = Client(base_url='unix://var/run/docker.sock')
47+
48+
# Ensure we were passed at least one argument
49+
if len(sys.argv) < 2:
50+
usage()
51+
52+
container_names = sys.argv[1:]
53+
54+
for container_name in container_names:
55+
t = threading.Thread(target=wait_for_container, args=[docker_client, container_name])
56+
t.daemon = True
57+
t.start()
58+
thread_list.append(t)
59+
60+
# Wait until we receive an event signifying one of the containers has stopped
61+
g_thread_exit_event.wait()
62+
sys.exit(0)
63+
64+
if __name__ == '__main__':
65+
main()

0 commit comments

Comments
 (0)