I spend way too much time trying to get software not officially support on PowerPC computers running. My latest project is Syncthing. Started in 2013 by Jakob Borg, Syncthing is promoted as an “opensource alternative to proprietary decentralized file sharing services” [1]. The biggest competitor is BitTorrent’s Sync application. The premise for both applications is the same. You pick a folder on your computer or mobile device you want to share to device or user. The application generates cryptographic identifiers that are shared and used for securing traffic. With BitTorrent Sync the identifiers are shared when you start the process of sharing a folder. For Syncthing they are shared when connecting devices together. In the end the result of secure end-to-end communication is accomplished by both applications, jus the roads are a little different.
I’ve been using BTSync for the past year as a way to keep a copy of a KeePass file synced between my computers and my Nexus 5. My KeePass file is something I don’t want to keep up on a service like Google Drive since the cloud is outside of my control. LastPass is a great service, but again, passwords are stored in the cloud and I like control.
The developers of Syncthing are doing a great job of updating the product and releasing versions for the major desktop platforms. Third-party developers have also stepped up and adapted Syncthing to run on Android and support for iOS looks to be on the roadmap [2]. One missing platform, however, is Linux on PPC. I know the market share of for PPC systems is microscopic even if you factor in IBM’s Power line of servers, some of Synology’s NAS products, and the Air Force’s PS3 cluster [3]. That is why I’m still surprised that BitTorrent released a Sync client for Linux PPC until April 2015 [4].
Enough back-story, here is how I got Syncthing running.
Step 0: Install Go
Syncthing is written in the Go programming language. For those who don’t know Go comes from few guys at Google who want something that looked like C, but is better [5]. Its popularity has exploded over the past few years and many applications are being written with it. Of course, to compile an application from source code that was written in Go, you have to have the Go build tools. That is the first problem: the developers of Go do not provide prebuilt tools for Linux PPC. Nobody seems to be building Go packages for Ubuntu yet either. Go 1.5 is the first version to support PPC but that is still listed as a feature in beta/testing. The developers focus on the major platforms like Linux 32/64-bit, Windows, and OS X.
So how does one get Go build tools for PPC? Why you build them of course. No problem, all it takes to build Go is Go… You read that right. You have to build Go using Go. It is really a chicken and egg problem. Obviously Go can’t be built by a PPC system for a PPC system, but there is hope. For 1.5 the developers of Go provide instructions for cross compiling the tools for different platforms [6]. For myself, I have a Ubuntu 14.04 amd64 virtual machine sitting around that can be used to test different software. Using it I can build go for PPC using the instructions.
- Download the tar.gz package of Go 1.4 to the home folder
- Extract the tar bundle. There should now be a folder called go
- Rename the folder to go1.4
- Use git to fetch the source repository from googlesource.com
- Run the bootstrap script to build Go for PPC
- After a few minutes a tar bundle will exist in the home folder called go-linux-ppc64-bootstrap.tbz
- Copy the tar bundle over to the PPC system
With the tools built and copied over, I now need to setup the bash environment to use Go.
- Extract the bundle to /usr/local
- Add the Go bin folder to the PATH variable
Woohoo. I now have Go for PPC. From here on out the process is as if you were building on an Intel box. I run Ubuntu 14.04 so all I have to do is follow the instructions.
Step 1: Build Syncthing
export GOPATH=~
mkdir -p ~/src/github.com/syncthing
cd ~/src/github.com/syncthing
git clone https://github.com/syncthing/syncthing
cd syncthing go run build.go
Step 2: Install Syncthing
cd ~/src/github.com/syncthing
cp syncthing /opt/
useradd -G sharing -m -d /home/syncthing -r -U syncthing
chown -R syncthing:syncthing /opt/syncthing
Step 3: Syncthing Startup Script
I took a startup script provided by the BTSync community and modified it to work with Syncthing.
http://bernaerts.dyndns.org/linux/75-debian/290-debian-server-btsync-permanent-peer
#! /bin/sh
### BEGIN INIT INFO
# Provides: Syncthing daemon
# Required-Start: $syslog
# Required-Stop: $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Syncthing server daemon
# Description: Daemon script to run a Syncthing permanent peer
# Placed in /etc/init.d.
### END INIT INFO
# Author: Nicolas Bernaerts <nicolas.bernaerts@laposte.net>
# Version:
# V1.0, 06/09/2013 - Creation
# V1.1, 09/09/2013 - Use under-priviledged system user
# description variables
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Syncthing server"
NAME="syncthing"
USER=$NAME
GROUP="sharing"
DAEMON=/opt/syncthing/bin/$NAME
DAEMON_OPTS=-gui-address=0.0.0.0:8384
PIDFILE=/var/run/$NAME.pid
# Exit if syncthing program is not installed
if [ ! -x "$DAEMON" ] ; then
echo "Binary $DAEMON does not exist. Aborting"
exit 0
fi
# Exit if syncthing user home directory doesn't exist
#if [ ! -d "$ROOT" ]; then
# echo "User $USER does not exist. Aborting"
# exit 0
#fi
# Function that starts the daemon/service
# 0 - daemon started
# 1 - daemon already running
# 2 - daemon could not be started
do_start()
{
# If needed, start the daemon
if [ -f "$PIDFILE" ]
then
echo "$NAME already running"
RETVAL="1"
else
start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --chuid $USER --group $GROUP --name $NAME --exec $DAEMON -- $DAEMON_OPTS
RETVAL="$?"
[ "$RETVAL" = "0" ] && echo "$NAME started"
fi
return "$RETVAL"
}
# Function that stops the daemon/service
# 0 - daemon stopped
# 1 - daemon already stopped
# 2 - daemon could not be stopped
do_stop()
{
# Stop the daemon
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = "0" ] && echo "$NAME stopped"
[ "$RETVAL" = "1" ] && echo "$NAME was not running"
# remove pid file
rm -f $PIDFILE
return "$RETVAL"
}
# deal with different parameters : start, stop & status
case "$1" in
# start service
start)
do_start
;;
# stop service
stop)
do_stop
;;
# restart service
restart)
do_stop
do_start
;;
# unknown command, display help message
*)
echo "Usage : $SCRIPTNAME {start|stop|restart}" >&2
exit 3
;;
esac
Make startup script executable and load by default
sudo chmod +x /etc/init.d/syncthing
sudo update-rc.d syncthing defaults
Step 4: Update Syncthing
For the packages provided by the developers, Syncthing is updated on an almost weekly basis. My PPC build doesn’t have this luxury, but I can easily automate the process by using a shell script like this one.
service syncthing stop
export GOPATH=$HOME
export GOROOT=/usr/local/go
export PATH=$PATH:/usr/local/go/bin
cd $HOME/src/github.com/syncthing
rm -rf syncthing.old
mv syncthing syncthing.old
git clone --branch v0.11 https://github.com/syncthing/syncthing.git
cd syncthing
/usr/local/go/bin/go run build.go
rm -rf /opt/syncthing.old
cd ../
cp -r syncthing /opt/
chown -R syncthing:syncthing /opt/syncthing
service syncthing start
Conclusion
There you have it. Syncthing compiled and running on a Linux PPC server. All there is left to do is to start sharing some folders between systems.
Have fun.
[1] https://syncthing.net/
[2] http://docs.syncthing.net/users/faq.html
[3] https://en.wikipedia.org/wiki/PlayStation_3_cluster
[4] http://forum.bittorrent.com/topic/38132-powerpc-and-powerpc-qoriq-support/
[5] https://en.wikipedia.org/wiki/Go_(programming_language)
[6] http://golang.org/doc/install/source