Synology DS415+ – Creating a PyCrypto Extensioned Postgres Instance for PostPooks

Written by James McDonald

May 13, 2015

Important Note: Completely ignore this post. See my post at https://toggen.com.au/it-tips/docker-synology-postbooks-postgres

So I just got myself a Synology DS415+ diskstation NAS so I could get rid of my desktop PC. It has what appears to be a very modern Linux Kernel and an x64 atom CPU

synologybox> uname -a
Linux synologybox 3.2.40 #5022 SMP Wed Jan 7 14:19:49 CST 2015 x86_64 GNU/Linux synology_avoton_415+

However the default install of the postgres server doesn’t support the pycrypto extension which is require by Postbooks/xTuple

What follows is the most hacky way of getting an instance of postgress running on synology, that supports pycrypto, and I’m embarrassed at how bad it is

  1. On my Fedora 21 machine, install Postgres from source http://www.xtuple.org/InstallingPostgresFromSource
    1. Remember to compile the contrib extensions
    2. run make install
  2. scp the resulting installation to the Synology box
    scp -r /usr/local/pgsql/9.3.6 root@synologybox:/volume1/folder1/pgsql
  3. Enable the Synology CLI and login to the synology box as root
    ssh -l root synologybox
  4. In the synology web interface create a user named postgres2 which will appear in /etc/passwd as: (in hindsight this should have been pguser or similar because postgres2 is too long for ls -al listings) you might need to vi /etc/passwd and change /sbin/nologin to /bin/sh
    postgres2:x:1027:100::/volume1/folder1/pgsql/9.3.6/data:/bin/sh
  5. Check for missing *.so (shared library) files and copy them from the F21 install to the lib folder
    export PATH=/volume1/folder1/pgsql/9.3.6/bin:$PATH
    export LD_LIBRARY_PATH=/volume1/folder1/pgsql/9.3.6/lib:$LD_LIBRARY_PATH
    
    # run postgres multiple times
    postgres
    
    # that will spit out something link missing libxml2.so.2 libpg etc etc
    # each time it errors out go to the fedora 21 system and copy the 
    # same file to the synology /volume1/folder1/pgsql/9.3.6/lib
    
    # e.g on fedora 21 repeat this command for each missing library
    scp /usr/lib64/libxml2.so.2 root@synologybox:/volume1/folder1/pgsql/9.3.6/lib
  6. Using the start script in postgresql-9.3.6/contrib/start-scripts/linux edit it so that it runs the new postgres instance as the correct user and contains the correct LD_LIBRARY_PATH which will pick up the missing shared libraries:
    #!/bin/sh
    
    # chkconfig: 2345 98 02
    # description: PostgreSQL RDBMS
    
    # This is an example of a start/stop script for SysV-style init, such
    # as is used on Linux systems.  You should edit some of the variables
    # and maybe the 'echo' commands.
    #
    # Place this file at /etc/init.d/postgresql (or
    # /etc/rc.d/init.d/postgresql) and make symlinks to
    #   /etc/rc.d/rc0.d/K02postgresql
    #   /etc/rc.d/rc1.d/K02postgresql
    #   /etc/rc.d/rc2.d/K02postgresql
    #   /etc/rc.d/rc3.d/S98postgresql
    #   /etc/rc.d/rc4.d/S98postgresql
    #   /etc/rc.d/rc5.d/S98postgresql
    # Or, if you have chkconfig, simply:
    # chkconfig --add postgresql
    #
    # Proper init scripts on Linux systems normally require setting lock
    # and pid files under /var/run as well as reacting to network
    # settings, so you should treat this with care.
    
    # Original author:  Ryan Kirkpatrick <pgsql@rkirkpat.net>
    
    # contrib/start-scripts/linux
    
    ## EDIT FROM HERE
    # change the port
    PGPORT=5433
    # Installation prefix
    # change prefix
    prefix=/volume1/folder1/pgsql/9.3.6
    # add the correct library path and then edit the 
    # case statement below to include it for the su -c command
    LD_LIBRARY_PATH=$prefix/lib
    
    # Data directory
    # change the data dir
    PGDATA="/volume1/folder1/pgsql/9.3.6/data"
    
    # Who to run the postmaster as, usually "postgres".  (NOT "root")
    # change the user
    PGUSER=postgres2
    
    # Where to keep a log file
    PGLOG="$PGDATA/serverlog"
    
    # It's often a good idea to protect the postmaster from being killed by the
    # OOM killer (which will tend to preferentially kill the postmaster because
    # of the way it accounts for shared memory).  Setting the OOM_SCORE_ADJ value
    # to -1000 will disable OOM kill altogether.  If you enable this, you probably
    # want to compile PostgreSQL with "-DLINUX_OOM_SCORE_ADJ=0", so that
    # individual backends can still be killed by the OOM killer.
    #OOM_SCORE_ADJ=-1000
    # Older Linux kernels may not have /proc/self/oom_score_adj, but instead
    # /proc/self/oom_adj, which works similarly except the disable value is -17.
    # For such a system, enable this and compile with "-DLINUX_OOM_ADJ=0".
    #OOM_ADJ=-17
    
    ## STOP EDITING HERE
    
    # The path that is to be used for the script
    PATH=$prefix/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    
    # What to use to start up the postmaster.  (If you want the script to wait
    # until the server has started, you could use "pg_ctl start -w" here.
    # But without -w, pg_ctl adds no value.)
    DAEMON="$prefix/bin/postmaster"
    
    # What to use to shut down the postmaster
    PGCTL="$prefix/bin/pg_ctl"
    
    set -e
    
    # Only start if we can find the postmaster.
    test -x $DAEMON ||
    {
    	echo "$DAEMON not found"
    	if [ "$1" = "stop" ]
    	then exit 0
    	else exit 5
    	fi
    }
    
    
    # Parse command line parameters.
    case $1 in
      start)
    	echo -n "Starting PostgreSQL: "
    	test x"$OOM_SCORE_ADJ" != x && echo "$OOM_SCORE_ADJ" > /proc/self/oom_score_adj
    	test x"$OOM_ADJ" != x && echo "$OOM_ADJ" > /proc/self/oom_adj
    	su - $PGUSER -c "LD_LIBRARY_PATH=$LD_LIBRARY_PATH $DAEMON -D '$PGDATA' -p $PGPORT &" >>$PGLOG 2>&1
    	echo "ok"
    	;;
      stop)
    	echo -n "Stopping PostgreSQL: "
    	su - $PGUSER -c "LD_LIBRARY_PATH=$LD_LIBRARY_PATH $PGCTL stop -D '$PGDATA' -s -m fast"
    	echo "ok"
    	;;
      restart)
    	echo -n "Restarting PostgreSQL: "
    	su - $PGUSER -c "LD_LIBRARY_PATH=$LD_LIBRARY_PATH $PGCTL stop -D '$PGDATA' -s -m fast -w"
    	test x"$OOM_SCORE_ADJ" != x && echo "$OOM_SCORE_ADJ" > /proc/self/oom_score_adj
    	test x"$OOM_ADJ" != x && echo "$OOM_ADJ" > /proc/self/oom_adj
    	su - $PGUSER -c "LD_LIBRARY_PATH=$LD_LIBRARY_PATH $DAEMON -D '$PGDATA' -p $PGPORT &" >>$PGLOG 2>&1
    	echo "ok"
    	;;
      reload)
            echo -n "Reload PostgreSQL: "
            su - $PGUSER -c "LD_LIBRARY_PATH=$LD_LIBRARY_PATH $PGCTL reload -D '$PGDATA' -s"
            echo "ok"
            ;;
      status)
    	su - $PGUSER -c "LD_LIBRARY_PATH=$LD_LIBRARY_PATH $PGCTL status -D '$PGDATA'"
    	;;
      *)
    	# Print help
    	echo "Usage: $0 {start|stop|restart|reload|status}" 1>&2
    	exit 1
    	;;
    esac
    
    exit 0
  7. copy the linux startup-script to /volume1/folder1/pgsql/9.3.6/bin and mark it executeable
  8. To put everything under the pgsql instance I created a data dir under the install prefix
    mkdir /volume1/folder1/pgsql/9.3.6/data
    chown postgres2 data -R
  9. Once you have everything ready you need to init the instance which creates all the necessary files (e.g. pg_hba.conf, postgresql)
    prefix=/volume1/folder1/pgsql/9.3.6
    LD_LIBRARY_PATH=$prefix/lib
    PATH=$prefix/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/syno/sbin:/usr/syno/bin:/usr/local/sbin:/usr/local/bin
    PGDATA=$prefix/data
    
    export LD_LIBRARY_PATH PATH PGDATA
    
    cd $prefix
    
    bin/initdb
    
  10. If initdb complains of PG_VERSION not existing in $prefix/data
    cd $prefix/data
    su - postgres2 -c "echo 9.3 > PG_VERSION"
  11. You need to allow postgres to listen on the network interface and remote md5 hashed password connections by editing pg_hba.conf
    # TYPE  DATABASE        USER            ADDRESS                 METHOD
    # "local" is for Unix domain socket connections only
    local   all             all                                     trust
    # IPv4 local connections:
    host    all             all             127.0.0.1/32            trust
    # IPv6 local connections:
    host    all             all             ::1/128                 trust
    # Allow replication connections from localhost, by a user with the
    # replication privilege.
    #local   replication     postgres2                                trust
    #host    replication     postgres2        127.0.0.1/32            trust
    #host    replication     postgres2        ::1/128                 trust
    # add this line
    host 	all		all		0.0.0.0/0		md5
    
  12. Once every thing is setup you can run your postgres instance
    synologybox> cd /volume1/folder1/pgsql/9.3.6
    synologybox> bin/linux
    Starting PostgreSQL: ok 
    synologybox> bin/linux status
    pg_ctl: server is running (PID: 16658) /volume1/folder1/pgsql/9.3.6/bin/postmaster "-D" "/volume1/folder1/pgsql/9.3.6/data" "-p" "5433"
    synologybox>
  13. And from there create a new user
    You also need to create a superuser for postgres
    # need the correct env to run postgres
    createuser -h localhost -p 5433 --pwprompt --superuser --createdb --createrole admin
    
    # or easier with prompts
    createuser -h localhost -p 5433 --interactive admin
  14. Finally make sure that the potgres server starts at boot http://forum.synology.com/enu/viewtopic.php?f=40&t=51025 **I haven’t as yet tested if this works because I am doing a 3TB copy and it’s not finished and I can’t reboot the Synology
    synologybox> ln -sf /volume1/folder1/pgsql/9.3.6/bin/linux /usr/local/etc/rc.d/progres.sh
  15. You will need to use something like pgadmin to restore your PostBooks db and create the pycrypto extension
  16. Finally you can test the Postbooks client from a remote host….

1 Comment

  1. Adrian Schiopu

    hello
    I want to install Postgresql 9.6.12 on my synology nas DS218+ (intel inside) as a second instance of PostgreSQL. preinstalled version is 9.3.22. (NOT docker version)
    I downloaded PostgreSQL from: https://www.enterprisedb.com/downloads/postgres-postgresql-downloads and install it on /volume1/pgsql_9.6.12.
    Everything is ok until “initdb”.
    I got this error:

    root@PACS:/volume1/pgsql_9.6.12# sudo /bin/initdb
    Fail to read result of ‘/bin/get_key_value /etc/synoinfo.conf usbstation’
    initdb: no data directory specified
    You must identify the directory where the data for this database system
    will reside. Do this with either the invocation option -D or the
    environment variable PGDATA

    Can you help me to solve this problem?
    Thanks in advance

    Reply

Trackbacks/Pingbacks

  1. Installing Postgres 9.x for Postbooks on Synology Diskstation with Docker | The Southern IT Observer - […] wrote a post about hacking another instance of Postgres onto the Synology Diskstation. But now that Synology has docker…

Submit a Comment

Your email address will not be published. Required fields are marked *

You May Also Like…