Skip to content
This repository has been archived by the owner on May 13, 2022. It is now read-only.

Commit

Permalink
add Dockerfile and entrypoint.py
Browse files Browse the repository at this point in the history
  • Loading branch information
BlinkyStitt committed Oct 20, 2016
1 parent 38e271d commit 8567431
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.git/
env/
rocker/
joinmarket.cfg
wallets/
.DS_Store
64 changes: 64 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#
# Quick and easy joinmarket
#
# docker build -t "bwstitt/joinmarket:latest" .
#
# Copying of the code is delayed as long as possible so that rebuilding the container while developing is faster
# This also means some of the install steps aren't in the most obvious order and the virtualenv is outside the code
#

FROM bwstitt/library-debian:jessie

# Install packages for joinmarket
RUN docker-apt-install \
gcc \
libsodium13 \
python-dev \
virtualenv

# i needed these when compiling myself, but new versions of pip with wheels save us
#libatlas-dev \
#libblas-dev \
#libfreetype6-dev \
#libpng12-dev \
#libsodium-dev \
#pkg-config \
#python-dev \

# create a user
RUN useradd -ms /bin/bash joinmarket

# install deps that don't depend on the code as the user
USER joinmarket
ENV HOME=/home/joinmarket
WORKDIR /home/joinmarket
# todo: will python3 work?
RUN virtualenv -p python2 ~/pyenv \
&& . ~/pyenv/bin/activate \
&& pip install -U setuptools pip \
&& pip install matplotlib numpy
# todo: do something to calculate font cache with matplotlib
# /home/joinmarket/pyenv/local/lib/python2.7/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.

# install the code
COPY . /home/joinmarket/src/joinmarket
WORKDIR /home/joinmarket/src/joinmarket
COPY docker/entrypoint.py /entrypoint.py
# todo: i wish copy would keep the user...
USER root
RUN chmod 500 /entrypoint.py \
&& chown -R joinmarket:joinmarket \
/entrypoint.py \
/home/joinmarket/src
USER joinmarket

# install deps from the code as the user
RUN . ~/pyenv/bin/activate \
&& pip install -r requirements.txt

# setup data volumes for logs and wallets
# todo: handle the blacklist and commitments
VOLUME ["/home/joinmarket/src/joinmarket/logs", "/home/joinmarket/src/joinmarket/wallets"]

ENTRYPOINT /entrypoint.py
CMD ob_watcher
4 changes: 4 additions & 0 deletions docker/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
todo:
- explain how to setup Tor
- explain how to setup bitcoind
- explain how to setup the config (and figure out how to keep sensitive things out of git)
169 changes: 169 additions & 0 deletions docker/entrypoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#!/home/joinmarket/pyenv/bin/python
"""Entrypoints for Docker containers to run joinmarket.
todo: wait_for_file should probably be a decorator
"""
import argparse
import logging
import os
import os.path
import subprocess
import sys
import time


log = logging.getLogger(__name__)


#
# Helpers
#

DEBUG_LOG_FORMAT = (
'-' * 80 + '\n' +
'%(asctime)s %(levelname)s in %(name)s @ %(threadName)s:\n' +
'%(pathname)s:%(lineno)d\n' +
'%(message)s\n' +
'-' * 80
)
DEFAULT_LOG_FORMAT = '%(asctime)s %(levelname)s: %(threadName)s: %(name)s: %(message)s' # noqa


def run(*args):
"""Run a python command inside the joinmarket virtualenv.
Raises subprocess.CalledProcessError if the command fails.
"""
if not args:
raise ValueError("run needs at least one arg")

command_list = [sys.executable] + map(str, args)

log.info("Running %s...", command_list[1])
log.debug("Full command: %s", command_list)
return subprocess.check_call(command_list, env=os.environ)


def wait_for_file(filename, sleep=10):
"""Sleep until a given file exists."""
if os.path.exists(filename):
return

log.info("'%s' does not exist. Check the README", filename)

while not os.path.exists(filename):
time.sleep(sleep)

log.info("Found '%s'", filename)
return


#
# Commands
#

def get_parser():
"""Create an argument parser that routes to the command functions."""
# create the top-level parser
parser = argparse.ArgumentParser()
# todo: configurable log level
subparsers = parser.add_subparsers()

# create the parser for the "maker" command
parser_maker = subparsers.add_parser('maker')
parser_maker.set_defaults(func=maker)

# create the parser for the "ob_watcher" command
parser_ob_watcher = subparsers.add_parser('ob_watcher')
parser_ob_watcher.set_defaults(func=ob_watcher)

# create the parser for the "sendpayment" command
parser_sendpayment = subparsers.add_parser('sendpayment')
parser_sendpayment.set_defaults(func=sendpayment)

# create the parser for the "taker" command
parser_tumbler = subparsers.add_parser('tumbler')
parser_tumbler.set_defaults(func=tumbler)

# create the parser for the "wallet_tool" command
parser_wallet_tool = subparsers.add_parser('wallet_tool')
parser_wallet_tool.set_defaults(func=wallet_tool)

return parser


def maker(args):
"""Earn Bitcoins and privacy."""
wallet_filename = 'wallets/wallet.json'

wait_for_file(wallet_filename)

# todo: wait for bitcoind to respond

run('yg-pe.py', wallet_filename, *args)


def ob_watcher(args):
"""Watch the orderbook."""
# todo: wait for bitcoind to respond
# todo: although, why does the orderbook need bitcoind?

log.debug("Starting ob-watcher...")
run('ob-watcher.py', *args)


def sendpayment(args):
""""Send Bitcoins with privacy.
todo: make sure we only sendpayment with coins that have already been
joined at least once.
"""
wallet_filename = 'wallets/wallet.json'

wait_for_file(wallet_filename)

# todo: wait for bitcoind to respond

run('sendpayment.py', *args)


def tumbler(args):
""""Send Bitcoins with layers of privacy."""
wallet_filename = 'wallets/wallet.json'

wait_for_file(wallet_filename)

# todo: wait for bitcoind to respond

run('tumbler.py', *args)


def wallet_tool(args):
"""Inspect and manage your Bitcoin wallet."""
run('wallet-tool.py', *args)


def main():
"""Manage joinmarket."""
parser = get_parser()
args, passthrough_args = parser.parse_known_args()

log_level = logging.DEBUG # todo: get log_level from args

if log_level == logging.DEBUG:
log_format = DEBUG_LOG_FORMAT
else:
log_format = DEFAULT_LOG_FORMAT

logging.basicConfig(
format=log_format,
level=log_level,
stream=sys.stdout,
)
log.debug("Hello!")

args.func(passthrough_args)


if __name__ == '__main__':
sys.exit(main())

0 comments on commit 8567431

Please sign in to comment.