From 8f8dd7f86a28d1f7bb9f6bc815bf6ca9ab7b4f64 Mon Sep 17 00:00:00 2001
From: dobli <dobler.alex@gmail.com>
Date: Tue, 29 Jan 2019 18:09:02 +0100
Subject: [PATCH] added postgres as database service

---
 building_manager.py                   | 54 +++++++++++++++++++++++++--
 template_configs/docker-skeleton.yml  |  7 +++-
 template_configs/docker-templates.yml | 25 +++++++++++++
 3 files changed, 81 insertions(+), 5 deletions(-)

diff --git a/building_manager.py b/building_manager.py
index f93a014..f2ceb4e 100755
--- a/building_manager.py
+++ b/building_manager.py
@@ -3,6 +3,7 @@
 import crypt
 import logging
 import os
+from hashlib import md5
 from shutil import copy2
 from subprocess import PIPE, run
 
@@ -24,7 +25,8 @@ TEMPLATE_DIR = 'template_configs'
 COMPOSE_NAME = 'docker-stack.yml'
 SKELETON_NAME = 'docker-skeleton.yml'
 TEMPLATES_NAME = 'docker-templates.yml'
-CONFIG_DIRS = ['mosquitto', 'nodered', 'ssh', 'traefik', 'volumerize']
+CONFIG_DIRS = ['mosquitto', 'nodered', 'ssh',
+               'traefik', 'volumerize', 'postgres']
 TEMPLATE_FILES = [
     'mosquitto/mosquitto.conf', 'nodered/nodered_package.json',
     'nodered/nodered_settings.js', 'ssh/sshd_config', 'traefik/traefik.toml'
@@ -36,13 +38,16 @@ EDIT_FILES = {
     "id_rsa": "ssh/id_rsa",
     "host_key": "ssh/ssh_host_ed25519_key",
     "known_hosts": "ssh/known_hosts",
-    "backup_config": "volumerize/backup_config.json"
+    "backup_config": "volumerize/backup_config.json",
+    "postgres_user": "postgres/user",
+    "postgres_passwd": "postgres/passwd"
 }
 CONSTRAINTS = {"building": "node.labels.building"}
 SERVICES = {
     "sftp": "sftp_X",
     "openhab": "openhab_X",
     "nodered": "nodered_X",
+    "postgres": "postgres_X",
     "mqtt": "mqtt_X"
 }
 
@@ -178,6 +183,26 @@ def add_mqtt_service(base_dir, hostname, number=0):
     add_or_update_compose_service(compose_path, service_name, template)
 
 
+def add_postgres_service(base_dir, hostname):
+    """Generates an postgres entry and adds it to the compose file
+
+    :base_dir: base directory for configuration files
+    :hostname: names of host that the services is added to
+    """
+    base_path = base_dir + '/' + CUSTOM_DIR
+    # compose file
+    compose_path = base_path + '/' + COMPOSE_NAME
+    # service name
+    service_name = f'postgres_{hostname}'
+    # template
+    template = get_service_template(base_dir, SERVICES['postgres'])
+    # only label contraint is building
+    template['deploy']['placement']['constraints'][0] = (
+        f"{CONSTRAINTS['building']} == {hostname}")
+
+    add_or_update_compose_service(compose_path, service_name, template)
+
+
 # Helper functions
 def get_service_template(base_dir, service_name):
     """Gets a service template entry from the template yaml
@@ -393,6 +418,22 @@ def generate_sftp_file(base_dir, username, password, direcories=None):
                                   file_content)
 
 
+def generate_postgres_files(base_dir, username, password):
+    """Generates postgres user and password files
+
+    :base_dir: path that contains custom config folder
+    :username: username to use
+    :password: password that will be used
+    """
+    # content is purely username and (hashed) password
+    hashed_password = 'md5' + \
+        md5(username.encode() + password.encode()).hexdigest()
+    create_or_replace_config_file(
+        base_dir, EDIT_FILES['postgres_user'], username)
+    create_or_replace_config_file(
+        base_dir, EDIT_FILES['postgres_passwd'], hashed_password)
+
+
 def generate_id_rsa_files(base_dir):
     """Generates id_rsa and id_rsa.pub private/public keys using ssh-keygen
 
@@ -668,7 +709,8 @@ def run_command_in_service(service, command, building=None):
         service_container = containers[0]
         print(f'Executing {command} in container {service_container.name}'
               f'({service_container.id}) on building {building}')
-        print(service_container.exec_run(command))
+        command_exec = service_container.exec_run(command)
+        print(command_exec.output.decode())
     client.close()
 
 
@@ -830,6 +872,7 @@ def init_menu(args):
     password = password_answers['password']
     hosts = answers['machines']
     generate_sftp_file(base_dir, username, password)
+    generate_postgres_files(base_dir, username, password)
     generate_mosquitto_file(base_dir, username, password)
     generate_traefik_file(base_dir, username, password)
     generate_volumerize_file(base_dir, hosts)
@@ -867,7 +910,8 @@ def init_machine_menu(base_dir, host, increment):
         {
             'type': 'input',
             'name': 'buildingid',
-            'message': f'Choose a name for building on server {host}'
+            'message': f'Choose a name for building on server {host}',
+            'default': f'{host}'
         },
         {
             'type': 'checkbox',
@@ -886,6 +930,8 @@ def init_machine_menu(base_dir, host, increment):
         add_nodered_service(base_dir, host)
     if 'mqtt' in services:
         add_mqtt_service(base_dir, host, increment)
+    if 'postgres' in services:
+        add_postgres_service(base_dir, host)
     print(answers)
 
 
diff --git a/template_configs/docker-skeleton.yml b/template_configs/docker-skeleton.yml
index ae80350..8e771c0 100644
--- a/template_configs/docker-skeleton.yml
+++ b/template_configs/docker-skeleton.yml
@@ -33,6 +33,10 @@ configs:
         file: ./mosquitto/mosquitto_passwords
     mosquitto_settings:
         file: ./mosquitto/mosquitto.conf
+    postgres_user:
+        file: ./postgres/user
+    postgres_passwd:
+        file: ./postgres/passwd
 
 volumes:
     openhab_addons:
@@ -41,9 +45,10 @@ volumes:
     nodered_data:
     mosquitto_data:
     influxdb_data:
-    unison_data:
+    postgres_data:
     backup_data:
     backup_cache:
+
     
 services:
     proxy:
diff --git a/template_configs/docker-templates.yml b/template_configs/docker-templates.yml
index 40fc5fb..cea84f8 100644
--- a/template_configs/docker-templates.yml
+++ b/template_configs/docker-templates.yml
@@ -33,6 +33,10 @@ configs:
         file: ./mosquitto/mosquitto_passwords
     mosquitto_settings:
         file: ./mosquitto/mosquitto.conf
+    postgres_user:
+        file: ./postgres/user
+    postgres_passwd:
+        file: ./postgres/passwd
 
 volumes:
     openhab_addons:
@@ -41,6 +45,7 @@ volumes:
     nodered_data:
     mosquitto_data:
     influxdb_data:
+    postgres_data:
     backup_data:
     backup_cache:
 
@@ -178,6 +183,26 @@ services:
             placement:
                 constraints:
                     - node.labels.building == X
+    postgres_X:
+        image: "postgres"
+        volumes:
+            - "postgres_data:/var/lib/postgresql/data/pgdata"
+        configs:
+            - source: postgres_user
+              target: /run/secrets/postgres_user
+            - source: postgres_passwd
+              target: /run/secrets/postgres_passwd
+        environment:
+            PGDATA: "/var/lib/postgresql/data/pgdata"
+            POSTGRES_USER_FILE: "/run/secrets/postgres_user"
+            POSTGRES_PASSWORD_FILE: "/run/secrets/postgres_passwd"
+            POSTGRES_DB: "openhab"
+        networks:
+            - habnet
+        deploy:
+            placement:
+                constraints:
+                    - node.labels.building == X
     proxy:
         image: "traefik"
         command: --api --docker --docker.swarmMode --logLevel="DEBUG"
-- 
GitLab