Make docker-compose work.

[?]
May 28, 2020, 3:05 PM
GMYPBCWEB6NKURRILAHR3TJUKDOGR2ZMK5I6MS6P5G2LAGH36P3QC

Dependencies

  • [2] L65BC6Y6 Use updated dbmigrations executables.
  • [3] B6HWAPDP Modularize & update to recent haskoin.
  • [4] LEINLS3X Update deployment documentation.
  • [5] HMDM3B55 Implement core of payments/billing infrastructure.
  • [6] V2VDN77H Enable postgres configuration via environment variable for Heroku.
  • [7] SOIAMXLW Build versioned docker images.
  • [8] O5FVTOM6 Undo JSON silliness, enable a couple more routes.
  • [9] 4B66XH43 Add sample billing config
  • [10] IPG33FAW Add billing daemon
  • [11] 3TAMXHCZ Add migrations to server startup.
  • [12] E2KOBKIJ Add setup script detailing the setup of the docker host.
  • [13] IZEVQF62 Work in progress replacing sqlite with postgres.
  • [14] 7VGYLTMU Clean up schema version handling.
  • [15] XZLSHL4D The server is now (tenuously) running, and serving pages via SSL!
  • [16] 2WOOGXDH Use dbmigrations to manage database state.
  • [17] ZKJJVD2H Fix aftok-server runit script permissions.
  • [18] EW2XN7KU Update docker build, clean up migration for payments tables.
  • [19] 2LZYVHFS Upgrade to Stack-based build in Docker
  • [20] 6L5BK5EH Use generic SMTP rather than Sendmail-specific mail client.
  • [21] NVOCQVAS Initial failing tests.
  • [22] AL37SVTC Implement payments service endpoints.
  • [23] NEDDHXUK Reformat via stylish-haskell
  • [24] NLZ3JXLO Fix formatting with stylish-haskell.
  • [25] 2XQD6KKK Add invitation logic and clean up DBProg error handling.
  • [26] DXIGERDT Change order of Docker build to avoid rebuilding the universe.
  • [27] T3X4DRLF Add dbmigrations to the docker build.
  • [28] QTHFTPDX Clean up dockerfile organization
  • [29] DFOBMSAO Initial work on payments API
  • [30] MJ6R42RC Utility methods for reading key & cert data.
  • [31] JEOPOOPT Dockerfile now builds correctly.
  • [32] 4ZLEDBK7 Initial attempts at dockerizing, cabal isn't cooperating.
  • [33] M3KUPGZK Add invitation email template.
  • [34] O722AOKE Add route to allow crediting of events to users/projects.
  • [35] HO2PFRAB Client login now handles response correctly.
  • [*] 64C6AWH6 Rename Ananke -> Quixotic, project reboot.
  • [*] GCVQD44V Create amends endpoint, switch to UUID primary keys
  • [*] WZUHEZSB Start of migration back toward snap.
  • [*] AXKKXBWN Initial attempt at writing down my ideas for a company based on trust.
  • [*] PBD7LZYQ Postgres & auth are beginning to function.
  • [*] ADMKQQGC Initial empty Snap project.
  • [*] W35DDBFY Factor common JSON conversions up into client lib module.

