From 41761f60439fb740189da574e6cd82a842883166 Mon Sep 17 00:00:00 2001 From: Rik Veenboer Date: Thu, 18 Dec 2014 12:18:17 +0000 Subject: [PATCH] Combine with files from virtual working directory --- .gitignore | 1 + build/config | 2 +- images/base/bin/app | 19 ++ images/base/bin/run | 7 + images/base/bin/ssh | 24 ++ images/base/id_rsa | 27 ++ images/btsync/Dockerfile | 5 + images/btsync/bin/app | 19 ++ images/btsync/bin/run | 7 + images/btsync/bin/ssh | 24 ++ images/btsync/build/boot/00_hosts.sh | 4 + images/btsync/build/config | 3 + images/btsync/build/init | 314 +++++++++++++++++++ images/btsync/build/runit/btsync | 8 + images/btsync/build/runit/cron | 2 + images/btsync/build/runit/sshd | 2 + images/btsync/build/runit/syslog | 24 ++ images/btsync/build/scripts/00_prepare.sh | 39 +++ images/btsync/build/scripts/01_boot.sh | 8 + images/btsync/build/scripts/01_cron.sh | 13 + images/btsync/build/scripts/01_init.sh | 12 + images/btsync/build/scripts/01_logrotate.sh | 7 + images/btsync/build/scripts/01_runit.sh | 7 + images/btsync/build/scripts/01_sshd.sh | 28 ++ images/btsync/build/scripts/01_syslog.sh | 11 + images/btsync/build/scripts/02_hosts.sh | 13 + images/btsync/build/scripts/02_utilities.sh | 10 + images/btsync/build/scripts/03_btsync.sh | 21 ++ images/btsync/build/scripts/99_cleanup.sh | 10 + images/btsync/fs/etc/btsync.conf | 70 +++++ images/firefox/bin/app | 19 ++ images/firefox/bin/run | 7 + images/firefox/bin/ssh | 24 ++ images/firefox/id_rsa | 27 ++ images/hamachi/Dockerfile | 5 + images/hamachi/bin/app | 19 ++ images/hamachi/bin/run | 7 + images/hamachi/bin/ssh | 24 ++ images/hamachi/build/boot/00_hosts.sh | 4 + images/hamachi/build/boot/01_hamachi.sh | 5 + images/hamachi/build/config | 3 + images/hamachi/build/init | 314 +++++++++++++++++++ images/hamachi/build/runit/cron | 2 + images/hamachi/build/runit/hamachi | 4 + images/hamachi/build/runit/sshd | 2 + images/hamachi/build/runit/syslog | 24 ++ images/hamachi/build/scripts/00_prepare.sh | 39 +++ images/hamachi/build/scripts/01_boot.sh | 8 + images/hamachi/build/scripts/01_cron.sh | 13 + images/hamachi/build/scripts/01_init.sh | 12 + images/hamachi/build/scripts/01_logrotate.sh | 7 + images/hamachi/build/scripts/01_runit.sh | 7 + images/hamachi/build/scripts/01_sshd.sh | 28 ++ images/hamachi/build/scripts/01_syslog.sh | 11 + images/hamachi/build/scripts/02_hosts.sh | 13 + images/hamachi/build/scripts/02_utilities.sh | 10 + images/hamachi/build/scripts/03_hamachi.sh | 18 ++ images/hamachi/build/scripts/99_cleanup.sh | 10 + images/hamachi/fs/bin/proxy | 3 + images/hamachi/id_rsa | 27 ++ 60 files changed, 1436 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 images/base/bin/app create mode 100644 images/base/bin/run create mode 100644 images/base/bin/ssh create mode 100644 images/base/id_rsa create mode 100644 images/btsync/Dockerfile create mode 100644 images/btsync/bin/app create mode 100644 images/btsync/bin/run create mode 100644 images/btsync/bin/ssh create mode 100644 images/btsync/build/boot/00_hosts.sh create mode 100644 images/btsync/build/config create mode 100644 images/btsync/build/init create mode 100644 images/btsync/build/runit/btsync create mode 100644 images/btsync/build/runit/cron create mode 100644 images/btsync/build/runit/sshd create mode 100644 images/btsync/build/runit/syslog create mode 100644 images/btsync/build/scripts/00_prepare.sh create mode 100644 images/btsync/build/scripts/01_boot.sh create mode 100644 images/btsync/build/scripts/01_cron.sh create mode 100644 images/btsync/build/scripts/01_init.sh create mode 100644 images/btsync/build/scripts/01_logrotate.sh create mode 100644 images/btsync/build/scripts/01_runit.sh create mode 100644 images/btsync/build/scripts/01_sshd.sh create mode 100644 images/btsync/build/scripts/01_syslog.sh create mode 100644 images/btsync/build/scripts/02_hosts.sh create mode 100644 images/btsync/build/scripts/02_utilities.sh create mode 100644 images/btsync/build/scripts/03_btsync.sh create mode 100644 images/btsync/build/scripts/99_cleanup.sh create mode 100644 images/btsync/fs/etc/btsync.conf create mode 100644 images/firefox/bin/app create mode 100644 images/firefox/bin/run create mode 100644 images/firefox/bin/ssh create mode 100644 images/firefox/id_rsa create mode 100644 images/hamachi/Dockerfile create mode 100644 images/hamachi/bin/app create mode 100644 images/hamachi/bin/run create mode 100644 images/hamachi/bin/ssh create mode 100644 images/hamachi/build/boot/00_hosts.sh create mode 100644 images/hamachi/build/boot/01_hamachi.sh create mode 100644 images/hamachi/build/config create mode 100644 images/hamachi/build/init create mode 100644 images/hamachi/build/runit/cron create mode 100644 images/hamachi/build/runit/hamachi create mode 100644 images/hamachi/build/runit/sshd create mode 100644 images/hamachi/build/runit/syslog create mode 100644 images/hamachi/build/scripts/00_prepare.sh create mode 100644 images/hamachi/build/scripts/01_boot.sh create mode 100644 images/hamachi/build/scripts/01_cron.sh create mode 100644 images/hamachi/build/scripts/01_init.sh create mode 100644 images/hamachi/build/scripts/01_logrotate.sh create mode 100644 images/hamachi/build/scripts/01_runit.sh create mode 100644 images/hamachi/build/scripts/01_sshd.sh create mode 100644 images/hamachi/build/scripts/01_syslog.sh create mode 100644 images/hamachi/build/scripts/02_hosts.sh create mode 100644 images/hamachi/build/scripts/02_utilities.sh create mode 100644 images/hamachi/build/scripts/03_hamachi.sh create mode 100644 images/hamachi/build/scripts/99_cleanup.sh create mode 100644 images/hamachi/fs/bin/proxy create mode 100644 images/hamachi/id_rsa diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1fd071f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/images/*/fs/var/* \ No newline at end of file diff --git a/build/config b/build/config index e386f1b..0085fd0 100644 --- a/build/config +++ b/build/config @@ -1,3 +1,3 @@ -nnexport LC_ALL=C +export LC_ALL=C export DEBIAN_FRONTEND=noninteractive minimal_apt_get_install='apt-get install -y --no-install-recommends' diff --git a/images/base/bin/app b/images/base/bin/app new file mode 100644 index 0000000..8c823a5 --- /dev/null +++ b/images/base/bin/app @@ -0,0 +1,19 @@ +ARGS="-v /root/.config/pulse:/root/.config/pulse" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +while : ; do + ID=`docker ps --no-trunc | grep $CONTAINER: | cut -d' ' -f1` + if [ -n "$ID" ]; then + break + fi + if [ ! -n "$STARTED" ]; then + echo "Starting container." + /opt/docker/bin/run $CONTAINER & + STARTED=yes + sleep 10 + fi +done +/opt/docker/bin/ssh $CONTAINER $1 "source .profile; /opt/$CONTAINER" diff --git a/images/base/bin/run b/images/base/bin/run new file mode 100644 index 0000000..edb24cf --- /dev/null +++ b/images/base/bin/run @@ -0,0 +1,7 @@ +ARGS="" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +/opt/docker/bin/run -t $CONTAINER "$ARGS" $1 "$2" diff --git a/images/base/bin/ssh b/images/base/bin/ssh new file mode 100644 index 0000000..14a9c00 --- /dev/null +++ b/images/base/bin/ssh @@ -0,0 +1,24 @@ +ARGS="" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +ID=`docker ps --no-trunc | grep $CONTAINER: | cut -d' ' -f1` +if [ -n "$ID" ]; then + IP=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $ID` + COMMAND="ssh -X -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i id_rsa $ARGS root@$IP" + if [ ! -e id_rsa ]; then + docker cp $ID:/opt/id_rsa . + fi + if [ ! -z "$1" ] && [ "$1" == "-l" ]; then + DISPLAY=:0 + chmod 0666 id_rsa + su user -c "$COMMAND \"$2\"" + else + chmod 0600 id_rsa + eval "$COMMAND \"$1\"" + fi +else + echo "Container is not running." +fi \ No newline at end of file diff --git a/images/base/id_rsa b/images/base/id_rsa new file mode 100644 index 0000000..e2b2903 --- /dev/null +++ b/images/base/id_rsa @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAuyD/PEkf8B0nYKIrKNVUJwB9NbB0fXyUf0K1wEc2NZU1LiCu +K9vhQRJaYuAfJKc+ROOW2bhnawya6tPybmOgk01FiM/ZyIqkQlQcZSatd1MbLwWb +M3OX1NM6fCNwqs0Yb8Ldh+WGeXrHoG2NW5v2c6R6iy7k3NVsdjTb2bHhEc3ttyMD ++GKdAk0zx1rorVFSWSjZz7tbHWQhacqbNUES/ELxvKcki2lCt7oGKdJl2AGSY0ut +mDXTCVfibH9eKmRQr0hiIBIjAu1wQGUWJs0mTmbF15hEk0jYy8ZSZJVIfgUzpIqO +rnMJSfyvjRfxuB4ItO1MN1A82iJp5iwoBeEZzwIDAQABAoIBAEkor2DMXfYsD7cR +77m5HXtaD5mr8P8Wc6AFXrVboe/086OjFzUCc+BS4o+Be+uCjy+zoshf9d6+QNrK +Hh/WR3MPZL4GNOjYezuLUsahBnR+Q0Rw9qp46MVGB7l8yZGdOY6IKr/0lkxsGhu4 +eOl14jZ3+YjsvoEv14WnSMSlbI7evfkFleQdOMAlxy28+DsIcJUa7tqqrlGmns52 +hyYiMF70Bzc7oLLIp9na8/i2RrcaPs7mQ6vkBv6j7xPAbQuSNrZCT0Vwlp4CCBeL +kHutuGhIgBWQ+mZNI+vFg0OV1PJE8spsETSPfT+b2Mk2n6oeoSmqhXW228iCjWze +FHadLXECgYEA7X7eOvopul60NFcUbqt/jttwwOiMcSL78EFos1S90Dl2D05TezIy +3vU2zfFQKuufVTSZirvrbTy/KkxyEalDzDG8RlS47CXup0HjMSddZlgVEFVvNk9x +UeUFoQFGWnxtuK1DX4nGFkd0LII1+BED4HpeMf1rKdd28GgulLoqWDUCgYEAybWB +Z2Zhrn18MHYWvOjaqOshRG3991flsxhiAnKS5v0Gu6vyBq8lI1669BUoF+ZRwQmj +EDwmuC6F6xCHvuLZty6f+efs4weDIWHnyWObwE1GfrcBHEKbiUpK9relFyE+3ara +68FBCzzzvFzWk4NZlv2YNA/EkTVSq+okfRaA0nMCgYABj9cITkLd/edzfKseuzQA +jYLlUeIykEdV4ig9Ha6N4wLawOodokvhWX19xzt+vMP0fH8SAYBf3IlpTs1lPla6 +zgzt7Xq12t4B7ZX/6cFcffHNhLJRih41qqrpzydWSwExuLn7s91AokGqVUTjl8EN +xeA+terxgIBAvn6n7b1/jQKBgQC07xZjzQfEQJW81sCwteMmcLwHqO6OB49o5m9M +KMAzaTa385YHfuY+YwQqXCv5vEULdnyJ3JsSzdCcudg6VzzaP32K6wqn3541vJ/x +G2OjzO12Tuw1EF56eWTjCHqTU+QTbOYxYcnZrdQo29IywjkD4vi7goVdh8pfoYkX +l674lwKBgEJPPaWsBuf5ECqnLhOnkVPOe/riti379CpkSEAp7N6cnKGLvTSNzw6C +35ejiQ37vOnxQgK0n7L/HSue5ZCAnSK2OFtZKkPmILipmnxt+RHsfKQm8uaspQ5n +a5TT6MegGgkTIXh4Jr5cJRkaXTYE9l+yXFrfzW1xgBgcgvVtHyZ8 +-----END RSA PRIVATE KEY----- diff --git a/images/btsync/Dockerfile b/images/btsync/Dockerfile new file mode 100644 index 0000000..7cbfb1b --- /dev/null +++ b/images/btsync/Dockerfile @@ -0,0 +1,5 @@ +FROM ubuntu:precise + +ADD build /build + +RUN for s in /build/scripts/*.sh; do [ -x $s ] && $s || : ; done \ No newline at end of file diff --git a/images/btsync/bin/app b/images/btsync/bin/app new file mode 100644 index 0000000..8c823a5 --- /dev/null +++ b/images/btsync/bin/app @@ -0,0 +1,19 @@ +ARGS="-v /root/.config/pulse:/root/.config/pulse" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +while : ; do + ID=`docker ps --no-trunc | grep $CONTAINER: | cut -d' ' -f1` + if [ -n "$ID" ]; then + break + fi + if [ ! -n "$STARTED" ]; then + echo "Starting container." + /opt/docker/bin/run $CONTAINER & + STARTED=yes + sleep 10 + fi +done +/opt/docker/bin/ssh $CONTAINER $1 "source .profile; /opt/$CONTAINER" diff --git a/images/btsync/bin/run b/images/btsync/bin/run new file mode 100644 index 0000000..b955881 --- /dev/null +++ b/images/btsync/bin/run @@ -0,0 +1,7 @@ +ARGS="-p 8888:8888 -v /opt/docker/images/btsync/fs:/host" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +/opt/docker/bin/run -t $CONTAINER "$ARGS" $1 "$2" diff --git a/images/btsync/bin/ssh b/images/btsync/bin/ssh new file mode 100644 index 0000000..14a9c00 --- /dev/null +++ b/images/btsync/bin/ssh @@ -0,0 +1,24 @@ +ARGS="" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +ID=`docker ps --no-trunc | grep $CONTAINER: | cut -d' ' -f1` +if [ -n "$ID" ]; then + IP=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $ID` + COMMAND="ssh -X -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i id_rsa $ARGS root@$IP" + if [ ! -e id_rsa ]; then + docker cp $ID:/opt/id_rsa . + fi + if [ ! -z "$1" ] && [ "$1" == "-l" ]; then + DISPLAY=:0 + chmod 0666 id_rsa + su user -c "$COMMAND \"$2\"" + else + chmod 0600 id_rsa + eval "$COMMAND \"$1\"" + fi +else + echo "Container is not running." +fi \ No newline at end of file diff --git a/images/btsync/build/boot/00_hosts.sh b/images/btsync/build/boot/00_hosts.sh new file mode 100644 index 0000000..cf95dc4 --- /dev/null +++ b/images/btsync/build/boot/00_hosts.sh @@ -0,0 +1,4 @@ +#!/bin/bash +set -e +echo "127.0.0.1 localhost" >> /tmp/hosts +echo "$HOST_ADDR host" >> /tmp/hosts diff --git a/images/btsync/build/config b/images/btsync/build/config new file mode 100644 index 0000000..0085fd0 --- /dev/null +++ b/images/btsync/build/config @@ -0,0 +1,3 @@ +export LC_ALL=C +export DEBIAN_FRONTEND=noninteractive +minimal_apt_get_install='apt-get install -y --no-install-recommends' diff --git a/images/btsync/build/init b/images/btsync/build/init new file mode 100644 index 0000000..5b56e0b --- /dev/null +++ b/images/btsync/build/init @@ -0,0 +1,314 @@ +#!/usr/bin/python2 -u +import os, os.path, sys, stat, signal, errno, argparse, time, json, re, posixfile + +KILL_PROCESS_TIMEOUT = 5 +KILL_ALL_PROCESSES_TIMEOUT = 5 + +LOG_LEVEL_ERROR = 1 +LOG_LEVEL_WARN = 1 +LOG_LEVEL_INFO = 2 +LOG_LEVEL_DEBUG = 3 + +log_level = None + +class AlarmException(Exception): + pass + +def error(message): + if log_level >= LOG_LEVEL_ERROR: + sys.stderr.write("*** %s\n" % message) + +def warn(message): + if log_level >= LOG_LEVEL_WARN: + print("*** %s" % message) + +def info(message): + if log_level >= LOG_LEVEL_INFO: + print("*** %s" % message) + +def debug(message): + if log_level >= LOG_LEVEL_DEBUG: + print("*** %s" % message) + +def ignore_signals_and_raise_keyboard_interrupt(signame): + signal.signal(signal.SIGTERM, signal.SIG_IGN) + signal.signal(signal.SIGINT, signal.SIG_IGN) + raise KeyboardInterrupt(signame) + +def raise_alarm_exception(): + raise AlarmException('Alarm') + +def listdir(path): + try: + result = os.stat(path) + except OSError: + return [] + if stat.S_ISDIR(result.st_mode): + return sorted(os.listdir(path)) + else: + return [] + +def is_exe(path): + try: + return os.path.isfile(path) and os.access(path, os.X_OK) + except OSError: + return False + +def import_envvars(clear_existing_environment = True): + new_env = {} + for envfile in listdir("/etc/container_environment"): + name = os.path.basename(envfile) + with open("/etc/container_environment/" + envfile, "r") as f: + value = f.read() + new_env[name] = value + if clear_existing_environment: + os.environ.clear() + for name, value in new_env.items(): + os.environ[name] = value + +def export_envvars(to_dir = True): + shell_dump = "" + for name, value in os.environ.items(): + if to_dir: + with open("/etc/container_environment/" + name, "w") as f: + f.write(value) + shell_dump += "export " + shquote(name) + "=" + shquote(value) + "\n" + with open("/etc/container_environment.sh", "w") as f: + f.write(shell_dump) + with open("/etc/container_environment.json", "w") as f: + f.write(json.dumps(dict(os.environ))) + +_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search + +def shquote(s): + """Return a shell-escaped version of the string *s*.""" + if not s: + return "''" + if _find_unsafe(s) is None: + return s + + # use single quotes, and put single quotes into double quotes + # the string $'b is then quoted as '$'"'"'b' + return "'" + s.replace("'", "'\"'\"'") + "'" + +def waitpid_reap_other_children(pid): + done = False + status = None + try: + this_pid, status = os.waitpid(pid, os.WNOHANG) + except OSError as e: + if e.errno == errno.ECHILD or e.errno == errno.ESRCH: + return None + else: + raise + while not done: + this_pid, status = os.waitpid(-1, 0) + done = this_pid == pid + return status + +def stop_child_process(name, pid, signo = signal.SIGTERM, time_limit = KILL_PROCESS_TIMEOUT): + info("Shutting down %s (PID %d)..." % (name, pid)) + try: + os.kill(pid, signo) + except OSError: + pass + signal.alarm(time_limit) + try: + try: + waitpid_reap_other_children(pid) + except OSError: + pass + except AlarmException: + warn("%s (PID %d) did not shut down in time. Forcing it to exit." % (name, pid)) + try: + os.kill(pid, signal.SIGKILL) + except OSError: + pass + try: + waitpid_reap_other_children(pid) + except OSError: + pass + finally: + signal.alarm(0) + +def run_command_killable(*argv): + filename = argv[0] + status = None + pid = os.spawnvp(os.P_NOWAIT, filename, argv) + try: + status = waitpid_reap_other_children(pid) + except BaseException as s: + warn("An error occurred. Aborting.") + stop_child_process(filename, pid) + raise + if status != 0: + if status is None: + error("%s exited with unknown status\n" % filename) + else: + error("%s failed with status %d\n" % (filename, os.WEXITSTATUS(status))) + sys.exit(1) + +def run_command_killable_and_import_envvars(*argv): + run_command_killable(*argv) + import_envvars() + export_envvars(False) + +def kill_all_processes(time_limit): + info("Killing all processes...") + try: + os.kill(-1, signal.SIGTERM) + except OSError: + pass + signal.alarm(time_limit) + try: + # Wait until no more child processes exist. + done = False + while not done: + try: + os.waitpid(-1, 0) + except OSError as e: + if e.errno == errno.ECHILD: + done = True + else: + raise + except AlarmException: + warn("Not all processes have exited in time. Forcing them to exit.") + try: + os.kill(-1, signal.SIGKILL) + except OSError: + pass + finally: + signal.alarm(0) + +def run_startup_files(): + # Run /opt/init.d/* + for name in listdir("/opt/init.d"): + filename = "/opt/init.d/" + name + if is_exe(filename): + info("Running %s..." % filename) + run_command_killable_and_import_envvars(filename) + + # Run /etc/rc.local. + if is_exe("/etc/rc.local"): + info("Running /etc/rc.local...") + run_command_killable_and_import_envvars("/etc/rc.local") + +def start_runit(): + info("Booting runit daemon...") + pid = os.spawnl(os.P_NOWAIT, "/usr/bin/runsvdir", "/usr/bin/runsvdir", + "-P", "/etc/service", "log: %s" % ('.' * 395)) + info("Runit started as PID %d" % pid) + return pid + +def wait_for_runit_or_interrupt(pid): + try: + status = waitpid_reap_other_children(pid) + return (True, status) + except KeyboardInterrupt: + return (False, None) + +def shutdown_runit_services(): + debug("Begin shutting down runit services...") + os.system("/usr/bin/sv down /etc/service/*") + +def wait_for_runit_services(): + debug("Waiting for runit services to exit...") + done = False + while not done: + done = os.system("/usr/bin/sv status /etc/service/* | grep -q '^run:'") != 0 + if not done: + time.sleep(0.1) + +def install_insecure_key(): + info("Installing insecure SSH key for user root") + run_command_killable("/usr/sbin/enable_insecure_key") + +def main(args): + import_envvars(False) + export_envvars() + + if args.enable_insecure_key: + install_insecure_key() + + if not args.skip_startup_files: + run_startup_files() + + runit_exited = False + exit_code = None + + if not args.skip_runit: + runit_pid = start_runit() + try: + exit_status = None + if len(args.main_command) == 0: + runit_exited, exit_code = wait_for_runit_or_interrupt(runit_pid) + if runit_exited: + if exit_code is None: + info("Runit exited with unknown status") + exit_status = 1 + else: + exit_status = os.WEXITSTATUS(exit_code) + info("Runit exited with status %d" % exit_status) + else: + info("Running %s..." % " ".join(args.main_command)) + pid = os.spawnvp(os.P_NOWAIT, args.main_command[0], args.main_command) + try: + exit_code = waitpid_reap_other_children(pid) + if exit_code is None: + info("%s exited with unknown status." % args.main_command[0]) + exit_status = 1 + else: + exit_status = os.WEXITSTATUS(exit_code) + info("%s exited with status %d." % (args.main_command[0], exit_status)) + except KeyboardInterrupt: + stop_child_process(args.main_command[0], pid) + except BaseException as s: + warn("An error occurred. Aborting.") + stop_child_process(args.main_command[0], pid) + raise + sys.exit(exit_status) + finally: + if not args.skip_runit: + shutdown_runit_services() + if not runit_exited: + stop_child_process("runit daemon", runit_pid) + wait_for_runit_services() + +# Parse options. +parser = argparse.ArgumentParser(description = 'Initialize the system.') +parser.add_argument('main_command', metavar = 'MAIN_COMMAND', type = str, nargs = '*', + help = 'The main command to run. (default: runit)') +parser.add_argument('--enable-insecure-key', dest = 'enable_insecure_key', + action = 'store_const', const = True, default = False, + help = 'Install the insecure SSH key') +parser.add_argument('--skip-startup-files', dest = 'skip_startup_files', + action = 'store_const', const = True, default = False, + help = 'Skip running /opt/init.d/* and /etc/rc.local') +parser.add_argument('--skip-runit', dest = 'skip_runit', + action = 'store_const', const = True, default = False, + help = 'Do not run runit services') +parser.add_argument('--no-kill-all-on-exit', dest = 'kill_all_on_exit', + action = 'store_const', const = False, default = True, + help = 'Don\'t kill all processes on the system upon exiting') +parser.add_argument('--quiet', dest = 'log_level', + action = 'store_const', const = LOG_LEVEL_WARN, default = LOG_LEVEL_INFO, + help = 'Only print warnings and errors') +args = parser.parse_args() +log_level = args.log_level + +if args.skip_runit and len(args.main_command) == 0: + error("When --skip-runit is given, you must also pass a main command.") + sys.exit(1) + +# Run main function. +signal.signal(signal.SIGTERM, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGTERM')) +signal.signal(signal.SIGINT, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGINT')) +signal.signal(signal.SIGALRM, lambda signum, frame: raise_alarm_exception()) +try: + main(args) +except KeyboardInterrupt: + warn("Init system aborted.") + exit(2) +finally: + if args.kill_all_on_exit: + kill_all_processes(KILL_ALL_PROCESSES_TIMEOUT) diff --git a/images/btsync/build/runit/btsync b/images/btsync/build/runit/btsync new file mode 100644 index 0000000..72f50fa --- /dev/null +++ b/images/btsync/build/runit/btsync @@ -0,0 +1,8 @@ +#!/bin/sh +mkdir -p $BTSYNC_DATA +if [ ! -e $BTSYNC_CONFIG ]; then + mkdir -p `dirname $BTSYNC_CONFIG` + /opt/btsync --dump-sample-config > $BTSYNC_CONFIG + sed -i "s,\(\"storage_path\"\s*:\).*,\1 \"$BTSYNC_DATA\"\,," $BTSYNC_CONFIG +fi +/opt/btsync --nodaemon --config $BTSYNC_CONFIG diff --git a/images/btsync/build/runit/cron b/images/btsync/build/runit/cron new file mode 100644 index 0000000..3638fb8 --- /dev/null +++ b/images/btsync/build/runit/cron @@ -0,0 +1,2 @@ +#!/bin/sh +/usr/sbin/cron -f diff --git a/images/btsync/build/runit/sshd b/images/btsync/build/runit/sshd new file mode 100644 index 0000000..ee85db5 --- /dev/null +++ b/images/btsync/build/runit/sshd @@ -0,0 +1,2 @@ +#!/bin/sh +/usr/sbin/sshd -D diff --git a/images/btsync/build/runit/syslog b/images/btsync/build/runit/syslog new file mode 100644 index 0000000..c850a34 --- /dev/null +++ b/images/btsync/build/runit/syslog @@ -0,0 +1,24 @@ +#!/bin/sh +set -e + +SYSLOGNG_OPTS="" + +[ -r /etc/default/syslog-ng ] && . /etc/default/syslog-ng + +case "x$CONSOLE_LOG_LEVEL" in + x[1-8]) + dmesg -n $CONSOLE_LOG_LEVEL + ;; + x) + ;; + *) + echo "CONSOLE_LOG_LEVEL is of unaccepted value." + ;; +esac + +if [ ! -e /dev/xconsole ] +then + mknod -m 640 /dev/xconsole p +fi + +syslog-ng -F -p /var/run/syslog-ng.pid $SYSLOGNG_OPTS diff --git a/images/btsync/build/scripts/00_prepare.sh b/images/btsync/build/scripts/00_prepare.sh new file mode 100644 index 0000000..206cf00 --- /dev/null +++ b/images/btsync/build/scripts/00_prepare.sh @@ -0,0 +1,39 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Temporarily disable dpkg fsync to make building faster. +echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/02apt-speedup + +## Prevent initramfs updates from trying to run grub and lilo. +## https://journal.paul.querna.org/articles/2013/10/15/docker-ubuntu-on-rackspace/ +## http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=594189 +export INITRD=no +mkdir -p /etc/container_environment +echo -n no > /etc/container_environment/INITRD + +## Update package list +apt-get update + +## Fix some issues with APT packages +## See https://github.com/dotcloud/docker/issues/1024 +dpkg-divert --local --rename --add /sbin/initctl +ln -sf /bin/true /sbin/initctl + +## Replace the 'ischroot' tool to make it always return true +## Prevent initscripts updates from breaking /dev/shm +## https://journal.paul.querna.org/articles/2013/10/15/docker-ubuntu-on-rackspace/ +## https://bugs.launchpad.net/launchpad/+bug/974584 +dpkg-divert --local --rename --add /usr/bin/ischroot +ln -sf /bin/true /usr/bin/ischroot + +## Install HTTPS support for APT +$minimal_apt_get_install apt-transport-https + +## Upgrade all packages +apt-get dist-upgrade -y --no-install-recommends + +## Fix locale +$minimal_apt_get_install language-pack-en +locale-gen en_US \ No newline at end of file diff --git a/images/btsync/build/scripts/01_boot.sh b/images/btsync/build/scripts/01_boot.sh new file mode 100644 index 0000000..0ad29df --- /dev/null +++ b/images/btsync/build/scripts/01_boot.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Boot entries +mkdir /opt/init.d/ +mv /build/boot/*.sh /opt/init.d/ diff --git a/images/btsync/build/scripts/01_cron.sh b/images/btsync/build/scripts/01_cron.sh new file mode 100644 index 0000000..0efba45 --- /dev/null +++ b/images/btsync/build/scripts/01_cron.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install cron daemon +$minimal_apt_get_install cron +mkdir -p /etc/service/cron +mv /build/runit/cron /etc/service/cron/run + +## Remove useless cron entries +# Checks for lost+found and scans for mtab +rm -f /etc/cron.daily/standard diff --git a/images/btsync/build/scripts/01_init.sh b/images/btsync/build/scripts/01_init.sh new file mode 100644 index 0000000..278c35a --- /dev/null +++ b/images/btsync/build/scripts/01_init.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install init process +mv /build/init /opt/ +mkdir -p /etc/container_environment +touch /etc/container_environment.sh +touch /etc/container_environment.json +chmod 700 /etc/container_environment +chmod 600 /etc/container_environment.sh /etc/container_environment.json diff --git a/images/btsync/build/scripts/01_logrotate.sh b/images/btsync/build/scripts/01_logrotate.sh new file mode 100644 index 0000000..173ffd6 --- /dev/null +++ b/images/btsync/build/scripts/01_logrotate.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install logrotate +$minimal_apt_get_install logrotate \ No newline at end of file diff --git a/images/btsync/build/scripts/01_runit.sh b/images/btsync/build/scripts/01_runit.sh new file mode 100644 index 0000000..8919aa2 --- /dev/null +++ b/images/btsync/build/scripts/01_runit.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install runit +$minimal_apt_get_install runit diff --git a/images/btsync/build/scripts/01_sshd.sh b/images/btsync/build/scripts/01_sshd.sh new file mode 100644 index 0000000..0e8edba --- /dev/null +++ b/images/btsync/build/scripts/01_sshd.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install the SSH server +$minimal_apt_get_install openssh-server +mkdir /var/run/sshd +mkdir -p /etc/service/sshd +cp /build/runit/sshd /etc/service/sshd/run + +## Install root key +cd /opt +AUTHORIZED_KEYS=/root/.ssh/authorized_keys +DIR=`dirname "$AUTHORIZED_KEYS"` +mkdir -p "$DIR" +chmod 700 "$DIR" +chown root:root "$DIR" +pwd +ssh-keygen -t rsa -N "" -f id_rsa +cat /opt/id_rsa.pub >> "$AUTHORIZED_KEYS" + +## X11 forwarding +$minimal_apt_get_install xauth + +## Setup environment +sed -i "1iexport HOME=/root" /root/.profile +sed -i "1isource /etc/container_environment.sh" /root/.profile diff --git a/images/btsync/build/scripts/01_syslog.sh b/images/btsync/build/scripts/01_syslog.sh new file mode 100644 index 0000000..9908a7f --- /dev/null +++ b/images/btsync/build/scripts/01_syslog.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install a syslog daemon +$minimal_apt_get_install syslog-ng-core +mkdir /etc/service/syslog-ng +mv /build/runit/syslog-ng /etc/service/syslog-ng/run +mkdir -p /var/lib/syslog-ng +sed -i "s/^\(#SYSLOGNG_OPTS=\).*$/\1\"--no-caps --default-modules=affile,afprog,afsocket,afuser,basicfuncs,csvparser,dbparser,syslogformat\"/" /etc/default/syslog-ng diff --git a/images/btsync/build/scripts/02_hosts.sh b/images/btsync/build/scripts/02_hosts.sh new file mode 100644 index 0000000..2a23e9b --- /dev/null +++ b/images/btsync/build/scripts/02_hosts.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Hosts file hack +LD_LIBRARY_PATH=/root/lib +mkdir -p $LD_LIBRARY_PATH +cp /lib/x86_64-linux-gnu/libnss_files.so.2 $LD_LIBRARY_PATH +sed -i 's,/etc/hosts,/tmp/hosts,' $LD_LIBRARY_PATH/libnss_files.so.2 + +## Environment variable +echo -n $LD_LIBRARY_PATH > /etc/container_environment/LD_LIBRARY_PATH \ No newline at end of file diff --git a/images/btsync/build/scripts/02_utilities.sh b/images/btsync/build/scripts/02_utilities.sh new file mode 100644 index 0000000..2b840e9 --- /dev/null +++ b/images/btsync/build/scripts/02_utilities.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Often used tools +$minimal_apt_get_install wget curl python-pip inetutils-ping telnet sox + +## Often used python modules +pip install argparse diff --git a/images/btsync/build/scripts/03_btsync.sh b/images/btsync/build/scripts/03_btsync.sh new file mode 100644 index 0000000..c7d98ca --- /dev/null +++ b/images/btsync/build/scripts/03_btsync.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Redis +cd opt +wget -O btsync.tar.gz http://download-lb.utorrent.com/endpoint/btsync/os/linux-x64/track/stable +tar xzf btsync.tar.gz +rm btsync.tar.gz + +export BTSYNC_CONFIG=/host/etc/btsync.conf +export BTSYNC_DATA=/host/var/btsync + +## Runit script +mkdir /etc/service/btsync +mv /build/runit/btsync /etc/service/btsync/run + +## Environment variables +echo -n $BTSYNC_CONFIG > /etc/container_environment/BTSYNC_CONFIG +echo -n $BTSYNC_DATA > /etc/container_environment/BTSYNC_DATA diff --git a/images/btsync/build/scripts/99_cleanup.sh b/images/btsync/build/scripts/99_cleanup.sh new file mode 100644 index 0000000..70eaf47 --- /dev/null +++ b/images/btsync/build/scripts/99_cleanup.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e +source /build/config +set -x + +apt-get clean +rm -rf /build +rm -rf /tmp/* /var/tmp/* +rm -rf /var/lib/apt/lists/* +rm -f /etc/dpkg/dpkg.cfg.d/02apt-speedup diff --git a/images/btsync/fs/etc/btsync.conf b/images/btsync/fs/etc/btsync.conf new file mode 100644 index 0000000..1bd17f5 --- /dev/null +++ b/images/btsync/fs/etc/btsync.conf @@ -0,0 +1,70 @@ +{ + "device_name": "My Sync Device", + "listening_port" : 0, // 0 - randomize port + +/* storage_path dir contains auxilliary app files + if no storage_path field: .sync dir created in the directory + where binary is located. + otherwise user-defined directory will be used +*/ + "storage_path" : "/host/var/btsync", + +// uncomment next line if you want to set location of pid file +// "pid_file" : "/var/run/btsync/btsync.pid", + + + "check_for_updates" : true, + "use_upnp" : true, // use UPnP for port mapping + + +/* limits in kB/s + 0 - no limit +*/ + "download_limit" : 0, + "upload_limit" : 0, + +/* remove "listen" field to disable WebUI + remove "login" and "password" fields to disable credentials check +*/ + "webui" : + { + "listen" : "0.0.0.0:8888", + "login" : "admin", + "password" : "password" + } + +/* !!! if you set shared folders in config file WebUI will be DISABLED !!! + shared directories specified in config file + override the folders previously added from WebUI. +*/ +/* + , + "shared_folders" : + [ + { +// use --generate-secret in command line to create new secret + "secret" : "MY_SECRET_1", // * required field + "dir" : "/home/user/bittorrent/sync_test", // * required field + +// use relay server when direct connection fails + "use_relay_server" : true, + "use_tracker" : true, + "use_dht" : false, + "search_lan" : true, +// enable SyncArchive to store files deleted on remote devices + "use_sync_trash" : true, +// restore modified files to original version, ONLY for Read-Only folders +// "overwrite_changes" : false, +// specify hosts to attempt connection without additional search + "known_hosts" : + [ + "192.168.1.2:44444" + ] + } + ] +*/ + +// Advanced preferences can be added to config file. +// Info is available in BitTorrent Sync User Guide. + +} diff --git a/images/firefox/bin/app b/images/firefox/bin/app new file mode 100644 index 0000000..8c823a5 --- /dev/null +++ b/images/firefox/bin/app @@ -0,0 +1,19 @@ +ARGS="-v /root/.config/pulse:/root/.config/pulse" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +while : ; do + ID=`docker ps --no-trunc | grep $CONTAINER: | cut -d' ' -f1` + if [ -n "$ID" ]; then + break + fi + if [ ! -n "$STARTED" ]; then + echo "Starting container." + /opt/docker/bin/run $CONTAINER & + STARTED=yes + sleep 10 + fi +done +/opt/docker/bin/ssh $CONTAINER $1 "source .profile; /opt/$CONTAINER" diff --git a/images/firefox/bin/run b/images/firefox/bin/run new file mode 100644 index 0000000..edb24cf --- /dev/null +++ b/images/firefox/bin/run @@ -0,0 +1,7 @@ +ARGS="" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +/opt/docker/bin/run -t $CONTAINER "$ARGS" $1 "$2" diff --git a/images/firefox/bin/ssh b/images/firefox/bin/ssh new file mode 100644 index 0000000..14a9c00 --- /dev/null +++ b/images/firefox/bin/ssh @@ -0,0 +1,24 @@ +ARGS="" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +ID=`docker ps --no-trunc | grep $CONTAINER: | cut -d' ' -f1` +if [ -n "$ID" ]; then + IP=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $ID` + COMMAND="ssh -X -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i id_rsa $ARGS root@$IP" + if [ ! -e id_rsa ]; then + docker cp $ID:/opt/id_rsa . + fi + if [ ! -z "$1" ] && [ "$1" == "-l" ]; then + DISPLAY=:0 + chmod 0666 id_rsa + su user -c "$COMMAND \"$2\"" + else + chmod 0600 id_rsa + eval "$COMMAND \"$1\"" + fi +else + echo "Container is not running." +fi \ No newline at end of file diff --git a/images/firefox/id_rsa b/images/firefox/id_rsa new file mode 100644 index 0000000..8835fc2 --- /dev/null +++ b/images/firefox/id_rsa @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvaPU8j/H6XZzNphjqXY/toIiAWSxNdfJ3OELaJN0v0myPHoI +7F6oaQShOTm/k9WTFihm+KNZp9booVBrilYVMDDXWcA8yvjEI3I+FCGekfU57SZk +tFW1yKYKRBDK7+W0R65L64uargphLx9espZE7WWRpMsgsFj0jbfNTlx8yMkV3Nlh +AAbFuMExoYKzeOEe2b9SISxGGCHXWDFgeh5RdGf5ErP43/mD6/g+w1d7g2+4zykU +ysM6NozaHv1i1UqDOJ5mq9bSPl7lsFopGcLQ0UTRmtSRF9CAqPTHK8sWVO4gwTVM +TNZdq6K60hD876QktvBWuzyYHpvZ4WSgzxDs2wIDAQABAoIBAG2PxIx8qtvH0kJ9 +gj66kY642jqh2Pv5gqd44SV246FMS4xDGPquqW+a/CZapcMcRhEsIGmPvlGIiPgB +xU+z8iPYY+J3fOfrFy4/Z3wr/DfpTKElaFMDnbWhsBao+QXmWOR832HjUucwGfum +jQhyZroczys9K9KWYhuqUBPwvSsmecEJ2kXrEECzJWY8oKECKsEIIaR57D79+0Vi +i57Ui2Rjzh3W0d74dt1zDvYF9iSIURFC7ZPKqMTQX0A8YMv520qIOURVk2RmPRG6 +ughHHIT3E4WAQ6555sc+dEYeM2RA64EVJNjzs4qin/0tlaS3cCf+3bef1pbSoYJD +mBoVu/kCgYEA9ZxXxCDsXYcSBPshpErJv7rQbTtNSW+cpzsqApAZEyPDcrSoA8+t +QP03HFsdY5osxes8jeJB0GsjWV40uct9cZtGWl+GjqEY7pwUFzJUslG9K+8bcQIN +wDNWWmL+Z+889HpAtPamjeMEGseyFmrxonvsjjVKsH0Ew5FRflXl040CgYEAxall +TucV++hzaU1eFdQrISOv5TK1XeRV0St+BPl7djlV3kJD6kK6QQpCdBUEY08W0HOX +1I5Soqc5ohF3y8E3B2AhkwL4CfD6zCp8Vksw4lfUquucgP0QmUb3AcVM/7tLM6/8 +kCfVvEFHecDI1GVwjBCuwZN9nEQmDsEkU3JttAcCgYEAxFzWnmtkDfJrKahN4TgZ +zDvjXzFGPSwKpnjawWnLYk35eL+OhF2JOqg3Y2hFOtiMa0ADDbySubqubEixBsn1 +5NoriR1OSsHpWPtX5KPMqzRGddWYruThcYSZyXHTy+ytYxhKm2OHDXEuWurFKr8d +qLZDDf71U9zf7itEaCjsshECgYAcGz1LnfJzUpduptC1G+lSGgf9+Frv0fMd/ig6 +Ptt+cSKzqwqLOhfP/cx7Qy3PjUR6OaWiVOaNOGgqkn9NWtkfVF0R0X9BsqGG/JeX +kbOOy9xyvXQQp2t/0CZ5evu69X/5BpJMUU3EKigmuPIVuaLqV8jxv65B1TLwMCih +MQlGawKBgQDT8T1/pJqQjx0MS/65m9q+zkeiNru7FnLWpkscJWYL7J27VEjuWtfB +TVIJkdV1kx0Y8liJ/Bjwe9Cwyz3dy4j5Hhz66oeQyK97rryyFU48NcECCOfvDdw/ +4LR71AgFyUwRfDSy2q1B38IspJCGCB+xP8cRUHZxySQesKEX1XECsQ== +-----END RSA PRIVATE KEY----- diff --git a/images/hamachi/Dockerfile b/images/hamachi/Dockerfile new file mode 100644 index 0000000..7cbfb1b --- /dev/null +++ b/images/hamachi/Dockerfile @@ -0,0 +1,5 @@ +FROM ubuntu:precise + +ADD build /build + +RUN for s in /build/scripts/*.sh; do [ -x $s ] && $s || : ; done \ No newline at end of file diff --git a/images/hamachi/bin/app b/images/hamachi/bin/app new file mode 100644 index 0000000..8c823a5 --- /dev/null +++ b/images/hamachi/bin/app @@ -0,0 +1,19 @@ +ARGS="-v /root/.config/pulse:/root/.config/pulse" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +while : ; do + ID=`docker ps --no-trunc | grep $CONTAINER: | cut -d' ' -f1` + if [ -n "$ID" ]; then + break + fi + if [ ! -n "$STARTED" ]; then + echo "Starting container." + /opt/docker/bin/run $CONTAINER & + STARTED=yes + sleep 10 + fi +done +/opt/docker/bin/ssh $CONTAINER $1 "source .profile; /opt/$CONTAINER" diff --git a/images/hamachi/bin/run b/images/hamachi/bin/run new file mode 100644 index 0000000..de4e269 --- /dev/null +++ b/images/hamachi/bin/run @@ -0,0 +1,7 @@ +ARGS="--privileged -v /opt/docker/images/hamachi/fs:/host" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +/opt/docker/bin/run -t $CONTAINER "$ARGS" $1 "$2" diff --git a/images/hamachi/bin/ssh b/images/hamachi/bin/ssh new file mode 100644 index 0000000..14a9c00 --- /dev/null +++ b/images/hamachi/bin/ssh @@ -0,0 +1,24 @@ +ARGS="" +DIR=`dirname $0` +DIR=`readlink -e $DIR` +BASE=`basename $DIR` +IFS='/' read -ra ADDR <<< "$DIR" +CONTAINER=${ADDR[-2]} +ID=`docker ps --no-trunc | grep $CONTAINER: | cut -d' ' -f1` +if [ -n "$ID" ]; then + IP=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $ID` + COMMAND="ssh -X -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i id_rsa $ARGS root@$IP" + if [ ! -e id_rsa ]; then + docker cp $ID:/opt/id_rsa . + fi + if [ ! -z "$1" ] && [ "$1" == "-l" ]; then + DISPLAY=:0 + chmod 0666 id_rsa + su user -c "$COMMAND \"$2\"" + else + chmod 0600 id_rsa + eval "$COMMAND \"$1\"" + fi +else + echo "Container is not running." +fi \ No newline at end of file diff --git a/images/hamachi/build/boot/00_hosts.sh b/images/hamachi/build/boot/00_hosts.sh new file mode 100644 index 0000000..cf95dc4 --- /dev/null +++ b/images/hamachi/build/boot/00_hosts.sh @@ -0,0 +1,4 @@ +#!/bin/bash +set -e +echo "127.0.0.1 localhost" >> /tmp/hosts +echo "$HOST_ADDR host" >> /tmp/hosts diff --git a/images/hamachi/build/boot/01_hamachi.sh b/images/hamachi/build/boot/01_hamachi.sh new file mode 100644 index 0000000..41bf6be --- /dev/null +++ b/images/hamachi/build/boot/01_hamachi.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -e +cd /opt +dpkg -i hamachi.deb +kill -9 `pgrep hamachid` \ No newline at end of file diff --git a/images/hamachi/build/config b/images/hamachi/build/config new file mode 100644 index 0000000..0085fd0 --- /dev/null +++ b/images/hamachi/build/config @@ -0,0 +1,3 @@ +export LC_ALL=C +export DEBIAN_FRONTEND=noninteractive +minimal_apt_get_install='apt-get install -y --no-install-recommends' diff --git a/images/hamachi/build/init b/images/hamachi/build/init new file mode 100644 index 0000000..5b56e0b --- /dev/null +++ b/images/hamachi/build/init @@ -0,0 +1,314 @@ +#!/usr/bin/python2 -u +import os, os.path, sys, stat, signal, errno, argparse, time, json, re, posixfile + +KILL_PROCESS_TIMEOUT = 5 +KILL_ALL_PROCESSES_TIMEOUT = 5 + +LOG_LEVEL_ERROR = 1 +LOG_LEVEL_WARN = 1 +LOG_LEVEL_INFO = 2 +LOG_LEVEL_DEBUG = 3 + +log_level = None + +class AlarmException(Exception): + pass + +def error(message): + if log_level >= LOG_LEVEL_ERROR: + sys.stderr.write("*** %s\n" % message) + +def warn(message): + if log_level >= LOG_LEVEL_WARN: + print("*** %s" % message) + +def info(message): + if log_level >= LOG_LEVEL_INFO: + print("*** %s" % message) + +def debug(message): + if log_level >= LOG_LEVEL_DEBUG: + print("*** %s" % message) + +def ignore_signals_and_raise_keyboard_interrupt(signame): + signal.signal(signal.SIGTERM, signal.SIG_IGN) + signal.signal(signal.SIGINT, signal.SIG_IGN) + raise KeyboardInterrupt(signame) + +def raise_alarm_exception(): + raise AlarmException('Alarm') + +def listdir(path): + try: + result = os.stat(path) + except OSError: + return [] + if stat.S_ISDIR(result.st_mode): + return sorted(os.listdir(path)) + else: + return [] + +def is_exe(path): + try: + return os.path.isfile(path) and os.access(path, os.X_OK) + except OSError: + return False + +def import_envvars(clear_existing_environment = True): + new_env = {} + for envfile in listdir("/etc/container_environment"): + name = os.path.basename(envfile) + with open("/etc/container_environment/" + envfile, "r") as f: + value = f.read() + new_env[name] = value + if clear_existing_environment: + os.environ.clear() + for name, value in new_env.items(): + os.environ[name] = value + +def export_envvars(to_dir = True): + shell_dump = "" + for name, value in os.environ.items(): + if to_dir: + with open("/etc/container_environment/" + name, "w") as f: + f.write(value) + shell_dump += "export " + shquote(name) + "=" + shquote(value) + "\n" + with open("/etc/container_environment.sh", "w") as f: + f.write(shell_dump) + with open("/etc/container_environment.json", "w") as f: + f.write(json.dumps(dict(os.environ))) + +_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search + +def shquote(s): + """Return a shell-escaped version of the string *s*.""" + if not s: + return "''" + if _find_unsafe(s) is None: + return s + + # use single quotes, and put single quotes into double quotes + # the string $'b is then quoted as '$'"'"'b' + return "'" + s.replace("'", "'\"'\"'") + "'" + +def waitpid_reap_other_children(pid): + done = False + status = None + try: + this_pid, status = os.waitpid(pid, os.WNOHANG) + except OSError as e: + if e.errno == errno.ECHILD or e.errno == errno.ESRCH: + return None + else: + raise + while not done: + this_pid, status = os.waitpid(-1, 0) + done = this_pid == pid + return status + +def stop_child_process(name, pid, signo = signal.SIGTERM, time_limit = KILL_PROCESS_TIMEOUT): + info("Shutting down %s (PID %d)..." % (name, pid)) + try: + os.kill(pid, signo) + except OSError: + pass + signal.alarm(time_limit) + try: + try: + waitpid_reap_other_children(pid) + except OSError: + pass + except AlarmException: + warn("%s (PID %d) did not shut down in time. Forcing it to exit." % (name, pid)) + try: + os.kill(pid, signal.SIGKILL) + except OSError: + pass + try: + waitpid_reap_other_children(pid) + except OSError: + pass + finally: + signal.alarm(0) + +def run_command_killable(*argv): + filename = argv[0] + status = None + pid = os.spawnvp(os.P_NOWAIT, filename, argv) + try: + status = waitpid_reap_other_children(pid) + except BaseException as s: + warn("An error occurred. Aborting.") + stop_child_process(filename, pid) + raise + if status != 0: + if status is None: + error("%s exited with unknown status\n" % filename) + else: + error("%s failed with status %d\n" % (filename, os.WEXITSTATUS(status))) + sys.exit(1) + +def run_command_killable_and_import_envvars(*argv): + run_command_killable(*argv) + import_envvars() + export_envvars(False) + +def kill_all_processes(time_limit): + info("Killing all processes...") + try: + os.kill(-1, signal.SIGTERM) + except OSError: + pass + signal.alarm(time_limit) + try: + # Wait until no more child processes exist. + done = False + while not done: + try: + os.waitpid(-1, 0) + except OSError as e: + if e.errno == errno.ECHILD: + done = True + else: + raise + except AlarmException: + warn("Not all processes have exited in time. Forcing them to exit.") + try: + os.kill(-1, signal.SIGKILL) + except OSError: + pass + finally: + signal.alarm(0) + +def run_startup_files(): + # Run /opt/init.d/* + for name in listdir("/opt/init.d"): + filename = "/opt/init.d/" + name + if is_exe(filename): + info("Running %s..." % filename) + run_command_killable_and_import_envvars(filename) + + # Run /etc/rc.local. + if is_exe("/etc/rc.local"): + info("Running /etc/rc.local...") + run_command_killable_and_import_envvars("/etc/rc.local") + +def start_runit(): + info("Booting runit daemon...") + pid = os.spawnl(os.P_NOWAIT, "/usr/bin/runsvdir", "/usr/bin/runsvdir", + "-P", "/etc/service", "log: %s" % ('.' * 395)) + info("Runit started as PID %d" % pid) + return pid + +def wait_for_runit_or_interrupt(pid): + try: + status = waitpid_reap_other_children(pid) + return (True, status) + except KeyboardInterrupt: + return (False, None) + +def shutdown_runit_services(): + debug("Begin shutting down runit services...") + os.system("/usr/bin/sv down /etc/service/*") + +def wait_for_runit_services(): + debug("Waiting for runit services to exit...") + done = False + while not done: + done = os.system("/usr/bin/sv status /etc/service/* | grep -q '^run:'") != 0 + if not done: + time.sleep(0.1) + +def install_insecure_key(): + info("Installing insecure SSH key for user root") + run_command_killable("/usr/sbin/enable_insecure_key") + +def main(args): + import_envvars(False) + export_envvars() + + if args.enable_insecure_key: + install_insecure_key() + + if not args.skip_startup_files: + run_startup_files() + + runit_exited = False + exit_code = None + + if not args.skip_runit: + runit_pid = start_runit() + try: + exit_status = None + if len(args.main_command) == 0: + runit_exited, exit_code = wait_for_runit_or_interrupt(runit_pid) + if runit_exited: + if exit_code is None: + info("Runit exited with unknown status") + exit_status = 1 + else: + exit_status = os.WEXITSTATUS(exit_code) + info("Runit exited with status %d" % exit_status) + else: + info("Running %s..." % " ".join(args.main_command)) + pid = os.spawnvp(os.P_NOWAIT, args.main_command[0], args.main_command) + try: + exit_code = waitpid_reap_other_children(pid) + if exit_code is None: + info("%s exited with unknown status." % args.main_command[0]) + exit_status = 1 + else: + exit_status = os.WEXITSTATUS(exit_code) + info("%s exited with status %d." % (args.main_command[0], exit_status)) + except KeyboardInterrupt: + stop_child_process(args.main_command[0], pid) + except BaseException as s: + warn("An error occurred. Aborting.") + stop_child_process(args.main_command[0], pid) + raise + sys.exit(exit_status) + finally: + if not args.skip_runit: + shutdown_runit_services() + if not runit_exited: + stop_child_process("runit daemon", runit_pid) + wait_for_runit_services() + +# Parse options. +parser = argparse.ArgumentParser(description = 'Initialize the system.') +parser.add_argument('main_command', metavar = 'MAIN_COMMAND', type = str, nargs = '*', + help = 'The main command to run. (default: runit)') +parser.add_argument('--enable-insecure-key', dest = 'enable_insecure_key', + action = 'store_const', const = True, default = False, + help = 'Install the insecure SSH key') +parser.add_argument('--skip-startup-files', dest = 'skip_startup_files', + action = 'store_const', const = True, default = False, + help = 'Skip running /opt/init.d/* and /etc/rc.local') +parser.add_argument('--skip-runit', dest = 'skip_runit', + action = 'store_const', const = True, default = False, + help = 'Do not run runit services') +parser.add_argument('--no-kill-all-on-exit', dest = 'kill_all_on_exit', + action = 'store_const', const = False, default = True, + help = 'Don\'t kill all processes on the system upon exiting') +parser.add_argument('--quiet', dest = 'log_level', + action = 'store_const', const = LOG_LEVEL_WARN, default = LOG_LEVEL_INFO, + help = 'Only print warnings and errors') +args = parser.parse_args() +log_level = args.log_level + +if args.skip_runit and len(args.main_command) == 0: + error("When --skip-runit is given, you must also pass a main command.") + sys.exit(1) + +# Run main function. +signal.signal(signal.SIGTERM, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGTERM')) +signal.signal(signal.SIGINT, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGINT')) +signal.signal(signal.SIGALRM, lambda signum, frame: raise_alarm_exception()) +try: + main(args) +except KeyboardInterrupt: + warn("Init system aborted.") + exit(2) +finally: + if args.kill_all_on_exit: + kill_all_processes(KILL_ALL_PROCESSES_TIMEOUT) diff --git a/images/hamachi/build/runit/cron b/images/hamachi/build/runit/cron new file mode 100644 index 0000000..3638fb8 --- /dev/null +++ b/images/hamachi/build/runit/cron @@ -0,0 +1,2 @@ +#!/bin/sh +/usr/sbin/cron -f diff --git a/images/hamachi/build/runit/hamachi b/images/hamachi/build/runit/hamachi new file mode 100644 index 0000000..5f05d6e --- /dev/null +++ b/images/hamachi/build/runit/hamachi @@ -0,0 +1,4 @@ +#!/bin/sh +/opt/logmein-hamachi/bin/hamachid -c $HAMACHI_DATA +strace -qqe '' -p `pgrep hamachid` +/host/bin/proxy \ No newline at end of file diff --git a/images/hamachi/build/runit/sshd b/images/hamachi/build/runit/sshd new file mode 100644 index 0000000..ee85db5 --- /dev/null +++ b/images/hamachi/build/runit/sshd @@ -0,0 +1,2 @@ +#!/bin/sh +/usr/sbin/sshd -D diff --git a/images/hamachi/build/runit/syslog b/images/hamachi/build/runit/syslog new file mode 100644 index 0000000..c850a34 --- /dev/null +++ b/images/hamachi/build/runit/syslog @@ -0,0 +1,24 @@ +#!/bin/sh +set -e + +SYSLOGNG_OPTS="" + +[ -r /etc/default/syslog-ng ] && . /etc/default/syslog-ng + +case "x$CONSOLE_LOG_LEVEL" in + x[1-8]) + dmesg -n $CONSOLE_LOG_LEVEL + ;; + x) + ;; + *) + echo "CONSOLE_LOG_LEVEL is of unaccepted value." + ;; +esac + +if [ ! -e /dev/xconsole ] +then + mknod -m 640 /dev/xconsole p +fi + +syslog-ng -F -p /var/run/syslog-ng.pid $SYSLOGNG_OPTS diff --git a/images/hamachi/build/scripts/00_prepare.sh b/images/hamachi/build/scripts/00_prepare.sh new file mode 100644 index 0000000..206cf00 --- /dev/null +++ b/images/hamachi/build/scripts/00_prepare.sh @@ -0,0 +1,39 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Temporarily disable dpkg fsync to make building faster. +echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/02apt-speedup + +## Prevent initramfs updates from trying to run grub and lilo. +## https://journal.paul.querna.org/articles/2013/10/15/docker-ubuntu-on-rackspace/ +## http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=594189 +export INITRD=no +mkdir -p /etc/container_environment +echo -n no > /etc/container_environment/INITRD + +## Update package list +apt-get update + +## Fix some issues with APT packages +## See https://github.com/dotcloud/docker/issues/1024 +dpkg-divert --local --rename --add /sbin/initctl +ln -sf /bin/true /sbin/initctl + +## Replace the 'ischroot' tool to make it always return true +## Prevent initscripts updates from breaking /dev/shm +## https://journal.paul.querna.org/articles/2013/10/15/docker-ubuntu-on-rackspace/ +## https://bugs.launchpad.net/launchpad/+bug/974584 +dpkg-divert --local --rename --add /usr/bin/ischroot +ln -sf /bin/true /usr/bin/ischroot + +## Install HTTPS support for APT +$minimal_apt_get_install apt-transport-https + +## Upgrade all packages +apt-get dist-upgrade -y --no-install-recommends + +## Fix locale +$minimal_apt_get_install language-pack-en +locale-gen en_US \ No newline at end of file diff --git a/images/hamachi/build/scripts/01_boot.sh b/images/hamachi/build/scripts/01_boot.sh new file mode 100644 index 0000000..0ad29df --- /dev/null +++ b/images/hamachi/build/scripts/01_boot.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Boot entries +mkdir /opt/init.d/ +mv /build/boot/*.sh /opt/init.d/ diff --git a/images/hamachi/build/scripts/01_cron.sh b/images/hamachi/build/scripts/01_cron.sh new file mode 100644 index 0000000..0efba45 --- /dev/null +++ b/images/hamachi/build/scripts/01_cron.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install cron daemon +$minimal_apt_get_install cron +mkdir -p /etc/service/cron +mv /build/runit/cron /etc/service/cron/run + +## Remove useless cron entries +# Checks for lost+found and scans for mtab +rm -f /etc/cron.daily/standard diff --git a/images/hamachi/build/scripts/01_init.sh b/images/hamachi/build/scripts/01_init.sh new file mode 100644 index 0000000..278c35a --- /dev/null +++ b/images/hamachi/build/scripts/01_init.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install init process +mv /build/init /opt/ +mkdir -p /etc/container_environment +touch /etc/container_environment.sh +touch /etc/container_environment.json +chmod 700 /etc/container_environment +chmod 600 /etc/container_environment.sh /etc/container_environment.json diff --git a/images/hamachi/build/scripts/01_logrotate.sh b/images/hamachi/build/scripts/01_logrotate.sh new file mode 100644 index 0000000..173ffd6 --- /dev/null +++ b/images/hamachi/build/scripts/01_logrotate.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install logrotate +$minimal_apt_get_install logrotate \ No newline at end of file diff --git a/images/hamachi/build/scripts/01_runit.sh b/images/hamachi/build/scripts/01_runit.sh new file mode 100644 index 0000000..8919aa2 --- /dev/null +++ b/images/hamachi/build/scripts/01_runit.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install runit +$minimal_apt_get_install runit diff --git a/images/hamachi/build/scripts/01_sshd.sh b/images/hamachi/build/scripts/01_sshd.sh new file mode 100644 index 0000000..0e8edba --- /dev/null +++ b/images/hamachi/build/scripts/01_sshd.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install the SSH server +$minimal_apt_get_install openssh-server +mkdir /var/run/sshd +mkdir -p /etc/service/sshd +cp /build/runit/sshd /etc/service/sshd/run + +## Install root key +cd /opt +AUTHORIZED_KEYS=/root/.ssh/authorized_keys +DIR=`dirname "$AUTHORIZED_KEYS"` +mkdir -p "$DIR" +chmod 700 "$DIR" +chown root:root "$DIR" +pwd +ssh-keygen -t rsa -N "" -f id_rsa +cat /opt/id_rsa.pub >> "$AUTHORIZED_KEYS" + +## X11 forwarding +$minimal_apt_get_install xauth + +## Setup environment +sed -i "1iexport HOME=/root" /root/.profile +sed -i "1isource /etc/container_environment.sh" /root/.profile diff --git a/images/hamachi/build/scripts/01_syslog.sh b/images/hamachi/build/scripts/01_syslog.sh new file mode 100644 index 0000000..9908a7f --- /dev/null +++ b/images/hamachi/build/scripts/01_syslog.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Install a syslog daemon +$minimal_apt_get_install syslog-ng-core +mkdir /etc/service/syslog-ng +mv /build/runit/syslog-ng /etc/service/syslog-ng/run +mkdir -p /var/lib/syslog-ng +sed -i "s/^\(#SYSLOGNG_OPTS=\).*$/\1\"--no-caps --default-modules=affile,afprog,afsocket,afuser,basicfuncs,csvparser,dbparser,syslogformat\"/" /etc/default/syslog-ng diff --git a/images/hamachi/build/scripts/02_hosts.sh b/images/hamachi/build/scripts/02_hosts.sh new file mode 100644 index 0000000..2a23e9b --- /dev/null +++ b/images/hamachi/build/scripts/02_hosts.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Hosts file hack +LD_LIBRARY_PATH=/root/lib +mkdir -p $LD_LIBRARY_PATH +cp /lib/x86_64-linux-gnu/libnss_files.so.2 $LD_LIBRARY_PATH +sed -i 's,/etc/hosts,/tmp/hosts,' $LD_LIBRARY_PATH/libnss_files.so.2 + +## Environment variable +echo -n $LD_LIBRARY_PATH > /etc/container_environment/LD_LIBRARY_PATH \ No newline at end of file diff --git a/images/hamachi/build/scripts/02_utilities.sh b/images/hamachi/build/scripts/02_utilities.sh new file mode 100644 index 0000000..2b840e9 --- /dev/null +++ b/images/hamachi/build/scripts/02_utilities.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Often used tools +$minimal_apt_get_install wget curl python-pip inetutils-ping telnet sox + +## Often used python modules +pip install argparse diff --git a/images/hamachi/build/scripts/03_hamachi.sh b/images/hamachi/build/scripts/03_hamachi.sh new file mode 100644 index 0000000..b28f3a3 --- /dev/null +++ b/images/hamachi/build/scripts/03_hamachi.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e +source /build/config +set -x + +## Hamachi dependency +$minimal_apt_get_install lsb-core net-tools socat strace + +## Hamachi +cd /opt +export HAMACHI_DATA=/host/var/lib/logmein-hamachi +export HAMACHI_VERSION=2.1.0.119 +wget -O hamachi.deb https://secure.logmein.com/labs/logmein-hamachi_$HAMACHI_VERSION-1_amd64.deb +mkdir -p /etc/service/hamachi +cp /build/runit/hamachi /etc/service/hamachi/run + +## Environment variables +echo -n $HAMACHI_DATA > /etc/container_environment/HAMACHI_DATA \ No newline at end of file diff --git a/images/hamachi/build/scripts/99_cleanup.sh b/images/hamachi/build/scripts/99_cleanup.sh new file mode 100644 index 0000000..70eaf47 --- /dev/null +++ b/images/hamachi/build/scripts/99_cleanup.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e +source /build/config +set -x + +apt-get clean +rm -rf /build +rm -rf /tmp/* /var/tmp/* +rm -rf /var/lib/apt/lists/* +rm -f /etc/dpkg/dpkg.cfg.d/02apt-speedup diff --git a/images/hamachi/fs/bin/proxy b/images/hamachi/fs/bin/proxy new file mode 100644 index 0000000..80cbff2 --- /dev/null +++ b/images/hamachi/fs/bin/proxy @@ -0,0 +1,3 @@ +#!/bin/bash +socat TCP-LISTEN:8888,fork TCP:host:8888 & +socat TCP-LISTEN:80,fork,crlf SYSTEM:"echo HTTP/1.0 200; echo Content-Type: text/plain; echo;" & \ No newline at end of file diff --git a/images/hamachi/id_rsa b/images/hamachi/id_rsa new file mode 100644 index 0000000..549610b --- /dev/null +++ b/images/hamachi/id_rsa @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAsX9pVM/MiGZI/coaYJ53bDi06RK6EO03QeNw0JpHD1C+cW/J +8bTqfrEsDF6M3uproDzTP+PmpP3zjD8gLcvptiFk5xoK6PjjPqDivqON9eI5Fqnk +KGuV6BRBhPWfDNzPZsdoCIYTwF2HXdSSq9Wbl9EagudcpwW5k5n/VzC+ANZC0ASe +DD2qwnpppo4XmBd7CIvjYTC2bqH4brYNBMZYLOCyXrgTGP5Kudzg1+UzY1xt1SuH +k09CXLkOH5EhGp9MdNj+RUiPlDVwSV96ltb5idew246Ar6isrqy+6jbzufCad+9H +KA8olb66/UxDNF2U5FuHAg6AHjNHPKXghosGrwIDAQABAoIBAFRXS5CuUOz7VXGq +qBADHJIC/AvIBzvlzBz12vR0apGfd27lhJrisY5T169k+iEuWMfCP0sbmswJk8Gv +eTXpr/sIMS8TE94R7cEjp7qYcutEfIYFYlHGlWu6vEtWfyYYgkC/PfLW6um8R4dR +bARUsuNXy/Ypw7/lm4HEai1fDtnMKmxnNtc0LRiuO9Tp9rmbJlsGfrxVO1jkbCNw +IchHQshDbLCMtPhxNo2PZ7NfwMyxldOIGT83iVX94Yo0XrcnhqEYBqvYOAlWoGa0 +FFKxRFOxL8y8u1q8kShHyZLsPfE/enhozpKhVpX/J73X81hzG8+zRrE+QjCKh/OG +kUm/CQkCgYEA6ewIBoV7YQeSg+S+zbvDPXA41BVMJVqmUBXASGTgRVRbd+EvH2tY +6EoL28ihaNJTSNBCtLFAcU/L8gFL/qivzfJ//wBoLWe3XtT9V9ne7uMTT2njFYr2 ++/W7PgNpcIurg2Uz9LRNQ+AfYTdGddf/Hp/MqAICGTNY2vXL98a7PXMCgYEAwkAR +xkpWO6Y2Mfg/qwhV2igDzEhupM6A+NZW6w2JmUhJeQiRZgCCSEOW8EV33A50k4l1 +0X/Wy+AWwFu+uA6YTJzg63Ec430XOLKJMSBPl3SZr8eJ0/6CfPMrvW7KahIebCIm +xDTN4JrGn3wfEBF7rzB3TrLMlu+dgw5Hzf8iAtUCgYAUyaTs72/Hb6TVk75hCg6P +pyllr37U0vl0pHox9MT5ZEW8oYZOhHuiKPJk1a+CYS6FifxjklzntO+q0fKu7s6w +vpwhTSf04QKqqsLYy8PD9uoAZKiJgY/xVCUPnb4BAmh7hMLZPCyhm4kuWnsofclu +L0VAqO0G0ElVLAK0QjThgQKBgCNfQ11WYAmQpMHIsN9WLzwAmWBzuCIusHGfpkg7 +ONk+vpJZqxBl+1Npa2zpWYAq6bOMDnZNzzFk5v+0NTCTB8y7rIFzIY2TU80xRaY6 +egPcabgGn+SIrf5O0aI3MIjML9oFBgYoj2zdAlo8YfOtG1a1fqRIDtVVYNtimFS8 +ptbZAoGBAJ7yH5cDO723k/dkpd0BscYIue0e3GDvSxLdZGEzIGkSXlDtB0sue1A2 +wyAhlxFEVhDvKHqwre9I++7uUkVePHkvvb04eSsaxIEtp3N+GXvNFKanlJ4P2PV1 +V8nXSzgi5f5/p65TwzStdsnKMNnnOL7wq4hY06xr2eUKUI9h3lHl +-----END RSA PRIVATE KEY-----