github.com/gust1n/deis@v0.13.1-0.20141009230754-43ff4d95947b/database/bin/boot (about)

     1  #!/bin/bash
     2  #
     3  # This script is designed to be run inside the container
     4  #
     5  
     6  # fail hard and fast even on pipelines
     7  set -eo pipefail
     8  
     9  # set debug based on envvar
    10  [[ $DEBUG ]] && set -x
    11  
    12  # configure etcd
    13  export ETCD_PORT=${ETCD_PORT:-4001}
    14  export ETCD="$HOST:$ETCD_PORT"
    15  export ETCD_PATH=${ETCD_PATH:-/deis/database}
    16  export ETCD_TTL=${ETCD_TTL:-10}
    17  
    18  export BUCKET_NAME=${BUCKET_NAME:-db_wal}
    19  export BACKUPS_TO_RETAIN=${BACKUPS_TO_RETAIN:-5}
    20  
    21  # how many TTL/2 sleeps between backups -- 2160 is 3 hours
    22  export BACKUP_FREQUENCY=${BACKUP_FREQUENCY:-2160}
    23  
    24  # wait for etcd to be available
    25  until etcdctl --no-sync -C $ETCD ls >/dev/null 2>&1; do
    26  	echo "database: waiting for etcd at $ETCD..."
    27  	sleep $(($ETCD_TTL/2))  # sleep for half the TTL
    28  done
    29  
    30  # wait until etcd has discarded potentially stale values
    31  sleep $(($ETCD_TTL+1))
    32  
    33  function etcd_set_default {
    34    etcdctl --no-sync -C $ETCD mk $ETCD_PATH/$1 $2 >/dev/null 2>&1 || true
    35  }
    36  
    37  etcd_set_default engine postgresql_psycopg2
    38  etcd_set_default adminUser ${PG_ADMIN_USER:-postgres}
    39  etcd_set_default adminPass ${PG_ADMIN_PASS:-changeme123}
    40  etcd_set_default user ${PG_USER_NAME:-deis}
    41  etcd_set_default password ${PG_USER_PASS:-changeme123}
    42  etcd_set_default name ${PG_USER_DB:-deis}
    43  etcd_set_default bucketName ${BUCKET_NAME}
    44  
    45  # wait for confd to run once and install initial templates
    46  until confd -onetime -node $ETCD -config-file /app/confd.toml; do
    47  	echo "database: waiting for confd to write initial templates..."
    48  	sleep $(($ETCD_TTL/2))  # sleep for half the TTL
    49  done
    50  
    51  # ensure WAL log bucket exists
    52  envdir /etc/wal-e.d/env /app/bin/create_bucket ${BUCKET_NAME}
    53  
    54  initial_backup=0
    55  if [[ ! -f /var/lib/postgresql/9.3/main/initialized ]]; then
    56    echo "database: no existing database found."
    57    # check if there are any backups -- if so, let's restore
    58    # we could probably do better than just testing number of lines -- one line is just a heading, meaning no backups
    59    if [[ `envdir /etc/wal-e.d/env wal-e --terse backup-list | wc -l` -gt "1" ]]; then
    60      echo "database: restoring from backup..."
    61      rm -rf /var/lib/postgresql/9.3/main
    62      sudo -u postgres envdir /etc/wal-e.d/env wal-e backup-fetch /var/lib/postgresql/9.3/main LATEST
    63      chown -R postgres:postgres /var/lib/postgresql/9.3/main
    64      chmod 0700 /var/lib/postgresql/9.3/main
    65      echo "restore_command = 'envdir /etc/wal-e.d/env wal-e wal-fetch \"%f\" \"%p\"'" | sudo -u postgres tee /var/lib/postgresql/9.3/main/recovery.conf >/dev/null
    66    else
    67      echo "database: no backups found. Initializing a new database..."
    68      initial_backup=1
    69    fi
    70    # either way, we mark the database as initialized
    71    touch /var/lib/postgresql/9.3/main/initialized
    72  else
    73    echo "database: existing data directory found. Starting postgres..."
    74  fi
    75  
    76  # run the service in the background
    77  sudo -i -u postgres /usr/lib/postgresql/9.3/bin/postgres \
    78                      -c config-file=${PG_CONFIG:-/etc/postgresql/9.3/main/postgresql.conf} \
    79                      -c listen-addresses=${PG_LISTEN:-*} &
    80  
    81  SERVICE_PID=$!
    82  
    83  # smart shutdown on SIGINT and SIGTERM
    84  function on_exit() {
    85      kill -TERM $SERVICE_PID
    86      wait $SERVICE_PID 2>/dev/null
    87      exit 0
    88  }
    89  trap on_exit INT TERM
    90  
    91  # spawn confd in the background to update services based on etcd changes
    92  confd -node $ETCD -config-file /app/confd.toml &
    93  CONFD_PID=$!
    94  
    95  # wait for the service to become available
    96  sleep 1 && while [[ -z $(netstat -lnt | awk "\$6 == \"LISTEN\" && \$4 ~ \".5432\" && \$1 ~ \"tcp.?\"") ]] ; do sleep 1; done
    97  
    98  # perform a one-time reload to populate database entries
    99  /usr/local/bin/reload
   100  
   101  if [[ "${initial_backup}" == "1" ]] ; then
   102    echo "database: performing an initial backup..."
   103    # perform an initial backup
   104    sudo -u postgres envdir /etc/wal-e.d/env wal-e backup-push /var/lib/postgresql/9.3/main
   105  fi
   106  
   107  echo "database: postgres is running..."
   108  
   109  count=1
   110  # publish the service to etcd using the injected HOST and EXTERNAL_PORT
   111  if [[ ! -z $EXTERNAL_PORT ]]; then
   112  	# configure service discovery
   113  	PORT=${PORT:-5432}
   114  	PROTO=${PROTO:-tcp}
   115  
   116  	set +e
   117  
   118  	# wait for the service to become available on PORT
   119  	sleep 1 && while [[ -z $(netstat -lnt | awk "\$6 == \"LISTEN\" && \$4 ~ \".$PORT\" && \$1 ~ \"$PROTO.?\"") ]] ; do sleep 1; done
   120  
   121  	# while the port is listening, publish to etcd
   122  	while [[ ! -z $(netstat -lnt | awk "\$6 == \"LISTEN\" && \$4 ~ \".$PORT\" && \$1 ~ \"$PROTO.?\"") ]] ; do
   123  		etcdctl --no-sync -C $ETCD set $ETCD_PATH/host $HOST --ttl $ETCD_TTL >/dev/null
   124  		etcdctl --no-sync -C $ETCD set $ETCD_PATH/port $EXTERNAL_PORT --ttl $ETCD_TTL >/dev/null
   125  
   126      # perform a backup whenever we hit BACKUP_FREQUENCY
   127      # we really need cron :(
   128      if [[ "${count}" -ge "${BACKUP_FREQUENCY}" ]] ; then
   129        echo "database: performing a backup..."
   130        if [[ -f /var/lib/postgresql/9.3/main/recovery.conf ]] ; then
   131          echo "database: database is currently recovering from a backup. Will try again next loop..."
   132        else
   133          # perform a backup
   134          sudo -u postgres envdir /etc/wal-e.d/env wal-e backup-push /var/lib/postgresql/9.3/main
   135          # only retain the latest BACKUPS_TO_RETAIN backups
   136          sudo -u postgres envdir /etc/wal-e.d/env wal-e delete --confirm retain ${BACKUPS_TO_RETAIN}
   137          count=0
   138        fi
   139      fi
   140      ((count++))
   141  		sleep $(($ETCD_TTL/2)) # sleep for half the TTL
   142  	done
   143  
   144  	# if the loop quits, something went wrong
   145  	exit 1
   146  
   147  fi
   148  
   149  wait