diff options
| -rw-r--r-- | docker-compose.yml | 10 | ||||
| -rwxr-xr-x | manage.py | 89 | ||||
| -rw-r--r-- | postgres/init.sql | 73 | 
3 files changed, 35 insertions, 137 deletions
| diff --git a/docker-compose.yml b/docker-compose.yml index 37678949..eb987624 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,13 @@ services:        POSTGRES_DB: pysite        POSTGRES_PASSWORD: pysite        POSTGRES_USER: pysite +    healthcheck: +      test: ["CMD-SHELL", "pg_isready -U pysite"] +      interval: 2s +      timeout: 1s +      retries: 5 +    volumes: +      - ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql    web:      build: @@ -33,7 +40,8 @@ services:      ports:        - "127.0.0.1:8000:8000"      depends_on: -      - postgres +      postgres: +        condition: service_healthy      tty: true      volumes:        - .:/app:ro @@ -1,9 +1,6 @@  #!/usr/bin/env python  import os -import socket  import sys -import time -from urllib.parse import SplitResult, urlsplit  import django  from django.contrib.auth import get_user_model @@ -55,21 +52,6 @@ class SiteManager:              print("Starting in debug mode.")      @staticmethod -    def parse_db_url(db_url: str) -> SplitResult: -        """Validate and split the given databse url.""" -        db_url_parts = urlsplit(db_url) -        if not all(( -            db_url_parts.hostname, -            db_url_parts.username, -            db_url_parts.password, -            db_url_parts.path -        )): -            raise ValueError( -                "The DATABASE_URL environment variable is not a valid PostgreSQL database URL." -            ) -        return db_url_parts - -    @staticmethod      def create_superuser() -> None:          """Create a default django admin super user in development environments."""          print("Creating a superuser.") @@ -99,36 +81,6 @@ class SiteManager:              print(f"Existing bot token found: {token}")      @staticmethod -    def wait_for_postgres() -> None: -        """Wait for the PostgreSQL database specified in DATABASE_URL.""" -        print("Waiting for PostgreSQL database.") - -        # Get database URL based on environmental variable passed in compose -        database_url_parts = SiteManager.parse_db_url(os.environ["DATABASE_URL"]) -        domain = database_url_parts.hostname -        # Port may be omitted, 5432 is the default psql port -        port = database_url_parts.port or 5432 - -        # Attempt to connect to the database socket -        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - -        attempts_left = 10 -        while attempts_left: -            try: -                # Ignore 'incomplete startup packet' -                s.connect((domain, port)) -                s.shutdown(socket.SHUT_RDWR) -                print("Database is ready.") -                break -            except socket.error: -                attempts_left -= 1 -                print("Not ready yet, retrying.") -                time.sleep(0.5) -        else: -            print("Database could not be found, exiting.") -            sys.exit(1) - -    @staticmethod      def set_dev_site_name() -> None:          """Set the development site domain in admin from default example."""          # import Site model now after django setup @@ -141,44 +93,8 @@ class SiteManager:                  name="pythondiscord.local:8000"              ) -    @staticmethod -    def run_metricity_init() -> None: -        """ -        Initialise metricity relations and populate with some testing data. - -        This is done at run time since other projects, like Python bot, -        rely on the site initialising it's own db, since they do not have -        access to the init.sql file to mount a docker-compose volume. -        """ -        import psycopg2 -        from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT - -        print("Initialising metricity.") - -        db_url_parts = SiteManager.parse_db_url(os.environ["DATABASE_URL"]) -        conn = psycopg2.connect( -            host=db_url_parts.hostname, -            port=db_url_parts.port, -            user=db_url_parts.username, -            password=db_url_parts.password, -            database=db_url_parts.path[1:] -        ) -        # Required to create a db from `cursor.execute()` -        conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) - -        with conn.cursor() as cursor, open("postgres/init.sql", encoding="utf-8") as f: -            cursor.execute( -                f.read(), -                ("metricity", db_url_parts.username, db_url_parts.password) -            ) -        conn.close() -      def prepare_server(self) -> None:          """Perform preparation tasks before running the server.""" -        self.wait_for_postgres() -        if self.debug: -            self.run_metricity_init() -          django.setup()          print("Applying migrations.") @@ -233,11 +149,6 @@ class SiteManager:  def main() -> None:      """Entry point for Django management script.""" -    # Always run metricity init when in CI, indicated by the CI env var -    if os.environ.get("CI", "false").lower() == "true": -        SiteManager.wait_for_postgres() -        SiteManager.run_metricity_init() -      # Use the custom site manager for launching the server      if len(sys.argv) > 1 and sys.argv[1] == "run":          SiteManager(sys.argv).run_server() diff --git a/postgres/init.sql b/postgres/init.sql index 55bb468f..190a705c 100644 --- a/postgres/init.sql +++ b/postgres/init.sql @@ -1,29 +1,8 @@ --- The following function is from Stack Overflow --- https://stackoverflow.com/questions/18389124/simulate-create-database-if-not-exists-for-postgresql/36218838#36218838 --- User frankhommers (https://stackoverflow.com/users/971229/frankhommers) - -DO -$do$ -DECLARE -  _db TEXT := %s; -  _user TEXT := %s; -  _password TEXT := %s; -BEGIN -  CREATE EXTENSION IF NOT EXISTS dblink; -  IF EXISTS (SELECT 1 FROM pg_database WHERE datname = _db) THEN -    RAISE NOTICE 'Database already exists'; -  ELSE -    PERFORM dblink_connect( -        'host=localhost user=' || _user || -        ' password=' || _password || -        ' dbname=' || current_database() -    ); -    PERFORM dblink_exec('CREATE DATABASE ' || _db); -  END IF; -END -$do$; - -CREATE TABLE IF NOT EXISTS users ( +CREATE DATABASE metricity; + +\c metricity; + +CREATE TABLE users (      id varchar,      joined_at timestamp,      primary key(id) @@ -32,14 +11,14 @@ CREATE TABLE IF NOT EXISTS users (  INSERT INTO users VALUES (      0,      current_timestamp -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO users VALUES (      1,      current_timestamp -) ON CONFLICT (id) DO NOTHING; +); -CREATE TABLE IF NOT EXISTS channels ( +CREATE TABLE channels (      id varchar,      name varchar,      primary key(id) @@ -48,44 +27,44 @@ CREATE TABLE IF NOT EXISTS channels (  INSERT INTO channels VALUES(      '267659945086812160',      'python-general' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO channels VALUES(      '11',      'help-apple' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO channels VALUES(      '12',      'help-cherry' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO channels VALUES(      '21',      'ot0-hello' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO channels VALUES(      '22',      'ot1-world' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO channels VALUES(      '31',      'voice-chat-0' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO channels VALUES(      '32',      'code-help-voice-0' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO channels VALUES(      '1234',      'zebra' -) ON CONFLICT (id) DO NOTHING; +); -CREATE TABLE IF NOT EXISTS messages ( +CREATE TABLE messages (      id varchar,      author_id varchar references users(id),      is_deleted boolean, @@ -100,7 +79,7 @@ INSERT INTO messages VALUES(      false,      now(),      '267659945086812160' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO messages VALUES(      1, @@ -108,7 +87,7 @@ INSERT INTO messages VALUES(      false,      now() + INTERVAL '10 minutes,',      '1234' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO messages VALUES(      2, @@ -116,7 +95,7 @@ INSERT INTO messages VALUES(      false,      now(),      '11' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO messages VALUES(      3, @@ -124,7 +103,7 @@ INSERT INTO messages VALUES(      false,      now(),      '12' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO messages VALUES(      4, @@ -132,7 +111,7 @@ INSERT INTO messages VALUES(      false,      now(),      '21' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO messages VALUES(      5, @@ -140,7 +119,7 @@ INSERT INTO messages VALUES(      false,      now(),      '22' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO messages VALUES(      6, @@ -148,7 +127,7 @@ INSERT INTO messages VALUES(      false,      now(),      '31' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO messages VALUES(      7, @@ -156,7 +135,7 @@ INSERT INTO messages VALUES(      false,      now(),      '32' -) ON CONFLICT (id) DO NOTHING; +);  INSERT INTO messages VALUES(      8, @@ -164,4 +143,4 @@ INSERT INTO messages VALUES(      true,      now(),      '32' -) ON CONFLICT (id) DO NOTHING; +); | 
