github.com/inflatablewoman/deis@v1.0.1-0.20141111034523-a4511c46a6ce/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    set +e
    35    etcdctl --no-sync -C $ETCD mk $ETCD_PATH/$1 $2 >/dev/null 2>&1
    36    if [[ $? -ne 0 && $? -ne 4 ]]; then
    37      echo "etcd_set_default: an etcd error occurred. aborting..."
    38      exit 1
    39    fi
    40    set -e
    41  }
    42  
    43  etcd_set_default engine postgresql_psycopg2
    44  etcd_set_default adminUser ${PG_ADMIN_USER:-postgres}
    45  etcd_set_default adminPass ${PG_ADMIN_PASS:-changeme123}
    46  etcd_set_default user ${PG_USER_NAME:-deis}
    47  etcd_set_default password ${PG_USER_PASS:-changeme123}
    48  etcd_set_default name ${PG_USER_DB:-deis}
    49  etcd_set_default bucketName ${BUCKET_NAME}
    50  
    51  # wait for confd to run once and install initial templates
    52  until confd -onetime -node $ETCD -config-file /app/confd.toml; do
    53  	echo "database: waiting for confd to write initial templates..."
    54  	sleep $(($ETCD_TTL/2))  # sleep for half the TTL
    55  done
    56  
    57  # initialize database if one doesn't already exist
    58  # for example, in the case of a data container
    59  if [[ ! -d /var/lib/postgresql/9.3/main ]]; then
    60  	chown -R postgres:postgres /var/lib/postgresql
    61  	sudo -u postgres /usr/lib/postgresql/9.3/bin/initdb -D /var/lib/postgresql/9.3/main
    62  fi
    63  
    64  # ensure WAL log bucket exists
    65  envdir /etc/wal-e.d/env /app/bin/create_bucket ${BUCKET_NAME}
    66  
    67  initial_backup=0
    68  if [[ ! -f /var/lib/postgresql/9.3/main/initialized ]]; then
    69    echo "database: no existing database found."
    70    # check if there are any backups -- if so, let's restore
    71    # we could probably do better than just testing number of lines -- one line is just a heading, meaning no backups
    72    if [[ `envdir /etc/wal-e.d/env wal-e --terse backup-list | wc -l` -gt "1" ]]; then
    73      echo "database: restoring from backup..."
    74      rm -rf /var/lib/postgresql/9.3/main
    75      sudo -u postgres envdir /etc/wal-e.d/env wal-e backup-fetch /var/lib/postgresql/9.3/main LATEST
    76      chown -R postgres:postgres /var/lib/postgresql/9.3/main
    77      chmod 0700 /var/lib/postgresql/9.3/main
    78      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
    79    else
    80      echo "database: no backups found. Initializing a new database..."
    81      initial_backup=1
    82    fi
    83    # either way, we mark the database as initialized
    84    touch /var/lib/postgresql/9.3/main/initialized
    85  else
    86    echo "database: existing data directory found. Starting postgres..."
    87  fi
    88  
    89  # run the service in the background
    90  sudo -i -u postgres /usr/lib/postgresql/9.3/bin/postgres \
    91                      -c config-file=${PG_CONFIG:-/etc/postgresql/9.3/main/postgresql.conf} \
    92                      -c listen-addresses=${PG_LISTEN:-*} &
    93  
    94  SERVICE_PID=$!
    95  
    96  # smart shutdown on SIGINT and SIGTERM
    97  function on_exit() {
    98      kill -TERM $SERVICE_PID
    99      wait $SERVICE_PID 2>/dev/null
   100      exit 0
   101  }
   102  trap on_exit INT TERM
   103  
   104  # spawn confd in the background to update services based on etcd changes
   105  confd -node $ETCD -config-file /app/confd.toml &
   106  CONFD_PID=$!
   107  
   108  # wait for the service to become available
   109  sleep 1 && while [[ -z $(netstat -lnt | awk "\$6 == \"LISTEN\" && \$4 ~ \".5432\" && \$1 ~ \"tcp.?\"") ]] ; do sleep 1; done
   110  
   111  # perform a one-time reload to populate database entries
   112  /usr/local/bin/reload
   113  
   114  if [[ "${initial_backup}" == "1" ]] ; then
   115    echo "database: performing an initial backup..."
   116    # perform an initial backup
   117    sudo -u postgres envdir /etc/wal-e.d/env wal-e backup-push /var/lib/postgresql/9.3/main
   118  fi
   119  
   120  echo "database: postgres is running..."
   121  
   122  count=1
   123  # publish the service to etcd using the injected HOST and EXTERNAL_PORT
   124  if [[ ! -z $EXTERNAL_PORT ]]; then
   125  	# configure service discovery
   126  	PORT=${PORT:-5432}
   127  	PROTO=${PROTO:-tcp}
   128  
   129  	set +e
   130  
   131  	# wait for the service to become available on PORT
   132  	sleep 1 && while [[ -z $(netstat -lnt | awk "\$6 == \"LISTEN\" && \$4 ~ \".$PORT\" && \$1 ~ \"$PROTO.?\"") ]] ; do sleep 1; done
   133  
   134  	# while the port is listening, publish to etcd
   135  	while [[ ! -z $(netstat -lnt | awk "\$6 == \"LISTEN\" && \$4 ~ \".$PORT\" && \$1 ~ \"$PROTO.?\"") ]] ; do
   136  		etcdctl --no-sync -C $ETCD set $ETCD_PATH/host $HOST --ttl $ETCD_TTL >/dev/null
   137  		etcdctl --no-sync -C $ETCD set $ETCD_PATH/port $EXTERNAL_PORT --ttl $ETCD_TTL >/dev/null
   138  
   139      # perform a backup whenever we hit BACKUP_FREQUENCY
   140      # we really need cron :(
   141      if [[ "${count}" -ge "${BACKUP_FREQUENCY}" ]] ; then
   142        echo "database: performing a backup..."
   143        if [[ -f /var/lib/postgresql/9.3/main/recovery.conf ]] ; then
   144          echo "database: database is currently recovering from a backup. Will try again next loop..."
   145        else
   146          # perform a backup
   147          sudo -u postgres envdir /etc/wal-e.d/env wal-e backup-push /var/lib/postgresql/9.3/main
   148          # only retain the latest BACKUPS_TO_RETAIN backups
   149          sudo -u postgres envdir /etc/wal-e.d/env wal-e delete --confirm retain ${BACKUPS_TO_RETAIN}
   150          count=0
   151        fi
   152      fi
   153      ((count++))
   154  		sleep $(($ETCD_TTL/2)) # sleep for half the TTL
   155  	done
   156  
   157  	# if the loop quits, something went wrong
   158  	exit 1
   159  
   160  fi
   161  
   162  wait