Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F3912578
D2934.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D2934.id.diff
View Options
diff --git a/pillar/paas/docker.sls b/pillar/paas/docker.sls
--- a/pillar/paas/docker.sls
+++ b/pillar/paas/docker.sls
@@ -2,10 +2,97 @@
# Salt — Provision Docker engine
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
-# Created: 2018-03-10
# License: Trivial work, not eligible to copyright
# -------------------------------------------------------------
+# -------------------------------------------------------------
+# Hard dependencies between containers
+#
+# To compute optimal Docker containers start order, the following
+# rules apply:
+#
+# - depends_of_containers: launch after a specific container
+# values are the keys for those containers
+#
+# - depends_of_services: launch after containers from this service
+#
+# Hierarchy of keys can use dot (.) as separator, e.g. links.mysql
+#
+# Values are configuration keys from docker_containers pillar.
+#
+# Soft dependencies (e.g. Notifications Center depends of Sentry)
+# aren't documented, as it can still run without it.
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+docker_containers_dependencies:
+
+ #
+ # Core services
+ #
+
+ kafka:
+ depends_of_containers:
+ - zookeeper
+
+ #
+ # Simple services
+ #
+
+ auth-grove:
+ depends_of_containers:
+ - mysql_link
+
+ bugzilla:
+ depends_of_services:
+ - mysql
+
+ cachet:
+ depends_of_containers:
+ - mysql_link
+
+ etherpad:
+ depends_of_containers:
+ - mysql_link
+
+ notifications:
+ depends_of_containers:
+ - broker_link
+
+ phabricator:
+ depends_of_containers:
+ - mysql_link
+
+ pixelfed:
+ depends_of_containers:
+ - links.mysql
+ - links.redis
+
+ #
+ # Sentry
+ #
+
+ relay:
+ may_depends_of_containers:
+ - kafka
+ - redis
+ - web
+
+ sentry:
+ depends_of_services:
+ - redis
+ - kafka
+ - postgresql
+ - memcached
+ - exim
+ - snuba
+ - symbolicator
+
+ snuba:
+ depends_of_containers:
+ - services.broker
+ - services.clickhouse
+ - services.redis
+
# -------------------------------------------------------------
# Monitoring
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/roles/paas-docker/docker/files/docker-paas-list-containers.py b/roles/paas-docker/docker/files/docker-paas-list-containers.py
new file mode 100755
--- /dev/null
+++ b/roles/paas-docker/docker/files/docker-paas-list-containers.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python3
+
+# -------------------------------------------------------------
+# Docker PaaS - List of containers
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# Description: Resolve the dependencies between containers
+# into a graph, and use topological sorting
+# to offer an order of containers.
+#
+# This can be used to run every container in
+# the right order to avoid any link issue.
+#
+# License: BSD-2-Clause
+# -------------------------------------------------------------
+
+
+from graphlib import TopologicalSorter
+import json
+import subprocess
+import sys
+
+
+CONTAINER_DELIMITERS = [":"]
+
+
+# -------------------------------------------------------------
+# Resolve dependencies
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+def solve_containers_order(containers, dependencies):
+ graph = {}
+
+ for service, instances in containers.items():
+ if service not in dependencies:
+ graph |= {instance: [] for instance in instances}
+ continue
+
+ rules = dependencies[service]
+ for instance, args in instances.items():
+ graph[instance] = solve_dependencies(containers, rules, instance, args)
+
+ return list(TopologicalSorter(graph).static_order())
+
+
+def solve_dependencies(containers, rules, instance, args):
+ other_instances = []
+
+ if "depends_of_containers" in rules:
+ other_instances += [
+ get_value(args, container_key)
+ for container_key in rules["depends_of_containers"]
+ ]
+
+ if "may_depends_of_containers" in rules:
+ other_instances += [
+ get_value(args, container_key)
+ for container_key in rules["may_depends_of_containers"]
+ if container_key in args
+ ]
+
+ if "depends_of_services" in rules:
+ if "network" not in args:
+ print(
+ f"[WARN] Can't resolve depends_of_services rule for instance {instance} as no network is specified.",
+ file=sys.stderr,
+ )
+ return other_instances
+
+ for service in rules["depends_of_services"]:
+ for other_instance, other_args in containers[service].items():
+ if "network" not in other_args:
+ # For example, pixelfed_redis isn't on a network
+ continue
+
+ if args["network"] == other_args["network"]:
+ other_instances.append(other_instance)
+
+ return other_instances
+
+
+# -------------------------------------------------------------
+# Helper methods to get and clean container values
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+def clean_value(container):
+ for delimiter in CONTAINER_DELIMITERS:
+ pos = container.find(delimiter)
+ if pos > -1:
+ container = container[:pos]
+
+ return container
+
+
+def get_value(args, key):
+ if "." in key:
+ pos = key.find(".")
+ return get_value(args[key[:pos]], key[pos + 1 :])
+
+ try:
+ return clean_value(args[key])
+ except KeyError:
+ print(f"[FATAL] No {key} in {args}", file=sys.stderr)
+ sys.exit(1)
+
+
+# -------------------------------------------------------------
+# Helper methods to query Salt pillar
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+def query_pillar(*keys):
+ cmd = ["sudo", "salt-call", "pillar.items", "--out", "json"]
+ process = subprocess.run(cmd, capture_output=True)
+
+ if process.returncode != 0:
+ raise RuntimeError("Can't query Salt: " + process.stderr)
+
+ pillar = json.loads(process.stdout)["local"]
+ return tuple(pillar.get(key, {}) for key in keys)
+
+
+# -------------------------------------------------------------
+# Application entry point
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+def run():
+ try:
+ containers, dependencies = query_pillar(
+ "docker_containers", "docker_containers_dependencies"
+ )
+ except RuntimeError as e:
+ print(e, file=sys.stderr)
+ sys.exit(2)
+
+ for container in solve_containers_order(containers, dependencies):
+ print(container)
+
+
+if __name__ == "__main__":
+ run()
diff --git a/roles/paas-docker/docker/software.sls b/roles/paas-docker/docker/software.sls
--- a/roles/paas-docker/docker/software.sls
+++ b/roles/paas-docker/docker/software.sls
@@ -6,7 +6,7 @@
# License: Trivial work, not eligible to copyright
# -------------------------------------------------------------
-{% from "map.jinja" import services with context %}
+{% from "map.jinja" import dirs, services with context %}
# -------------------------------------------------------------
# Install Docker engine
@@ -56,3 +56,8 @@
pkg.installed:
- pkgs:
- docker-processes
+
+{{ dirs.bin }}/docker-paas-list-containers:
+ file.managed:
+ - source: salt://roles/paas-docker/docker/files/docker-paas-list-containers.py
+ - mode: 755
diff --git a/roles/paas-docker/systemd-unit/files/containers.conf b/roles/paas-docker/systemd-unit/files/containers.conf
deleted file mode 100644
--- a/roles/paas-docker/systemd-unit/files/containers.conf
+++ /dev/null
@@ -1,9 +0,0 @@
-acquisitariat
-white-rabbit
-notifications
-aphlict
-devcentral
-wolfphab
-pad
-cachet
-ci
diff --git a/roles/paas-docker/systemd-unit/files/docker-containers.service b/roles/paas-docker/systemd-unit/files/docker-containers.service
--- a/roles/paas-docker/systemd-unit/files/docker-containers.service
+++ b/roles/paas-docker/systemd-unit/files/docker-containers.service
@@ -17,5 +17,5 @@
[Service]
Type=simple
RemainAfterExit=yes
-ExecStart=docker_start
-ExecStop=docker_stop
+ExecStart=docker-paas-start-containers
+ExecStop=docker-paas-stop-containers
diff --git a/roles/paas-docker/systemd-unit/files/docker_start.sh b/roles/paas-docker/systemd-unit/files/docker-paas-start-containers.sh
rename from roles/paas-docker/systemd-unit/files/docker_start.sh
rename to roles/paas-docker/systemd-unit/files/docker-paas-start-containers.sh
--- a/roles/paas-docker/systemd-unit/files/docker_start.sh
+++ b/roles/paas-docker/systemd-unit/files/docker-paas-start-containers.sh
@@ -6,7 +6,7 @@
# Project: Nasqueron
# Created: 2015-12-29
# License: Trivial work, not eligible to copyright
-# Source file: roles/paas-docker/systemd-unit/files/docker_start.sh
+# Source file: roles/paas-docker/systemd-unit/files/docker-paas-start-containers.sh
# -------------------------------------------------------------
#
# <auto-generated>
@@ -16,4 +16,4 @@
# and will be lost if the state is redeployed.
# </auto-generated>
-get-containers-list | xargs docker start
+docker-paas-list-containers | xargs docker start
diff --git a/roles/paas-docker/systemd-unit/files/docker_stop.sh b/roles/paas-docker/systemd-unit/files/docker-paas-stop-containers.sh
rename from roles/paas-docker/systemd-unit/files/docker_stop.sh
rename to roles/paas-docker/systemd-unit/files/docker-paas-stop-containers.sh
--- a/roles/paas-docker/systemd-unit/files/docker_stop.sh
+++ b/roles/paas-docker/systemd-unit/files/docker-paas-stop-containers.sh
@@ -6,7 +6,7 @@
# Project: Nasqueron
# Created: 2015-12-29
# License: Trivial work, not eligible to copyright
-# Source file: roles/paas-docker/systemd-unit/files/docker_stop.sh
+# Source file: roles/paas-docker/systemd-unit/files/docker-paas-stop-containers.sh
# -------------------------------------------------------------
#
# <auto-generated>
@@ -16,4 +16,4 @@
# and will be lost if the state is redeployed.
# </auto-generated>
-get-containers --reverse | xargs docker stop
+docker-paas-list-containers | tac | xargs docker stop
diff --git a/roles/paas-docker/systemd-unit/files/get-containers-list.sh b/roles/paas-docker/systemd-unit/files/get-containers-list.sh
deleted file mode 100755
--- a/roles/paas-docker/systemd-unit/files/get-containers-list.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env bash
-
-# -------------------------------------------------------------
-# PaaS Docker
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-# Project: Nasqueron
-# Created: 2017-01-30
-# License: Trivial work, not eligible to copyright
-# Source file: roles/paas-docker/systemd-unit/files/get-containers-list.sh
-# -------------------------------------------------------------
-#
-# <auto-generated>
-# This file is managed by our rOPS SaltStack repository.
-#
-# Changes to this file may cause incorrect behavior
-# and will be lost if the state is redeployed.
-# </auto-generated>
-
-## Read /etc/containers.conf and recover docker’s names into an array.
-## get-containers-list [--reverse]
-
-file='/etc/containers.conf'
-
-if [[ ! -f "$file" ]]; then
- echo "$file : does not exists "
- exit 1
-elif [[ ! -r "$file" ]]; then
- echo "$file : can not read "
-fi
-
-# Get names in an array
-# 21:42 <geirha> since bash 4, you can use mapfile instead of that
-# while read loop. mapfile -t array < "$file"
-mapfile -t array < "$file"
-
-# Test argument to know in which order return names
-if [[ $1 == "--reverse" ]]; then
- for ((i="${#array[*]}" - 1; i >= 0; i--)); do
- echo "${array[i]}"
- done
-elif [[ -z "$1" ]]; then
- for ((i=0; i < "${#array[*]}"; i++)); do
- echo "${array[i]}"
- done
-else
- echo "$1 is not a valid argument"
-fi
diff --git a/roles/paas-docker/systemd-unit/init.sls b/roles/paas-docker/systemd-unit/init.sls
--- a/roles/paas-docker/systemd-unit/init.sls
+++ b/roles/paas-docker/systemd-unit/init.sls
@@ -2,9 +2,46 @@
# Salt — Provision Docker engine
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
-# Created: 2018-09-13
# License: Trivial work, not eligible to copyright
# -------------------------------------------------------------
-# This section is intentionally left blank.
-# See T1428.
+{% from "map.jinja" import dirs, services with context %}
+
+# -------------------------------------------------------------
+# Helper executables to start and stop containers
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{% for action in ['start', 'stop'] %}
+
+{{ dirs.bin }}/docker-paas-{{ action }}-containers:
+ file.managed:
+ - source: salt://roles/paas-docker/systemd-unit/files/docker-paas-{{ action }}-containers.sh
+ - mode: 755
+
+{% endfor %}
+
+# -------------------------------------------------------------
+# Service
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{% if services['manager'] == 'systemd' %}
+
+docker-containers_unit:
+ file.managed:
+ - name: /etc/systemd/system/docker-containers.service
+ - source: salt://roles/paas-docker/systemd-unit/files/docker-containers.service
+ - mode: 644
+ module.run:
+ - service.force_reload:
+ - name: docker-containers
+ - onchanges:
+ - file: docker-containers_unit
+
+docker-containers_running:
+ service.running:
+ - name: docker-containers
+ - enable: true
+ - watch:
+ - module: docker-containers_unit
+
+{% endif %}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 20, 06:15 (1 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2307273
Default Alt Text
D2934.id.diff (13 KB)
Attached To
Mode
D2934: Determine in what order containers should be run
Attached
Detach File
Event Timeline
Log In to Comment