Change contents

  • replacement in Dockerfile at line 2
    [4.84][4.1:37]()
    FROM phusion/baseimage:0.9.19
    [4.84]
    [4.120]
    FROM ubuntu:focal
  • replacement in Dockerfile at line 8
    [4.231][4.1:26](),[4.26][4.38:231](),[4.219][4.328:383](),[4.231][4.328:383](),[4.328][4.328:383]()
    # Base GHC/cabal install
    RUN echo 'deb http://download.fpcomplete.com/ubuntu xenial main' > /etc/apt/sources.list.d/fpco.list && \
    apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 575159689BEFB442
    # Install libpq-dev to enable postgresql-simple build
    [4.231]
    [4.383]
    # Install build tools & library dependencies
  • edit in Dockerfile at line 12
    [4.204]
    [4.204]
    g++ gcc libc6-dev libffi-dev libgmp-dev make xz-utils zlib1g-dev git gnupg curl \
  • replacement in Dockerfile at line 14
    [4.235][4.235:249](),[4.249][4.1:269]()
    git stack
    # apt-get install -y --no-install-recommends wget && \
    # echo 'deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main' > /etc/apt/sources.list.d/pgdg.list && \
    # wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \
    [4.235]
    [4.269]
    libsecp256k1-dev
    RUN apt-get install -y --no-install-recommends ca-certificates
  • replacement in Dockerfile at line 18
    [4.270][4.270:331](),[4.331][4.1:146]()
    # Install npm, then use it to get purescript, pulp and bower
    # RUN apt-get install -y --no-install-recommends nodejs
    # RUN apt-get install -y --no-install-recommends npm
    # RUN npm install -g npm bower pulp
    [4.270]
    [4.146]
    RUN update-ca-certificates
    ADD ./docker/install_stack.sh /root/
    RUN /bin/sh /root/install_stack.sh
  • replacement in Dockerfile at line 22
    [4.35][4.460:519](),[4.147][4.460:519](),[4.460][4.460:519](),[4.519][4.148:196]()
    # Fix executable name used by the purescript npm installer
    # RUN ln -s /usr/bin/nodejs /usr/local/bin/node
    [4.147]
    [4.196]
    RUN /usr/local/bin/stack upgrade --force-download
  • replacement in Dockerfile at line 27
    [4.375][4.375:411]()
    RUN stack --resolver lts-7.16 setup
    [4.375]
    [4.411]
    RUN /root/.local/bin/stack --resolver lts-13.9 setup
  • replacement in Dockerfile at line 30
    [4.456][4.456:487](),[4.487][2.1:43]()
    RUN stack install dbmigrations
    RUN stack install dbmigrations-postgresql
    [4.456]
    [4.1]
    RUN /root/.local/bin/stack install dbmigrations
    RUN /root/.local/bin/stack install dbmigrations-postgresql
  • replacement in Dockerfile at line 46
    [4.23][4.441:482](),[4.441][4.441:482](),[4.482][4.332:368]()
    RUN stack setup
    RUN stack install cpphs
    RUN stack build --only-dependencies
    [4.23]
    [4.1141]
    RUN /root/.local/bin/stack setup
    RUN /root/.local/bin/stack install cpphs
    RUN apt-get update && apt-get install -y --no-install-recommends libssl-dev
    RUN /root/.local/bin/stack build --only-dependencies -j1
  • replacement in Dockerfile at line 58
    [4.579][4.268:286](),[4.268][4.268:286]()
    RUN stack install
    [4.268]
    [4.1081]
    RUN /root/.local/bin/stack install
  • replacement in Dockerfile at line 60
    [4.1082][4.566:636](),[4.636][4.36:288]()
    # Build the client application and install it where snap can serve it
    #ADD ./client /opt/aftok/client
    #WORKDIR /opt/aftok/client
    #RUN npm install
    #ENV PATH=./node_modules/.bin:${PATH}
    #
    #RUN bower --allow-root install
    #RUN pulp build
    #RUN pulp browserify --optimise --to dist/aftok.js
    #ADD ./dist /opt/aftok/server/static
    [4.1082]
    [4.42]
    # add the s6-overlay init process
    # RUN mkdir -p /etc/services.d/aftok
    # RUN mkdir -p /etc/fix-attrs.d/
    #
    # ADD https://github.com/just-containers/s6-overlay/releases/download/v1.21.8.0/s6-overlay-amd64.tar.gz /tmp/
    # RUN tar xzf /tmp/s6-overlay-amd64.tar.gz -C / --exclude="./bin" && \
    # tar xzf /tmp/s6-overlay-amd64.tar.gz -C /usr ./bin
    #
    # ADD ./docker/aftok-server.sh /etc/services.d/aftok/run
    # ADD ./docker/fix-attrs.d/* /etc/fix-attrs.d/
    #
    # ENTRYPOINT ["/init"]
  • replacement in Dockerfile at line 73
    [4.43][4.580:718]()
    # Add the main shell script that starts the aftok server
    RUN mkdir /etc/service/aftok
    ADD ./docker/aftok-server.sh /etc/service/aftok/run
    [4.43]
    [4.828]
    ENTRYPOINT ["/opt/aftok/bin/aftok-server"]
  • edit in Dockerfile at line 75
    [4.829][4.1413:1473](),[4.1413][4.1413:1473]()
    # Use baseimage-docker's init system.
    CMD ["/sbin/my_init"]
  • edit in Makefile at line 2
    [4.320]
    [4.320]
    PWD=$(shell pwd)
  • replacement in Makefile at line 8
    [4.334][4.334:375]()
    docker build -t nuttycom/aftok:latest .
    [4.334]
    [4.375]
    docker build -t aftok/aftok:latest .
  • replacement in Makefile at line 11
    [4.402][4.402:511]()
    docker tag nuttycom/aftok:latest nuttycom/aftok:$(VERSION)
    docker push docker.io/nuttycom/aftok:$(VERSION)
    [4.402]
    [4.1310]
    docker tag aftok/aftok:latest aftok/aftok:$(VERSION)
    docker push docker.io/aftok/aftok:$(VERSION)
  • replacement in Makefile at line 14
    [4.1311][4.560:594](),[4.594][4.512:614]()
    run-local-docker: build-container
    docker run --net=host -it -v /home/nuttycom/projects/aftok/local/conf/:/etc/aftok aftok/aftok:latest
    [4.1311]
    run-local-docker: build-image
    docker run --net=host -it -v $(PWD)/local/conf/:/etc/aftok aftok/aftok:latest
  • edit in aftok.cabal at line 161
    [38.7248]
    [39.148]
    , directory
  • file addition: nginx (d--r------)
    [4.1]
  • file move: nginx.conf (----------)nginx.conf (----------)
    [0.1614]
    [4.200]
  • edit in deploy/nginx/nginx.conf at line 1
    [4.200]
    [4.201]
    daemon off;
  • edit in deploy/nginx/nginx.conf at line 15
    [4.388]
    [4.388]
    upstream aftok-server {
    server aftok-server:8000;
    }
  • replacement in deploy/nginx/nginx.conf at line 26
    [4.473][4.473:489]()
    listen 443;
    [4.473]
    [4.489]
    listen 443 ssl;
  • replacement in deploy/nginx/nginx.conf at line 29
    [4.517][4.517:621]()
    ssl_certificate /etc/nginx/aftok.crt;
    ssl_certificate_key /etc/nginx/aftok.key;
    [4.517]
    [4.621]
    ssl_certificate /opt/nginx/aftok.crt;
    ssl_certificate_key /opt/nginx/aftok.key;
  • edit in deploy/nginx/nginx.conf at line 32
    [4.622][4.622:634]()
    ssl on;
  • replacement in deploy/nginx/nginx.conf at line 34
    [4.729][4.729:837]()
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;
    [4.729]
    [4.837]
    ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
  • replacement in deploy/nginx/nginx.conf at line 45
    [4.1224][4.1224:1303]()
    proxy_pass http://localhost:8000;
    proxy_read_timeout 90;
    [4.1224]
    [4.1303]
    proxy_pass http://aftok-server;
    proxy_read_timeout 90;
  • replacement in deploy/nginx/nginx.conf at line 48
    [4.1304][4.1304:1371]()
    proxy_redirect http://localhost:8000 https://aftok.com;
    [4.1304]
    [4.1371]
    proxy_redirect http://aftok-server https://aftok.com;
  • replacement in docker/aftok-server.sh at line 1
    [4.1530][4.1531:1543]()
    #!/bin/bash
    [4.1530]
    [4.1543]
    #!/usr/bin/execlineb -P
  • replacement in docker/aftok-server.sh at line 3
    [4.1544][2.46:132]()
    /root/.local/bin/moo-postgresql upgrade --config-file=/etc/aftok/aftok-migrations.cfg
    [4.1544]
    [4.289]
    s6-setuidgid daemon
    # /root/.local/bin/moo-postgresql upgrade --config-file=/etc/aftok/aftok-migrations.cfg
    backtick AFTOK_CFG { echo "/etc/aftok/aftok.cfg" }
  • file addition: install_stack.sh (----------)
    [4.1510]
    #!/bin/sh -e
    #
    # Stack installation script.
    #
    # This script is meant for quick & easy install via:
    # 'curl -sSL https://get.haskellstack.org/ | sh'
    # or:
    # 'wget -qO- https://get.haskellstack.org/ | sh'
    #
    # By default, this installs 'stack' to '/usr/local/bin'.
    #
    # Arguments (use `... | sh -s - ARGUMENTS`)
    #
    # -q: reduce script's output
    # -f: force over-write even if 'stack' already installed
    # -d DESTDIR: change destination directory
    #
    # Make pull requests at:
    # https://github.com/commercialhaskell/stack/blob/master/etc/scripts/get-stack.sh
    #
    # Note that this script will ask for root access using `sudo` in order to use
    # your platform's package manager to install dependencies and to install to
    # `/usr/local/bin`. If you prefer more control, follow the manual
    # installation instructions for your platform at:
    # https://docs.haskellstack.org/en/stable/install_and_upgrade/
    #
    STACK_VERSION="2.1.3"
    HOME_LOCAL_BIN="$HOME/.local/bin"
    DEFAULT_DEST="/usr/local/bin/stack"
    # Windows doesn't have a good place for DEST, but all CI systems (Appveyor, Travis, Azure) support /bin
    DEFAULT_DEST_WINDOWS="/bin/stack"
    DEST=""
    QUIET=""
    FORCE=""
    STACK_TEMP_DIR=
    # creates a temporary directory, which will be cleaned up automatically
    # when the script finishes
    make_temp_dir() {
    STACK_TEMP_DIR="$(mktemp -d 2>/dev/null || mktemp -d -t stack)"
    }
    # cleanup the temporary directory if it's been created. called automatically
    # when the script exits.
    cleanup_temp_dir() {
    if [ -n "$STACK_TEMP_DIR" ] ; then
    rm -rf "$STACK_TEMP_DIR"
    STACK_TEMP_DIR=
    fi
    }
    # print a message to stderr and exit with error code
    die() {
    echo "$@" >&2
    exit 1
    }
    # print a message to stdout unless '-q' passed to script
    info() {
    if [ -z "$QUIET" ] ; then
    echo "$@"
    fi
    }
    # print a separator for post-install messages
    post_install_separator() {
    info ""
    info "-------------------------------------------------------------------------------"
    info ""
    }
    # determines the the CPU's instruction set
    get_isa() {
    if arch | grep -q armv7 ; then
    echo arm
    elif arch | grep -q aarch64 ; then
    echo aarch64
    else
    echo x86
    fi
    }
    # exits with code 0 if arm ISA is detected as described above
    is_arm() {
    test "$(get_isa)" = arm
    }
    # exits with code 0 if aarch64 ISA is detected as described above
    is_aarch64() {
    test "$(get_isa)" = aarch64
    }
    # determines 64- or 32-bit architecture
    # if getconf is available, it will return the arch of the OS, as desired
    # if not, it will use uname to get the arch of the CPU, though the installed
    # OS could be 32-bits on a 64-bit CPU
    get_arch() {
    if has_getconf ; then
    if getconf LONG_BIT | grep -q 64 ; then
    echo 64
    else
    echo 32
    fi
    else
    case "$(uname -m)" in
    *64)
    echo 64
    ;;
    *)
    echo 32
    ;;
    esac
    fi
    }
    # exits with code 0 if a 64-bit architecture is detected as described above
    is_64_bit() {
    test "$(get_arch)" = 64
    }
    # prints a generic bindist notice
    print_bindist_notice() {
    if [ -z "$1" ] ; then
    info ""
    info "Using generic bindist..."
    info ""
    else
    info ""
    info "Using generic $1 bindist..."
    info ""
    fi
    }
    # Adds a 'sudo' prefix if sudo is available to execute the given command
    # If not, the given command is run as is
    # When requesting root permission, always show the command and never re-use cached credentials.
    sudocmd() {
    reason="$1"; shift
    if command -v sudo >/dev/null; then
    echo
    echo "About to use 'sudo' to run the following command as root:"
    echo " $@"
    echo "in order to $reason."
    echo
    # -k: Disable cached credentials (force prompt for password).
    sudo -k "$@"
    else
    "$@"
    fi
    }
    # Install dependencies for distros that use Apt
    apt_install_dependencies() {
    info "Installing dependencies..."
    info ""
    apt_get_install_pkgs "$@"
    }
    # Attempts an install on Ubuntu via apt, if possible
    # Expects the version (in Major.Minor format, with any sub-minor removed)
    # as the first and only argument
    # If the version of Ubuntu is unsupported, it attempts to copy the binary
    # and install the necessary dependencies explicitly.
    do_ubuntu_install() {
    install_dependencies() {
    apt_install_dependencies g++ gcc libc6-dev libffi-dev libgmp-dev make xz-utils zlib1g-dev git gnupg netbase
    }
    if is_arm ; then
    install_dependencies
    print_bindist_notice
    install_arm_binary
    elif is_aarch64 ; then
    install_dependencies
    print_bindist_notice
    install_aarch64_binary
    elif is_64_bit ; then
    install_dependencies
    print_bindist_notice
    install_64bit_standard_binary
    else
    install_dependencies
    print_bindist_notice
    install_32bit_standard_binary
    fi
    }
    # Attempts an install on Debian.
    # Expects the single-number version as the first and only argument
    # If the version of Debian is unsupported, it attempts to copy the binary
    # and install the necessary dependencies explicitly.
    do_debian_install() {
    install_dependencies() {
    apt_install_dependencies g++ gcc libc6-dev libffi-dev libgmp-dev make xz-utils zlib1g-dev git gnupg netbase
    }
    if is_arm ; then
    install_dependencies
    print_bindist_notice
    install_arm_binary
    elif is_aarch64 ; then
    install_dependencies
    print_bindist_notice
    install_aarch64_binary
    elif is_64_bit ; then
    install_dependencies
    print_bindist_notice
    install_64bit_standard_binary
    else
    install_dependencies
    print_bindist_notice
    install_32bit_standard_binary
    fi
    }
    # Attempts an install on Fedora.
    # Expects the single-number version as the first and only argument
    # If the version of Fedora is unsupported, it attempts to copy the binary
    # and install the necessary dependencies explicitly.
    do_fedora_install() {
    install_dependencies() {
    dnf_install_pkgs perl make automake gcc gmp-devel libffi zlib-devel xz tar git gnupg
    }
    if is_64_bit ; then
    install_dependencies "$1"
    print_bindist_notice
    install_64bit_standard_binary
    else
    install_dependencies "$1"
    print_bindist_notice
    install_32bit_standard_binary
    fi
    }
    # Attempts an install on CentOS.
    # Expects the single-number version as the first and only argument
    # If the version of CentOS is unsupported, it attempts to copy the binary
    # and install the necessary dependencies explicitly.
    do_centos_install() {
    install_dependencies() {
    yum_install_pkgs perl make automake gcc gmp-devel libffi zlib xz tar git gnupg
    }
    if is_64_bit ; then
    install_dependencies
    print_bindist_notice
    install_64bit_standard_binary
    else
    case "$1" in
    "6"*)
    die "Sorry, there is currently no Linux 32-bit gmp4 binary available."
    ;;
    *)
    install_dependencies
    print_bindist_notice
    install_32bit_standard_binary
    ;;
    esac
    fi
    }
    # Attempts to install on Windows, designed for CI scripts (tested on Appveyor, Travis, Azure)
    do_windows_install() {
    info "Using Windows install.."
    info ""
    make_temp_dir
    dl_to_file "http://www.stackage.org/stack/windows-x86_64" "$STACK_TEMP_DIR/stack.zip"
    if [ "$(basename $DEST)" != "stack" ]; then
    # should never happen, the -d flag appends stack itself
    die "Currently the destination must always end with 'stack' on Windows, got: $DEST"
    fi
    if ! 7z x $STACK_TEMP_DIR/stack.zip stack.exe "-o$(dirname $DEST)"; then
    die "Extract zip file failed, you probably don't have 7z installed"
    fi
    post_install_separator
    info "Stack has been installed to: $DEST"
    info ""
    check_dest_on_path
    }
    # Attempts to install on macOS.
    # If 'brew' exists, installs using Homebrew. Otherwise, installs
    # the generic bindist.
    do_osx_install() {
    info "Using generic bindist..."
    info ""
    install_64bit_osx_binary
    info "NOTE: You may need to run 'xcode-select --install' and/or"
    info " 'open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg'"
    info " to set up the Xcode command-line tools, which Stack uses."
    info ""
    }
    # Attempts to insall on FreeBSD. Installs dependencies with
    # 'pkg install' and then downloads bindist.
    do_freebsd_install() {
    install_dependencies() {
    pkg_install_pkgs devel/gmake perl5 lang/gcc misc/compat8x misc/compat9x converters/libiconv ca_root_nss
    }
    if is_64_bit ; then
    install_dependencies
    install_64bit_freebsd_binary
    else
    die "Sorry, there is currently no 32-bit FreeBSD binary available."
    fi
    }
    # Alpine distro install
    do_alpine_install() {
    install_dependencies() {
    apk_install_pkgs gmp libgcc xz make
    }
    install_dependencies
    if is_64_bit ; then
    print_bindist_notice
    install_64bit_standard_binary
    else
    die "Sorry, there is currently no 32-bit Alpine Linux binary available."
    fi
    }
    # Attempts to install on unsupported Linux distribution by downloading
    # the bindist.
    do_sloppy_install() {
    info "This installer doesn't support your Linux distribution, trying generic"
    info "bindist..."
    info ""
    if is_arm ; then
    install_arm_binary
    elif is_aarch64 ; then
    install_aarch64_binary
    elif is_64_bit ; then
    install_64bit_standard_binary
    else
    install_32bit_standard_binary
    fi
    info "Since this installer doesn't support your Linux distribution,"
    info "there is no guarantee that 'stack' will work at all! You may"
    info "need to manually install some system info dependencies for GHC:"
    info " gcc, make, libffi, zlib, libgmp and libtinfo"
    info "Please see http://docs.haskellstack.org/en/stable/install_and_upgrade/"
    info "Pull requests to add support for this distro would be welcome!"
    info ""
    }
    # Attempts to determine the running Linux distribution.
    # Prints "DISTRO;VERSION" (distribution name and version)"."
    distro_info() {
    parse_lsb() {
    lsb_release -a 2> /dev/null | perl -ne "$1"
    }
    try_lsb() {
    if has_lsb_release ; then
    TL_DIST="$(parse_lsb 'if(/Distributor ID:\s+([^ ]+)/) { print "\L$1"; }')"
    TL_VERSION="$(parse_lsb 'if(/Release:\s+([^ ]+)/) { print "\L$1"; }')"
    echo "$TL_DIST;$TL_VERSION"
    else
    return 1
    fi
    }
    try_release() {
    parse_release() {
    perl -ne "$1" /etc/*release 2>/dev/null
    }
    parse_release_id() {
    parse_release 'if(/^(DISTRIB_)?ID\s*=\s*"?([^"]+)/) { print "\L$2"; exit 0; }'
    }
    parse_release_version() {
    parse_release 'if(/^(DISTRIB_RELEASE|VERSION_ID)\s*=\s*"?([^"]+)/) { print $2; exit 0; }'
    }
    TR_RELEASE="$(parse_release_id);$(parse_release_version)"
    if [ ";" = "$TR_RELEASE" ] ; then
    if [ -e /etc/arch-release ] ; then
    # /etc/arch-release exists but is often empty
    echo "arch;"
    elif [ -e /etc/centos-release ] && grep -q "\<6\>" /etc/centos-release ; then
    # /etc/centos-release has a non-standard format before version 7
    echo "centos;6"
    else
    return 1
    fi
    else
    echo "$TR_RELEASE"
    fi
    }
    try_issue() {
    case "$(cat /etc/issue 2>/dev/null)" in
    "Arch Linux"*)
    echo "arch;" # n.b. Version is not available in /etc/issue on Arch
    ;;
    "Ubuntu"*)
    echo "ubuntu;$(perl -ne 'if(/Ubuntu (\d+\.\d+)/) { print $1; }' < /etc/issue)"
    ;;
    "Debian"*)
    echo "debian;$(perl -ne 'if(/Debian GNU\/Linux (\d+(\.\d+)?)/) { print $1; }' < /etc/issue)"
    ;;
    *"SUSE"*)
    echo "suse;$(perl -ne 'if(/SUSE\b.* (\d+\.\d+)/) { print $1; }' < /etc/issue)"
    ;;
    *"NixOS"*)
    echo "nixos;$(perl -ne 'if(/NixOS (\d+\.\d+)/) { print $1; }' < /etc/issue)"
    ;;
    "CentOS"*)
    echo "centos;$(perl -ne 'if(/^CentOS release (\d+)\./) { print $1; }' < /etc/issue)"
    ;;
    *)
    esac
    # others do not output useful info in issue, return empty
    }
    try_lsb || try_release || try_issue
    }
    # Attempt to install on a Linux distribution
    do_distro() {
    if ! has_perl ; then
    if ! try_install_pkgs perl ; then
    #TODO: remove dependence on 'perl', which is not installed by default
    #on some distributions (Fedora and RHEL, in particular).
    die "This script requires 'perl', please install it to continue."
    fi
    fi
    IFS=";" read -r DISTRO VERSION <<GETDISTRO
    $(distro_info)
    GETDISTRO
    if [ -n "$DISTRO" ] ; then
    info "Detected Linux distribution: $DISTRO"
    info ""
    fi
    case "$DISTRO" in
    ubuntu|linuxmint|elementary|neon)
    do_ubuntu_install "$VERSION"
    ;;
    debian|kali|raspbian|mx)
    do_debian_install "$VERSION"
    ;;
    fedora)
    do_fedora_install "$VERSION"
    ;;
    centos|rhel|redhatenterpriseserver)
    do_centos_install "$VERSION"
    ;;
    alpine)
    do_alpine_install "$VERSION"
    ;;
    *)
    do_sloppy_install
    esac
    }
    set_default_dest() {
    [ "$DEST" != "" ] || DEST="$DEFAULT_DEST"
    }
    # Determine operating system and attempt to install.
    do_os() {
    case "$(uname)" in
    "Linux")
    set_default_dest
    do_distro
    ;;
    "Darwin")
    set_default_dest
    do_osx_install
    ;;
    "FreeBSD")
    set_default_dest
    do_freebsd_install
    ;;
    MINGW64_NT-*|MSYS_NT-*)
    DEFAULT_DEST="$DEFAULT_DEST_WINDOWS"
    set_default_dest
    do_windows_install
    ;;
    *)
    die "Sorry, this installer does not support your operating system: $(uname).
    See http://docs.haskellstack.org/en/stable/install_and_upgrade/"
    esac
    }
    # Download a URL to file using 'curl' or 'wget'.
    dl_to_file() {
    if has_curl ; then
    if ! curl ${QUIET:+-sS} -L -o "$2" "$1"; then
    die "curl download failed: $1"
    fi
    elif has_wget ; then
    if ! wget ${QUIET:+-q} "-O$2" "$1"; then
    die "wget download failed: $1"
    fi
    else
    # should already have checked for this, otherwise this message will probably
    # not be displayed, since dl_to_stdout will be part of a pipeline
    die "Neither wget nor curl is available, please install one to continue."
    fi
    }
    # Check for 'curl' or 'wget' and attempt to install 'curl' if neither found,
    # or fail the script if that is not possible.
    check_dl_tools() {
    if ! has_curl && ! has_wget ; then
    if ! try_install_pkgs curl ; then
    die "Neither wget nor curl is available, please install one to continue."
    fi
    fi
    }
    # Download a Stack bindst and install it in /usr/local/bin/stack.
    install_from_bindist() {
    IFB_URL="https://github.com/commercialhaskell/stack/releases/download/v${STACK_VERSION}/stack-${STACK_VERSION}-$1"
    check_dl_tools
    make_temp_dir
    dl_to_file "$IFB_URL" "$STACK_TEMP_DIR/$1.bindist"
    mkdir -p "$STACK_TEMP_DIR/$1"
    if ! tar xzf "$STACK_TEMP_DIR/$1.bindist" -C "$STACK_TEMP_DIR/$1"; then
    die "Extract bindist failed"
    fi
    STACK_TEMP_EXE="$STACK_TEMP_DIR/$(basename "$DEST")"
    mv "$STACK_TEMP_DIR/$1"/*/stack "$STACK_TEMP_EXE"
    destdir="$(dirname "$DEST")"
    if [ ! -d "$destdir" ]; then
    info "$destdir directory does not exist; creating it..."
    # First try to create directory as current user, then try with sudo if it fails.
    if ! mkdir -p "$destdir" 2>/dev/null; then
    if ! sudocmd "create the destination directory" mkdir -p "$destdir"; then
    die "Could not create directory: $DEST"
    fi
    fi
    fi
    # First attempt to install 'stack' as current user, then try with sudo if it fails
    info "Installing Stack to: $DEST..."
    if ! install -c -m 0755 "$STACK_TEMP_EXE" "$destdir" 2>/dev/null; then
    if ! sudocmd "copy 'stack' to the destination directory" install -c -o 0 -g 0 -m 0755 "$STACK_TEMP_EXE" "$destdir"; then
    die "Install to $DEST failed"
    fi
    fi
    post_install_separator
    info "Stack has been installed to: $DEST"
    info ""
    check_dest_on_path
    }
    install_arm_binary() {
    install_from_bindist "linux-arm.tar.gz"
    }
    install_32bit_standard_binary() {
    install_from_bindist "linux-i386.tar.gz"
    }
    install_64bit_standard_binary() {
    install_from_bindist "linux-x86_64-static.tar.gz"
    }
    install_aarch64_binary() {
    install_from_bindist "linux-aarch64.tar.gz"
    }
    install_64bit_gmp4_linked_binary() {
    install_from_bindist "linux-x86_64-gmp4.tar.gz"
    }
    install_64bit_gmp4_linked_binary() {
    install_from_bindist "linux-x86_64-gmp4"
    }
    install_64bit_osx_binary() {
    install_from_bindist "osx-x86_64.tar.gz"
    }
    install_64bit_freebsd_binary() {
    install_from_bindist "freebsd-x86_64.tar.gz"
    }
    # Attempt to install packages using whichever of apt-get, dnf, yum, or apk is
    # available.
    try_install_pkgs() {
    if has_apt_get ; then
    apt_get_install_pkgs "$@"
    elif has_dnf ; then
    dnf_install_pkgs "$@"
    elif has_yum ; then
    yum_install_pkgs "$@"
    elif has_apk ; then
    apk_install_pkgs "$@"
    else
    return 1
    fi
    }
    # Install packages using apt-get
    apt_get_install_pkgs() {
    missing=
    for pkg in $*; do
    if ! dpkg -s $pkg 2>/dev/null |grep '^Status:.*installed' >/dev/null; then
    missing="$missing $pkg"
    fi
    done
    if [ "$missing" = "" ]; then
    info "Already installed!"
    elif ! sudocmd "install required system dependencies" apt-get install -y ${QUIET:+-qq}$missing; then
    die "Installing apt packages failed. Please run 'apt-get update' and try again."
    fi
    }
    # Install packages using dnf
    dnf_install_pkgs() {
    if ! sudocmd "install required system dependencies" dnf install -y ${QUIET:+-q} "$@"; then
    die "Installing dnf packages failed. Please run 'dnf check-update' and try again."
    fi
    }
    # Install packages using yum
    yum_install_pkgs() {
    if ! sudocmd "install required system dependencies" yum install -y ${QUIET:+-q} "$@"; then
    die "Installing yum packages failed. Please run 'yum check-update' and try again."
    fi
    }
    # Install packages using apk
    apk_install_pkgs() {
    if ! sudocmd "install required system dependencies" apk add --update ${QUIET:+-q} "$@"; then
    die "Installing apk packages failed. Please run 'apk update' and try again."
    fi
    }
    # Install packages using pkg
    pkg_install_pkgs() {
    if ! sudocmd "install required system dependencies" pkg install -y "$@"; then
    die "Installing pkg packages failed. Please run 'pkg update' and try again."
    fi
    }
    # Get installed Stack version, if any
    installed_stack_version() {
    stack --version | grep -o 'Version \([[:digit:]]\|\.\)\+' | tr A-Z a-z
    }
    # Get installed Stack's path
    stack_location() {
    command -v stack
    }
    # Check whether 'stack' command exists
    has_stack() {
    if [ "$DEST" != "" ] ; then
    has_cmd "$DEST"
    else
    has_cmd stack
    fi
    }
    # Check whether 'wget' command exists
    has_wget() {
    has_cmd wget
    }
    # Check whether 'curl' command exists
    has_curl() {
    has_cmd curl
    }
    # Check whether 'lsb_release' command exists
    has_lsb_release() {
    has_cmd lsb_release
    }
    # Check whether 'sudo' command exists
    has_sudo() {
    has_cmd sudo
    }
    # Check whether 'getconf' command exists
    has_getconf() {
    has_cmd getconf
    }
    # Check whether 'brew' command exists
    #has_brew() {
    # has_cmd brew
    #}
    # Check whether 'perl' command exists
    has_perl() {
    has_cmd perl
    }
    # Check whether 'apt-get' command exists
    has_apt_get() {
    has_cmd apt-get
    }
    # Check whether 'yum' command exists
    has_yum() {
    has_cmd yum
    }
    # Check whether 'apk' command exists
    has_apk() {
    has_cmd apk
    }
    # Check whether 'dnf' command exists
    has_dnf() {
    has_cmd dnf
    }
    # Check whether the given command exists
    has_cmd() {
    command -v "$1" > /dev/null 2>&1
    }
    # Check whether the given path is listed in the PATH environment variable
    on_path() {
    echo ":$PATH:" | grep -q :"$1":
    }
    # Check whether ~/.local/bin is on the PATH, and print a warning if not.
    check_home_local_bin_on_path() {
    if ! on_path "$HOME_LOCAL_BIN" ; then
    #TODO: offer to add it for the user (pull requests welcome!)
    info "WARNING: '$HOME_LOCAL_BIN' is not on your PATH."
    info " For best results, please add it to the beginning of PATH in your profile."
    info ""
    fi
    }
    # Check whether $DEST is on the PATH, and print a warning if not.
    check_dest_on_path() {
    if ! on_path "$(dirname $DEST)" ; then
    info "WARNING: '$(dirname $DEST)' is not on your PATH."
    info ""
    fi
    }
    # Check whether Stack is already installed, and print an error if it is.
    check_stack_installed() {
    if has_stack ; then
    if [ "$FORCE" = "true" ] ; then
    [ "$DEST" != "" ] || DEST="$(stack_location)"
    else
    if has_curl; then
    get="curl -sSL"
    else
    get="wget -qO-"
    fi
    [ "$DEST" != "" ] && location=$(realpath "$DEST") || location=$(stack_location)
    die "Stack $(installed_stack_version) already appears to be installed at:
    $location
    Use 'stack upgrade' or your OS's package manager to upgrade,
    or pass '-f' to this script to over-write the existing binary, e.g.:
    $get https://get.haskellstack.org/ | sh -s - -f
    To install to a different location, pass '-d DESTDIR', e.g.:
    $get https://get.haskellstack.org/ | sh -s - -d /opt/stack-$STACK_VERSION/bin"
    fi
    fi
    }
    trap cleanup_temp_dir EXIT
    while [ $# -gt 0 ]; do
    case "$1" in
    -q|--quiet)
    # This tries its best to reduce output by suppressing the script's own
    # messages and passing "quiet" arguments to tools that support them.
    QUIET="true"
    shift
    ;;
    -f|--force)
    FORCE="true"
    shift
    ;;
    -d|--dest)
    DEST="$2/stack"
    shift 2
    ;;
    *)
    echo "Invalid argument: $1" >&2
    exit 1
    ;;
    esac
    done
    check_stack_installed
    do_os
    check_home_local_bin_on_path
  • file addition: docker-compose.yml (----------)
    [40.2]
    version: "3.7"
    services:
    aftok:
    image: aftok/aftok-server:latest
    container_name: aftok-server
    expose:
    - "8000"
    depends_on:
    - aftokdb
    volumes:
    - type: bind
    source: ${PWD}/local/conf/server
    target: /etc/aftok
    networks:
    - front-tier
    - back-tier
    init: true
    nginx:
    image: nginx:latest
    container_name: aftok-nginx
    ports:
    - "8080:80"
    - "8443:443"
    depends_on:
    - aftok
    volumes:
    - type: bind
    source: ${PWD}/deploy/nginx/
    target: /etc/nginx
    - type: bind
    source: ${PWD}/local/conf/nginx-certs
    target: /opt/nginx
    networks:
    - front-tier
    aftokdb:
    image: postgres:9.4
    container_name: aftok-db
    environment:
    POSTGRES_USER: "postgres"
    POSTGRES_PASSWORD: "postgres"
    volumes:
    - type: volume
    source: aftok-data
    target: /var/lib/postgresql/data
    networks:
    - back-tier
    volumes:
    aftok-data:
    networks:
    front-tier:
    back-tier:
  • replacement in migrations/2016-10-13_05-36-55_user-event-log.txt at line 5
    [4.187][4.7396:7444]()
    --create extension if not exists "uuid-ossp";
    [4.187]
    [4.233]
    -- create extension if not exists "uuid-ossp";
  • replacement in server/Aftok/QConfig.hs at line 1
    [4.4500][4.16673:16707]()
    {-# LANGUAGE TypeApplications #-}
    [4.4500]
    [4.4501]
    {-# LANGUAGE TemplateHaskell #-}
    {-# LANGUAGE OverloadedStrings #-}
  • edit in server/Aftok/QConfig.hs at line 8
    [4.4552]
    [4.32426]
    import Control.Lens (makeLenses, (^.))
  • edit in server/Aftok/QConfig.hs at line 12
    [4.6698]
    [4.32480]
    import System.Directory (doesFileExist, doesPathExist, listDirectory)
  • replacement in server/Aftok/QConfig.hs at line 14
    [4.32544][4.32544:32612]()
    import Filesystem.Path.CurrentOS (FilePath, fromText, encodeString)
    [4.32544]
    [4.4736]
    import Filesystem.Path.CurrentOS (FilePath, fromText, encodeString, parent)
  • edit in server/Aftok/QConfig.hs at line 21
    [4.32643][3.34057:34111]()
    import Aftok.Currency.Bitcoin (NetworkMode)
  • replacement in server/Aftok/QConfig.hs at line 23
    [4.4863][4.7029:7086](),[4.7086][4.32644:32674](),[4.7126][4.4944:4975](),[4.32674][4.4944:4975](),[4.4944][4.4944:4975](),[4.4975][4.7127:7190](),[4.7190][4.218:253](),[4.253][4.32675:32737](),[4.32737][3.34112:34143]()
    { hostname :: ByteString
    , port :: Int
    , authSiteKey :: FilePath
    , cookieTimeout :: Maybe Int
    , pgsConfig :: PGSConfig
    , smtpConfig :: SmtpConfig
    , billingConfig :: BillingConfig
    , templatePath :: FilePath
    , staticAssetPath :: FilePath
    , networkMode :: NetworkMode
    [4.4863]
    [4.534]
    { _hostname :: ByteString
    , _port :: Int
    , _authSiteKey :: FilePath
    , _cookieTimeout :: Maybe Int
    , _pgsConfig :: PGSConfig
    , _smtpConfig :: SmtpConfig
    , _billingConfig :: BillingConfig
    , _templatePath :: FilePath
    , _staticAssetPath :: FilePath
  • edit in server/Aftok/QConfig.hs at line 33
    [4.538]
    [4.5084]
    makeLenses ''QConfig
  • edit in server/Aftok/QConfig.hs at line 38
    [4.5183]
    [4.32777]
    cfgExists <- doesFileExist $ encodeString cfgFile
    pathExists <- doesPathExist $ encodeString cfgFile
    files <- listDirectory (encodeString $ parent cfgFile)
    putStrLn $ "Loading config from: " <> (pack . encodeString $ cfgFile)
    <> "; file exists = " <> (pack . show $ cfgExists)
    <> "; path exists = " <> (pack . show $ pathExists)
    <> "; parent dir = " <> (pack . encodeString $ parent cfgFile)
    <> "; dir contents = " <> (pack . show $ files)
  • replacement in server/Aftok/QConfig.hs at line 49
    [4.32903][4.5294:5321](),[4.5294][4.5294:5321]()
    readQConfig cfg dbEnvCfg
    [4.32903]
    [4.5321]
    conf <- readQConfig cfg dbEnvCfg
    putStrLn $ "Config loaded successfully."
    pure conf
  • edit in server/Aftok/QConfig.hs at line 64
    [4.33148][3.34144:34186]()
    <*> C.require cfg "networkMode"
  • replacement in server/Aftok/QConfig.hs at line 67
    [4.7545][4.7545:7601]()
    SC.setHostname (hostname qc) .
    SC.setPort (port qc)
    [4.7545]
    [4.6085]
    SC.setHostname (qc ^. hostname) .
    SC.setPort (qc ^. port)
  • replacement in server/Aftok/Snaplet/Projects.hs at line 85
    [4.2837][4.37040:37081]()
    let SmtpConfig{..} = QC.smtpConfig cfg
    [4.2837]
    [4.37081]
    let SmtpConfig{..} = cfg ^. QC.smtpConfig
  • replacement in server/Aftok/Snaplet/Projects.hs at line 87
    [4.37173][4.2838:2920](),[4.1459][4.2838:2920]()
    in buildProjectInviteEmail (templatePath cfg) pn fromEmail toEmail invCode >>=
    [4.37173]
    [4.37174]
    in buildProjectInviteEmail (cfg ^. templatePath) pn fromEmail toEmail invCode >>=
  • replacement in server/Aftok/Snaplet/Projects.hs at line 97
    [4.1882][4.1882:1953](),[4.1953][4.37247:37305]()
    buildProjectInviteEmail templatePath pn fromEmail toEmail invCode = do
    templates <- directoryGroup $ encodeString templatePath
    [4.1882]
    [4.1954]
    buildProjectInviteEmail tpath pn fromEmail toEmail invCode = do
    templates <- directoryGroup $ encodeString tpath
  • edit in server/Main.hs at line 5
    [42.5260]
    [4.11228]
    import Control.Lens ((^.), to)
  • edit in server/Main.hs at line 16
    [43.943]
    [3.36813]
    import qualified Aftok.Config as C
  • replacement in server/Main.hs at line 44
    [4.11874][4.37961:38079](),[4.19237][4.12521:12579](),[4.38079][4.12521:12579](),[4.12521][4.12521:12579]()
    initCookieSessionManager (encodeString $ authSiteKey cfg) "quookie" (Just "aftok.com") (cookieTimeout cfg)
    pgs <- nestSnaplet "db" db $ pgsInit' (pgsConfig cfg)
    [4.11874]
    [4.8692]
    initCookieSessionManager (cfg ^. authSiteKey . to encodeString)
    "quookie"
    (Just "aftok.com")
    (cfg ^. cookieTimeout)
    pgs <- nestSnaplet "db" db $ pgsInit' (cfg ^. pgsConfig)
  • replacement in server/Main.hs at line 51
    [3.36851][3.36851:36883]()
    let nmode = Q.networkMode cfg
    [3.36851]
    [4.2274]
    let nmode = cfg ^. billingConfig . C.networkMode
  • replacement in server/Main.hs at line 83
    [4.39418][4.39418:39532]()
    submitPaymentRoute = serveJSON paymentIdJSON $ method POST (paymentResponseHandler $ billingConfig cfg)
    [4.39418]
    [4.2549]
    submitPaymentRoute = serveJSON paymentIdJSON $ method POST (paymentResponseHandler $ cfg ^. billingConfig)
  • replacement in server/Main.hs at line 85
    [4.2550][4.39533:39611]()
    addRoutes [ ("static", serveDirectory . encodeString $ staticAssetPath cfg)
    [4.2550]
    [4.2569]
    addRoutes [ ("static", serveDirectory . encodeString $ cfg ^. staticAssetPath)