diff --git a/MANIFEST.in b/MANIFEST.in
index ab9357e6282af45440a11fedf8426b582ea2689d..78eff2924e98278051a61db8cb33d0cdfea80b89 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -13,3 +13,5 @@ recursive-include rattail/db/alembic *.mako
recursive-include rattail/db/alembic *.py
recursive-include rattail/templates/mail *.mako
+
+recursive-include rattail/fablib/deploy *
diff --git a/data/var/lib/rattail/init.d/dbsync b/data/var/lib/rattail/init.d/dbsync
deleted file mode 100644
index 7c8f25782376ef0273b4ae82eef2bf371942ef19..0000000000000000000000000000000000000000
--- a/data/var/lib/rattail/init.d/dbsync
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/bin/sh
-# -*- coding: utf-8 -*-
-################################################################################
-#
-# Rattail -- Retail Software Framework
-# Copyright © 2010-2012 Lance Edgar
-#
-# This file is part of Rattail.
-#
-# Rattail is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Affero General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option)
-# any later version.
-#
-# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
-# more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Rattail. If not, see .
-#
-################################################################################
-
-
-# This script is mostly based on the ``/etc/init.d/skeleton`` file from a
-# Debian 6 system.
-
-
-DESC=${DESC:-"Rattail Database Synchronizer"}
-NAME=${NAME:-"rattail-dbsync"}
-SCRIPTNAME=${SCRIPTNAME:-"/etc/init.d/$NAME"}
-PIDFILE=${PIDFILE:-"/var/run/rattail/$NAME.pid"}
-
-PYTHON=${PYTHON:-"/usr/bin/python"}
-RATTAIL=${RATTAIL:-"/usr/local/bin/rattail"}
-RATTAIL_ARGS=${RATTAIL_ARGS:-""}
-DBSYNC_ARGS=${DBSYNC_ARGS:-"--pidfile=$PIDFILE"}
-
-USER=${USER:-"rattail"}
-GROUP=${GROUP:-"rattail"}
-
-
-# Read configuration variable files if present.
-[ -r /etc/default/rattail ] && . /etc/default/rattail
-[ -r /etc/default/$NAME ] && . /etc/default/$NAME
-
-# Load the VERBOSE setting and other rcS variables.
-. /lib/init/vars.sh
-
-# Define LSB log_* functions.
-# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
-# and status_of_proc is working.
-. /lib/lsb/init-functions
-
-
-create_pid_dir() {
- PIDDIR=`dirname "$PIDFILE"`
- if [ ! -d "$PIDDIR" ]; then
- mkdir --parents "$PIDDIR"
- fi
- chown $USER:$GROUP "$PIDDIR"
-}
-
-
-#
-# Function that starts the daemon/service
-#
-do_start()
-{
- # Return
- # 0 if daemon has been started
- # 1 if daemon was already running
- # 2 if daemon could not be started
- create_pid_dir
- start-stop-daemon --start --pidfile $PIDFILE --exec $PYTHON --user $USER --test --quiet > /dev/null \
- || return 1
- start-stop-daemon --start --pidfile $PIDFILE --exec $PYTHON --startas $RATTAIL --chuid $USER --group $GROUP --quiet -- \
- $RATTAIL_ARGS dbsync $DBSYNC_ARGS start \
- || return 2
-}
-
-
-#
-# Function that stops the daemon/service
-#
-do_stop()
-{
- # Return
- # 0 if daemon has been stopped
- # 1 if daemon was already stopped
- # 2 if daemon could not be stopped
- # other if a failure occurred
- sudo -u $USER $RATTAIL $RATTAIL_ARGS dbsync $DBSYNC_ARGS stop > /dev/null 2>&1
-}
-
-
-case "$1" in
- start)
- [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
- do_start
- case "$?" in
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
- esac
- ;;
- stop)
- [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
- do_stop
- case "$?" in
- 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
- 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
- esac
- ;;
- status)
- status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
- ;;
- restart|force-reload)
- log_daemon_msg "Restarting $DESC" "$NAME"
- do_stop
- case "$?" in
- 0|1)
- do_start
- case "$?" in
- 0) log_end_msg 0 ;;
- 1) log_end_msg 1 ;; # Old process is still running
- *) log_end_msg 1 ;; # Failed to start
- esac
- ;;
- *)
- # Failed to stop
- log_end_msg 1
- ;;
- esac
- ;;
- *)
- echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
- exit 3
- ;;
-esac
-
-:
diff --git a/rattail/contrib/init.d/bouncer b/rattail/fablib/deploy/bouncer
similarity index 100%
rename from rattail/contrib/init.d/bouncer
rename to rattail/fablib/deploy/bouncer
diff --git a/rattail/contrib/init.d/datasync b/rattail/fablib/deploy/datasync
similarity index 100%
rename from rattail/contrib/init.d/datasync
rename to rattail/fablib/deploy/datasync
diff --git a/data/var/lib/rattail/init.d/filemon b/rattail/fablib/deploy/filemon
similarity index 100%
rename from data/var/lib/rattail/init.d/filemon
rename to rattail/fablib/deploy/filemon
diff --git a/rattail/fablib/pod.py b/rattail/fablib/pod.py
index c05faac8edde8b852a10b9c0a6153a7521e97c29..99c7138b69652c2217f33ec24d96b4384b248c90 100644
--- a/rattail/fablib/pod.py
+++ b/rattail/fablib/pod.py
@@ -25,6 +25,7 @@ Fabric Library for Product Open Data (POD)
"""
from __future__ import unicode_literals
+from __future__ import absolute_import
from fabric.api import sudo, cd, env
from fabric.contrib.files import exists
diff --git a/rattail/fablib/python.py b/rattail/fablib/python.py
index 86faf1563530e6f80ac5ed73bf4b64a11fdd4528..13ddc0652cc255df7eb0531a2cff834f755546b8 100644
--- a/rattail/fablib/python.py
+++ b/rattail/fablib/python.py
@@ -25,6 +25,7 @@ Fabric Library for Python
"""
from __future__ import unicode_literals
+from __future__ import absolute_import
from contextlib import contextmanager
diff --git a/rattail/fablib/rattail.py b/rattail/fablib/rattail.py
new file mode 100644
index 0000000000000000000000000000000000000000..e698e25bc79099699494c31462020d383164cbe2
--- /dev/null
+++ b/rattail/fablib/rattail.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Rattail -- Retail Software Framework
+# Copyright © 2010-2015 Lance Edgar
+#
+# This file is part of Rattail.
+#
+# Rattail is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Rattail. If not, see .
+#
+################################################################################
+"""
+Fabric library for Rattail itself
+"""
+
+from __future__ import unicode_literals
+from __future__ import absolute_import
+
+from fabric.api import sudo, env
+
+from rattail.fablib import make_deploy, make_system_user, mkdir
+
+
+deploy = make_deploy(__file__)
+
+
+def bootstrap_rattail(home='/var/lib/rattail', shell='/bin/bash', alias=True):
+ """
+ Bootstrap a basic Rattail software environment.
+ """
+ make_system_user('rattail', home=home, shell=shell, alias=alias)
+ sudo('adduser {0} rattail'.format(env.user))
+
+ mkdir('/etc/rattail')
+ mkdir('/srv/rattail')
+ mkdir('/var/log/rattail', owner='rattail:rattail', mode='0775')
+
+ mkdir('/srv/rattail/init')
+ deploy('filemon', '/srv/rattail/init/filemon')
+ deploy('datasync', '/srv/rattail/init/datasync')
+ deploy('bouncer', '/srv/rattail/init/bouncer')
diff --git a/rattail/fablib/ssh.py b/rattail/fablib/ssh.py
index 4c308269149b1f6749fc1898857259bff33319cf..9a39f4b589554a408718606f9b73768b3645b852 100644
--- a/rattail/fablib/ssh.py
+++ b/rattail/fablib/ssh.py
@@ -25,6 +25,7 @@ Fabric Library for SSH
"""
from __future__ import unicode_literals
+from __future__ import absolute_import
from fabric.api import *
from fabric.contrib.files import exists, sed