Browse Source

doit: better db handling

wait for db to be really ready;
clearly detect if the db still needs to be prepared
boyska 5 years ago
parent
commit
56f3127af6
2 changed files with 49 additions and 13 deletions
  1. 18 13
      dodo.py
  2. 31 0
      dodo_utils.py

+ 18 - 13
dodo.py

@@ -2,7 +2,9 @@ import subprocess
 
 from doit.tools import LongRunning
 
-from dodo_utils import wait_net_service, up2date_anyimages, run_task_func
+from dodo_utils import wait_net_service, wait_pgsql_db, \
+        up2date_hasimage, up2date_anyimages, \
+        run_task_func
 
 COMPOSE = 'docker-compose -p feedati'
 DOIT_CONFIG = {'default_tasks': ['up']}
@@ -46,31 +48,34 @@ def task__dbprepare_clean():
     '''rimuove il dump caricato sul db'''
     return {
         'actions': [
-            "docker container ls -a --format '{{.ID}}\t{{.Names}}'|"
-            "awk '$2 ~ /^feedati_db$/ { print  $$1 }' | "
-            "xargs -r docker container rm",
+            "docker ps -aqf name=feedati_db|xargs -r docker container rm ",
 
             "docker volume rm feedati_postgres_data || true",
         ]
     }
 
 
+def stop():
+    subprocess.check_call((COMPOSE + ' stop').split())
+    return True
+
+
 def task_dbprepare():
     '''applica il dump sql al container del db'''
     return {
-        'task_dep': ['_dbprepare_clean', 'build'],
+        'setup': ['_dbprepare_clean', 'build'],
         'file_dep': ['docker/ttrss.sql'],
         'actions': [
                     (COMPOSE + ' up -d db').split(),
-                    r'docker cp ./docker/ttrss.sql '
-                    '$(docker ps -qf name=feedati_db):/tmp/ttrss.sql',
-                    (wait_net_service, ['localhost', 5432, 300]),
-                    r'docker exec -t $(docker ps -qf name=feedati_db) '
-                    'su -c "psql -d ttrss < /tmp/ttrss.sql" postgres',
-                    'docker exec -t $(docker ps -qf name=feedati_db) '
-                    'rm -f /tmp/ttrss.sql',
-                    COMPOSE + ' stop',
+                    (wait_net_service, ('localhost', 5432, 300)),
+                    (wait_pgsql_db, ('feedati_db', 'ttrss', 'ttrss')),
+                    'echo LOADING DB',
+                    r'docker exec -i $(docker ps -aqf name=feedati_db) '
+                    'psql -h 127.0.0.1 -f - -d ttrss ttrss < docker/ttrss.sql',
+                    'echo DB RESTORED',
                     ],
+        'teardown': [(stop, [])],
+        'uptodate': [up2date_hasimage('feedati_postgres_data')()],
         'clean': [run_task_func(task__dbprepare_clean)]
     }
 

+ 31 - 0
dodo_utils.py

@@ -1,7 +1,9 @@
 import subprocess
+import time
 
 from doit import loader
 
+
 def wait_net_service(server, port, timeout=None):
     """ Wait for network service to appear 
         @param timeout: in seconds, if None or 0 wait forever
@@ -40,6 +42,24 @@ def wait_net_service(server, port, timeout=None):
             return True
 
 
+def wait_pgsql_db(container, dbname, user, timeout=60):
+    container_id = subprocess.check_output(
+        'docker ps -qf name=feedati_db'.split()).decode('utf8').strip()
+    print('container db=', container_id)
+    cmd = ['docker', 'exec', container_id,
+           'psql', '-h', 'localhost', '-U', user, '-w', dbname]
+    for i in range(timeout):
+        try:
+            subprocess.check_output(cmd, shell=False)
+        except subprocess.CalledProcessError as exc:
+            if exc.returncode == 2:  # there's some more to wait
+                time.sleep(1)
+                continue
+            raise
+        else:
+            return True
+
+
 def up2date_anyimages():
     cmd = "docker images -q feedati/*".split()
     output = subprocess.check_output(cmd).strip()
@@ -48,6 +68,17 @@ def up2date_anyimages():
     return False
 
 
+def up2date_hasimage(imagename):
+    def fun():
+        cmd = ' '.join(['docker', 'volume', 'ls',
+                        '-qf', 'name=%s' % imagename])
+        out = subprocess.check_output(cmd, shell=True).decode('utf8').strip()
+        if out:
+            return True
+        return False
+    return fun
+
+
 def run(cmd, **kwargs):
     def fun():
         subprocess.check_call(cmd, **kwargs)