diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..a3bed722a --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,305 @@ +version: 2 + +presets: + defaults: &defaults + working_directory: ~/src + docker: + - image: omisegoimages/ewallet-builder:stable + environment: + IMAGE_NAME: "omisego/ewallet" + + +jobs: + build_test: + <<: *defaults + steps: + - checkout + - restore_cache: &ewallet_deps + name: Restoring eWallet dependencies from cache + keys: + - v1-ewallet-deps-{{ checksum "mix.lock" }} + - v1-ewallet-deps- + - restore_cache: &ewallet_test_build + name: Restoring eWallet test artifacts from cache + keys: + - v1-ewallet-test-build-{{ checksum "mix.exs" }} + - v1-ewallet-test-build- + - run: + name: Retrieving eWallet dependencies + command: | + set -xe + # Force rebuilding bcrypt_elixir otherwise it's gonna fail loading NIFs + find deps/ -name bcrypt_elixir -print0 | xargs -0 rm -rf || true + make deps-ewallet + - save_cache: + name: Caching eWallet dependencies + key: v1-ewallet-deps-{{ checksum "mix.lock" }} + paths: + - deps + - run: + name: Building eWallet in test environment + command: | + set -xe + # Force rebuilding bcrypt_elixir otherwise it's gonna fail loading NIFs + find _build/ -name bcrypt_elixir -print0 | xargs -0 rm -rf || true + make build-test + - save_cache: + name: Caching eWallet test artifacts + key: v1-ewallet-test-build-{{ checksum "mix.exs" }} + paths: + - _build/test + + lint: + <<: *defaults + steps: + - checkout + - restore_cache: *ewallet_deps + - restore_cache: *ewallet_test_build + - run: + name: Checking code formattings + command: | + set +xe + make check-format + - run: + name: Checking credo + command: | + set -xe + # Force rebuilding bcrypt_elixir otherwise it's gonna fail loading NIFs + find deps/ -name bcrypt_elixir -print0 | xargs -0 rm -rf || true + find _build/ -name bcrypt_elixir -print0 | xargs -0 rm -rf || true + make deps-ewallet + make check-credo + environment: + MIX_ENV: test + + test: + <<: *defaults + docker: + - image: omisegoimages/ewallet-builder:stable + - image: postgres:9.6-alpine + steps: + - checkout + - restore_cache: *ewallet_deps + - restore_cache: *ewallet_test_build + - restore_cache: &ewallet_deps_assets + name: Restoring eWallet assets dependencies from cache + keys: + - v1-ewallet-assets-deps-{{ checksum "apps/admin_panel/assets/yarn.lock" }} + - v1-ewallet-assets-deps- + - run: + name: Running eWallet tests + command: | + set -xe + # Force rebuilding bcrypt_elixir otherwise it's gonna fail loading NIFs + find deps/ -name bcrypt_elixir -print0 | xargs -0 rm -rf || true + find _build/ -name bcrypt_elixir -print0 | xargs -0 rm -rf || true + make test-ewallet + environment: + DATABASE_URL: postgresql://postgres:@localhost:5432/ewallet + LOCAL_LEDGER_DATABASE_URL: postgresql://postgres:@localhost:5432/ledger + USE_JUNIT: 1 + MIX_ENV: test + - run: + name: Running eWallet assets tests + command: | + set -xe + make deps-assets + make test-assets + - save_cache: + name: Caching eWallet test dependencies + key: v1-ewallet-assets-deps-{{ checksum "apps/admin_panel/assets/yarn.lock" }} + paths: + - apps/admin_panel/assets/node_modules + + build: + <<: *defaults + steps: + - checkout + - restore_cache: *ewallet_deps + - restore_cache: *ewallet_deps_assets + - restore_cache: + name: Restoring eWallet production artifacts from cache + keys: + - v1-ewallet-prod-build-{{ checksum "mix.exs" }} + - v1-ewallet-prod-build- + - setup_remote_docker + - run: + name: Building eWallet in production environment + command: | + set -xe + # Force rebuilding bcrypt_elixir otherwise it's gonna fail loading NIFs + find deps/ -name bcrypt_elixir -print0 | xargs -0 rm -rf || true + find _build/ -name bcrypt_elixir -print0 | xargs -0 rm -rf || true + make build-prod + - save_cache: + name: Caching eWallet artifacts + key: v1-ewallet-prod-build-{{ checksum "mix.exs" }} + paths: + - _build/prod/.mix + - _build/prod/consolidated + - _build/prod/lib + - restore_cache: + name: Restoring Docker image artifacts from cache + keys: + - v1-docker-image-{{ checksum "Dockerfile" }} + - v1-docker-image- + - run: + name: Building Docker image + command: | + set -xe + docker load -i ~/caches/docker-layers.tar || true + make docker-build IMAGE_NAME=$IMAGE_NAME + mkdir -p ~/caches /tmp/workspace + docker save -o ~/caches/docker-layers.tar "$IMAGE_NAME" + docker save -o /tmp/workspace/docker-image.tar "$IMAGE_NAME" + - save_cache: + name: Saving Docker image layer cache + paths: + - ~/caches/docker-layers.tar + key: v1-docker-image-{{ checksum "Dockerfile" }} + - persist_to_workspace: + name: Persisting workspace + root: /tmp/workspace + paths: + - docker-image.tar + + test_e2e: + <<: *defaults + steps: + - setup_remote_docker + - checkout + - attach_workspace: &attach_workspace + name: Attaching workspace + at: /tmp/workspace + - run: + name: Preparing E2E environments + command: | + set -xe + + cat < .env + E2E_HTTP_HOST=http://ewallet:4000 + E2E_SOCKET_HOST=ws://ewallet:4000 + E2E_TEST_ADMIN_EMAIL=$(openssl rand -hex 4)@example.com + E2E_TEST_ADMIN_PASSWORD=$(openssl rand -base64 24 | tr '+/' '-_') + E2E_TEST_ADMIN_1_EMAIL=$(openssl rand -hex 4)@example.com + E2E_TEST_ADMIN_1_PASSWORD=$(openssl rand -base64 24 | tr '+/' '-_') + E2E_TEST_USER_EMAIL=$(openssl rand -hex 4)@example.com + E2E_TEST_USER_PASSWORD=$(openssl rand -base64 24 | tr '+/' '-_') + EOF + + docker load -i /tmp/workspace/docker-image.tar + docker network create net0 + + sh docker-gen.sh -i "$IMAGE_NAME" -n net0 -f .env > docker-compose.override.yml + docker-compose up -d postgres mail + docker-compose run --rm ewallet bin/ewallet initdb + docker-compose run --rm ewallet bin/ewallet seed -e + docker-compose run --rm ewallet bin/ewallet config base_url http://ewallet:4000 + docker-compose run --rm ewallet bin/ewallet config email_adapter smtp + docker-compose run --rm ewallet bin/ewallet config smtp_host mail + docker-compose run --rm ewallet bin/ewallet config smtp_port 1025 + - run: + name: Running E2E tests + command: | + set -xe + + # Primary container cannot connect directly to the Docker-in-Docker instance. + # We need to spawn another image to do so. + git clone https://github.com/omisego/e2e.git ~/e2e + docker create -v /src --name srcs alpine:3.8 /bin/true + docker cp ~/e2e srcs:/src + docker cp .env srcs:/src/e2e/.env + + docker-compose up -d ewallet + trap "docker-compose logs ewallet" 0 1 2 3 6 14 15 + + docker run --rm \ + --init \ + --network net0 \ + --volumes-from srcs \ + omisegoimages/ewallet-builder:stable \ + sh -c "cd /src/e2e && pipenv install && pipenv run robot tests" + + publish: + <<: *defaults + steps: + - setup_remote_docker + - attach_workspace: *attach_workspace + - run: + name: Logging into Docker Hub + command: | + echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin + - run: + name: Publishing Docker image + command: | + set -xe + docker load -i /tmp/workspace/docker-image.tar + + IMAGE_TAG="" + if [ -n "$CIRCLE_TAG" ]; then + _ver="${CIRCLE_TAG#*v}" + + # Given a v1.0.0-pre.1 tag, this will generate: + # - 1.0 + # - 1.0.0-pre + # - 1.0.0-pre.1 + while true; do + case "$_ver" in + *.* ) IMAGE_TAG="$_ver $IMAGE_TAG"; _ver="${_ver%.*}";; + * ) break;; + esac + done + + # In case the commit is HEAD of master branch, also tag stable. + if [ -n "$CIRCLE_REPOSITORY_URL" ] && [ -n "$CIRCLE_SHA1" ]; then + _ref="refs/heads/master" + _head="$(git ls-remote "$CIRCLE_REPOSITORY_URL" "$_ref" | awk '{ print $1 }')" + if [ "$CIRCLE_SHA1" = "$_head" ]; then + IMAGE_TAG="stable $IMAGE_TAG" + fi + fi + elif [ "$CIRCLE_BRANCH" = "master" ]; then + IMAGE_TAG="dev" + IMAGE_TAG="dev-$(git rev-parse --short HEAD) $IMAGE_TAG" + fi + + for tag in $IMAGE_TAG; do + docker tag "$IMAGE_NAME" "$IMAGE_NAME:$tag" + docker push "$IMAGE_NAME:$tag" + done + + +workflows: + version: 2 + test_build: + jobs: + - build_test + + - lint: + requires: + - build_test + + - test: + requires: + - build_test + + - build: + requires: + - lint + - test + filters: &mainline_branches + branches: + only: + - master + tags: + only: /^v.*/ + + - test_e2e: + requires: + - build + filters: *mainline_branches + + - publish: + requires: + - test_e2e + filters: *mainline_branches diff --git a/.dockerignore b/.dockerignore index 247fa8b36..10906c72c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,10 +1,8 @@ # Build -/_build/ /cover/ /deps/ /docs/ /.fetch -*.ez node_modules # Erlang diff --git a/.gitignore b/.gitignore index df246f1c7..4902ec646 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,28 @@ # Build +*.gz +.env +/.fetch /_build/ /cover/ /deps/ -/.fetch -*.ez + +# Docker +docker-compose.override.yml # Erlang erl_crash.dump # Public -/public/uploads /apps/admin_api/public/uploads -!/public/uploads/test.txt -/public/docs /private +/public/docs +/public/uploads +!/public/uploads/test.txt # Dev -.env .DS_Store -Thumbs.db .elixir_ls +Thumbs.db # Load Tester results /results/ diff --git a/Dockerfile b/Dockerfile index 0b3eabca6..7edb877cf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,79 +1,68 @@ -FROM omisegoimages/ewallet-base:1.6-otp20-stretch +FROM alpine:3.8 -COPY . /app -WORKDIR /app +LABEL maintainer="OmiseGO Team " +LABEL description="Official image for OmiseGO eWallet" + +ENV LANG=C.UTF-8 + +## S6 +## + +ENV S6_VERSION="1.21.4.0" + +RUN set -xe \ + && apk add --update --no-cache --virtual .fetch-deps \ + curl \ + ca-certificates \ + && S6_DOWNLOAD_URL="https://github.com/just-containers/s6-overlay/releases/download/v${S6_VERSION}/s6-overlay-amd64.tar.gz" \ + && S6_DOWNLOAD_SHA256="e903f138dea67e75afc0f61e79eba529212b311dc83accc1e18a449d58a2b10c" \ + && curl -fsL -o s6-overlay.tar.gz "${S6_DOWNLOAD_URL}" \ + && echo "${S6_DOWNLOAD_SHA256} s6-overlay.tar.gz" |sha256sum -c - \ + && tar -xzC / -f s6-overlay.tar.gz \ + && rm s6-overlay.tar.gz \ + && apk del .fetch-deps + +## Application +## + +RUN apk add --update --no-cache --virtual .ewallet-runtime \ + bash \ + imagemagick \ + libressl \ + libressl-dev \ + lksctp-tools + +COPY rootfs / -RUN set -xe && \ - groupadd -r ewallet && \ - useradd -r -g ewallet ewallet && \ - chown -R ewallet /app - -RUN set -xe && \ - rm -f /etc/apt/sources.list.d/chris-lea-node_js-stretch.list && \ - curl -fsL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ - curl -fsL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ - echo "deb https://deb.nodesource.com/node_8.x stretch main" > /etc/apt/sources.list.d/nodesource.list && \ - echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list && \ - apt-get update && \ - apt-get install -y nodejs yarn && \ - execlineb -P -c " \ - s6-setuidgid ewallet \ - s6-env HOME=/tmp/ewallet \ - cd /app/apps/admin_panel/assets \ - if { yarn install } \ - if { yarn build } \ - rm -rf node_modules \ - rm -rf /tmp/ewallet \ - " && \ - apt-get remove -y nodejs yarn && \ - apt-get clean && \ - rm -rf /etc/apt/sources.list.d/nodesource.list && \ - rm -rf /etc/apt/sources.list.d/yarn.list - -RUN set -xe && \ - execlineb -P -c " \ - s6-setuidgid ewallet \ - s6-env HOME=/tmp/ewallet \ - s6-env MIX_ENV=prod \ - if { mix local.hex --force } \ - if { mix local.rebar --force } \ - if { mix deps.get } \ - mix compile \ - if {mix docs --output=public/docs} \ - rm -rf /tmp/ewallet" +# USER directive is not being used here since privileges are dropped via +# s6-setuigid in /entrypoint. s6-overlay is required to be run as root. +ARG user=ewallet +ARG group=ewallet +ARG uid=10000 +ARG gid=10000 +RUN set -xe \ + && addgroup -g ${gid} ${group} \ + && adduser -D -h /app -u ${uid} -G ${group} ${user} \ + && chown "${uid}:${gid}" "/app" \ + && chmod +x /entrypoint + +ARG release_version + +ADD _build/prod/rel/ewallet/releases/${release_version}/ewallet.tar.gz /app +RUN chown -R ewallet:ewallet /app +WORKDIR /app + +# eWallet app is using PORT environment variable to determine which port to run +# the application server. ENV PORT 4000 -EXPOSE 4000 -EXPOSE 4369 -EXPOSE 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 - -RUN set -xe && \ - SERVICE_DIR=/etc/services.d/ewallet/ && \ - mkdir -p "$SERVICE_DIR" && \ - echo '#!/bin/execlineb -P' > $SERVICE_DIR/run && \ - echo 'with-contenv' >> $SERVICE_DIR/run && \ - echo 'cd /app' >> $SERVICE_DIR/run && \ - echo 's6-setuidgid ewallet' >> $SERVICE_DIR/run && \ - echo 's6-env HOME=/tmp/ewallet' >> ${SERVICE_DIR}/run && \ - echo 's6-env MIX_ENV=prod' >> $SERVICE_DIR/run && \ - echo 'backtick -in default_host { s6-hostname }' >> $SERVICE_DIR/run && \ - echo 'backtick -in default_cookie { openssl rand -hex 8 }' >> $SERVICE_DIR/run && \ - echo 'importas -iu default_host default_host' >> $SERVICE_DIR/run && \ - echo 'importas -iu default_cookie default_cookie' >> $SERVICE_DIR/run && \ - echo 'importas -D $default_host NODE_HOST NODE_HOST' >> $SERVICE_DIR/run && \ - echo 'importas -D $default_cookie ERLANG_COOKIE ERLANG_COOKIE' >> $SERVICE_DIR/run && \ - echo 'importas -D ewallet NODE_NAME NODE_NAME' >> $SERVICE_DIR/run && \ - echo 'importas -D localhost NODE_DNS NODE_DNS' >> $SERVICE_DIR/run && \ - echo 'elixir' >> $SERVICE_DIR/run && \ - echo ' --erl "-kernel inet_dist_listen_min 6900"' >> $SERVICE_DIR/run && \ - echo ' --erl "-kernel inet_dist_listen_max 6909"' >> $SERVICE_DIR/run && \ - echo ' --name "${NODE_NAME}@${NODE_HOST}"' >> $SERVICE_DIR/run && \ - echo ' --cookie $ERLANG_COOKIE' >> $SERVICE_DIR/run && \ - echo ' -S mix omg.server --no-watch' >> $SERVICE_DIR/run && \ - echo '#!/bin/execlineb -S1' > $SERVICE_DIR/finish && \ - echo 'if { s6-test ${1} -ne 0 }' >> $SERVICE_DIR/finish && \ - echo 'if { s6-test ${1} -ne 256 }' >> $SERVICE_DIR/finish && \ - echo 's6-svscanctl -t /var/run/s6/services' >> $SERVICE_DIR/finish - -ENTRYPOINT ["/init"] \ No newline at end of file +EXPOSE $PORT + +# These are ports required for clustering. The range is defined in vm.args +# in inet_dist_listen_min and inet_dist_listen_max. +EXPOSE 4369 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 + +ENTRYPOINT ["/init", "/entrypoint"] + +CMD ["foreground"] diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 54eff8090..000000000 --- a/Jenkinsfile +++ /dev/null @@ -1,148 +0,0 @@ -def label = "ewallet-${UUID.randomUUID().toString()}" -def yamlSpec = """ -spec: - nodeSelector: - cloud.google.com/gke-preemptible: "true" - tolerations: - - key: dedicated - operator: Equal - value: worker - effect: NoSchedule -""" - -podTemplate( - label: label, - yaml: yamlSpec, - containers: [ - containerTemplate( - name: 'jnlp', - image: 'gcr.io/omise-go/jenkins-slave', - args: '${computer.jnlpmac} ${computer.name}', - resourceRequestCpu: '200m', - resourceLimitCpu: '500m', - resourceRequestMemory: '128Mi', - resourceLimitMemory: '512Mi', - ), - containerTemplate( - name: 'postgresql', - image: 'postgres:9.6.9-alpine', - resourceRequestCpu: '300m', - resourceLimitCpu: '800m', - resourceRequestMemory: '512Mi', - resourceLimitMemory: '1024Mi', - ), - ], - volumes: [ - hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'), - hostPathVolume(mountPath: '/usr/bin/docker', hostPath: '/usr/bin/docker'), - ], -) { - node(label) { - Random random = new Random() - def tmpDir = pwd(tmp: true) - - def project = 'omisego' - def appName = 'ewallet' - def imageName = "${project}/${appName}" - - def nodeIP = getNodeIP() - def gitCommit - - stage('Checkout') { - checkout scm - } - - stage('Build') { - gitCommit = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim() - sh("docker build --pull . -t ${imageName}:${gitCommit}") - } - - stage('Test') { - container('postgresql') { - sh("pg_isready -t 60 -h localhost -p 5432") - } - - sh( - """ - docker run \ - --rm \ - --entrypoint /bin/execlineb \ - -e DATABASE_URL="postgresql://postgres@${nodeIP}:5432/ewallet_${gitCommit}_ewallet" \ - -e LOCAL_LEDGER_DATABASE_URL="postgresql://postgres@${nodeIP}:5432/ewallet_${gitCommit}_local_ledger" \ - ${imageName}:${gitCommit} \ - -P -c " \ - s6-setuidgid ewallet \ - s6-env HOME=/tmp/ewallet \ - s6-env MIX_ENV=test \ - cd /app \ - mix do format --check-formatted, credo, ecto.create, ecto.migrate, test \ - " \ - """.stripIndent() - ) - } - - if (env.BRANCH_NAME == 'master') { - stage('Push') { - withCredentials([file(credentialsId: 'docker', variable: 'DOCKER_CONFIG')]) { - def configDir = sh(script: "dirname ${DOCKER_CONFIG}", returnStdout: true).trim() - sh("docker --config=${configDir} tag ${imageName}:${gitCommit} ${imageName}:latest") - sh("docker --config=${configDir} push ${imageName}:${gitCommit}") - sh("docker --config=${configDir} push ${imageName}:latest") - } - } - - stage('Deploy') { - dir("${tmpDir}/deploy") { - checkout([ - $class: 'GitSCM', - branches: [[name: '*/master']], - userRemoteConfigs: [ - [ - url: 'ssh://git@github.com/omisego/kube.git', - credentialsId: 'github', - ], - ] - ]) - - sh("sed -i.bak 's#${imageName}:latest#${imageName}:${gitCommit}#' staging/k8s/ewallet/deployment.yaml") - sh("kubectl apply -f staging/k8s/ewallet/deployment.yaml") - sh("kubectl rollout status --namespace=staging deployment/ewallet") - - def podID = getPodID('--namespace=staging -l app=ewallet') - - sh( - """ - kubectl exec ${podID} --namespace=staging -- \ - /bin/execlineb -P -c " \ - s6-setuidgid ewallet \ - s6-env HOME=/tmp/ewallet \ - mix ecto.migrate \ - " \ - """.stripIndent() - ) - } - } - } else if (env.BRANCH_NAME == 'master') { - stage('Push') { - withCredentials([file(credentialsId: 'docker', variable: 'DOCKER_CONFIG')]) { - def configDir = sh(script: "dirname ${DOCKER_CONFIG}", returnStdout: true).trim() - sh("docker --config=${configDir} tag ${imageName}:${gitCommit} ${imageName}:stable") - sh("docker --config=${configDir} push ${imageName}:${gitCommit}") - sh("docker --config=${configDir} push ${imageName}:stable") - } - } - } - } -} - -String getNodeIP() { - def rawNodeIP = sh(script: 'ip -4 -o addr show scope global', returnStdout: true).trim() - def matched = (rawNodeIP =~ /inet (\d+\.\d+\.\d+\.\d+)/) - return "" + matched[0].getAt(1) -} - -String getPodID(String opts) { - def pods = sh(script: "kubectl get pods ${opts} -o name", returnStdout: true).trim() - def matched = (pods.split()[0] =~ /pods\/(.+)/) - return "" + matched[0].getAt(1) -} diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..2147b0d3d --- /dev/null +++ b/Makefile @@ -0,0 +1,114 @@ +all: clean build-prod + +RELEASE_VERSION != awk '/version:/ { gsub(/[^0-9a-z\.\-]+/, "", $$2); print $$2 }' < apps/ewallet/mix.exs +IMAGE_NAME ?= "omisego/ewallet:dev" +IMAGE_BUILDER ?= "omisegoimages/ewallet-builder:stable" +IMAGE_BUILD_DIR ?= "/tmp/ewallet-docker" + +# +# Setting-up +# + +deps: deps-ewallet deps-assets + +deps-ewallet: + mix deps.get + +deps-assets: + cd apps/admin_panel/assets && \ + yarn install + +.PHONY: deps deps-ewallet deps-assets + +# +# Cleaning +# + +clean: clean-ewallet clean-assets + +clean-ewallet: + rm -rf _build/ + rm -rf deps/ + +clean-assets: + rm -rf apps/admin_panel/assets/node_modules + rm -rf apps/admin_panel/priv/static + +.PHONY: clean clean-ewallet clean-assets + +# +# Linting +# + +format: + mix format + +check-format: + mix format --check-formatted + +check-credo: + mix credo + +.PHONY: format check-format check-credo + +# +# Building +# + +build-assets: deps-assets + cd apps/admin_panel/assets && \ + yarn build + +# If we call mix phx.digest without mix compile, mix release will silently fail +# for some reason. Always make sure to run mix compile first. +build-prod: deps-ewallet build-assets + env MIX_ENV=prod mix deps.clean mime --build + env MIX_ENV=prod mix compile + env MIX_ENV=prod mix phx.digest + env MIX_ENV=prod mix release + +build-test: deps-ewallet + env MIX_ENV=test mix deps.clean mime --build + env MIX_ENV=test mix compile + +.PHONY: build-assets build-prod build-test + +# +# Testing +# + +test: test-ewallet test-assets + +test-ewallet: build-test + env MIX_ENV=test mix do ecto.create, ecto.migrate, test + +test-assets: build-assets + cd apps/admin_panel/assets && \ + yarn test + +.PHONY: test test-ewallet test-assets + +# +# Docker +# + +docker-prod: + docker run --rm -it \ + -v $(PWD):/app \ + -v $(IMAGE_BUILD_DIR)/elixir_deps:/app/deps \ + -v $(IMAGE_BUILD_DIR)/node_modules:/app/apps/admin_panel/assets/node_modules \ + -u root \ + --entrypoint /bin/sh \ + $(IMAGE_BUILDER) \ + -c "cd /app && make build-prod" + +docker-build: + docker build \ + --build-arg release_version=$(RELEASE_VERSION) \ + --cache-from $(IMAGE_NAME) \ + -t $(IMAGE_NAME) \ + . + +docker: docker-prod docker-build + +.PHONY: docker docker-prod docker-build diff --git a/README.md b/README.md index 54d428c93..b31e7990d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # OmiseGO eWallet -[![Build Status](https://jenkins.omisego.io/buildStatus/icon?job=omisego/ewallet/master)](https://jenkins.omisego.io/blue/organizations/jenkins/omisego%2Fewallet/activity?branch=master) [![Gitter chat](https://badges.gitter.im/omisego/ewallet.png)](https://gitter.im/omisego/ewallet) +[![CircleCI](https://circleci.com/gh/omisego/ewallet.svg?style=svg)](https://circleci.com/gh/omisego/ewallet) [![Gitter chat](https://badges.gitter.im/omisego/ewallet.png)](https://gitter.im/omisego/ewallet) This is the server application of the OmiseGO eWallet Suite that allows businesses and individuals (referred hereafter as the "provider") to setup and run their own digital wallet services through their own local ledger. @@ -22,10 +22,10 @@ Here is an overview of all the eWallet components and what needs to be integrate Pick one of the following setup approaches that best suits your needs: -Setup | Description | Recommended for ------------|-------------|---------------- -[Bare‑metal](docs/setup/bare_metal.md) | Set up directly onto your base operating system. You will need to install Elixir, project's dependencies and Postgres manually if you havn't. | Developers and DevOps preferring to manage all dependencies and configurations themselves for any purposes. -[Docker](docs/setup/docker.md) | A pre-packaged image for production uses. No build-time dependencies. Packaged with Distillery. | Developers and DevOps looking to integrate or deploy the eWallet without changing its internals. +| Setup | Description | Recommended for | +| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| [Bare‑metal](docs/setup/bare_metal.md) | Set up directly onto your base operating system. You will need to install Elixir, project's dependencies and Postgres manually if you havn't. | Developers and DevOps preferring to manage all dependencies and configurations themselves for any purposes. | +| [Docker](docs/setup/docker.md) | A pre-packaged image for production uses. No build-time dependencies. Packaged with Distillery. | Developers and DevOps looking to integrate or deploy the eWallet without changing its internals. | Having trouble setting up the eWallet? Check the [Setup Troubleshooting Guide](docs/setup/troubleshooting.md). @@ -33,25 +33,25 @@ Having trouble setting up the eWallet? Check the [Setup Troubleshooting Guide](d Below are the links to the HTTP-RPC API documentations for the `master` branch. Note that the eWallet is not a centralized service and **the servers below are not for production uses.** -- Admin API ([**interactive**](https://ewallet.staging.omisego.io/api/admin/docs.ui) / [**yaml**](https://ewallet.staging.omisego.io/api/admin/docs.yaml) / [**json**](https://ewallet.staging.omisego.io/api/admin/docs.json)): Integrate with your server apps to perform higher-privilege operations, such as managing tokens, accounts, users, transactions, global settings, etc. -- Client API ([**interactive**](https://ewallet.staging.omisego.io/api/client/docs.ui) / [**yaml**](https://ewallet.staging.omisego.io/api/client/docs.yaml) / [**json**](https://ewallet.staging.omisego.io/api/client/docs.json)): Integrate with your client apps to transact on behalf of a specific user, such as creating a transaction request for a specific user, updating a user's settings, etc. +- Admin API ([**interactive**](https://ewallet.staging.omisego.io/api/admin/docs.ui) / [**yaml**](https://ewallet.staging.omisego.io/api/admin/docs.yaml) / [**json**](https://ewallet.staging.omisego.io/api/admin/docs.json)): Integrate with your server apps to perform higher-privilege operations, such as managing tokens, accounts, users, transactions, global settings, etc. +- Client API ([**interactive**](https://ewallet.staging.omisego.io/api/client/docs.ui) / [**yaml**](https://ewallet.staging.omisego.io/api/client/docs.yaml) / [**json**](https://ewallet.staging.omisego.io/api/client/docs.json)): Integrate with your client apps to transact on behalf of a specific user, such as creating a transaction request for a specific user, updating a user's settings, etc. We also provide the [**Ruby SDK**](https://github.com/omisego/ruby-sdk) ([sample server](https://github.com/omisego/sample-server)), [**iOS SDK**](https://github.com/omisego/ios-sdk) ([sample app](https://github.com/omisego/sample-ios)) and [**Android SDK**](https://github.com/omisego/android-sdk) ([sample app](https://github.com/omisego/sample-android)) so you do not have to deal with the HTTP-RPC layer yourself. Optionally, deeper dives into the eWallet are available: -- [Demo](docs/demo.md): Explore the sample shop server demos without setting up your own. -- [Guides](docs/guides/guides.md): Understand how the eWallet server works behind the scene. -- [Design](docs/design/design.md): Find out about the technical design decisions that revolve around the eWallet server. -- [Tests](docs/tests/tests.md): See how tests are organized for the eWallet server. -- [FAQ](docs/faq.md): Frequently asked questions. +- [Demo](docs/demo.md): Explore the sample shop server demos without setting up your own. +- [Guides](docs/guides/guides.md): Understand how the eWallet server works behind the scene. +- [Design](docs/design/design.md): Find out about the technical design decisions that revolve around the eWallet server. +- [Tests](docs/tests/tests.md): See how tests are organized for the eWallet server. +- [FAQ](docs/faq.md): Frequently asked questions. You can also follow our advanced setup guides to customize your eWallet server: -- [Environment variables](docs/setup/advanced/env.md) -- [Settings](docs/setup/advanced/settings.md) -- [Clustering](docs/setup/advanced/clustering.md) -- [Upgrading](docs/setup/upgrading/) +- [Environment variables](docs/setup/advanced/env.md) +- [Settings](docs/setup/advanced/settings.md) +- [Clustering](docs/setup/advanced/clustering.md) +- [Upgrading](docs/setup/upgrading/) ## Contributing @@ -61,16 +61,16 @@ Learn more from our [contributing guide](.github/CONTRIBUTING.md). ## Support -- [Issues](https://github.com/omisego/ewallet/issues): Browse or file a report for any bugs found -- [Gitter](https://gitter.im/omisego/ewallet): Discuss features and suggestions in real-time -- [StackOverflow](https://stackoverflow.com/questions/tagged/omisego): Search or create a new question with the tag `omisego` -- Need enterprise support or hosting solutions? [Get in touch with us](mailto:thibault@omisego.co) for more details +- [Issues](https://github.com/omisego/ewallet/issues): Browse or file a report for any bugs found +- [Gitter](https://gitter.im/omisego/ewallet): Discuss features and suggestions in real-time +- [StackOverflow](https://stackoverflow.com/questions/tagged/omisego): Search or create a new question with the tag `omisego` +- Need enterprise support or hosting solutions? [Get in touch with us](mailto:thibault@omisego.co) for more details ## Community efforts We are thankful to our community for creating and maintaining these wonderful work that we otherwise could not have done ourselves. If you have ported any part of the OmiseGO eWallet to another platform, we will be very happy to list them here. [Submit us a pull request](https://github.com/omisego/ewallet/pulls). -- [Alainy/OmiseGo-Go-SDK](https://github.com/Alainy/OmiseGo-Go-SDK) (Golang) +- [Alainy/OmiseGo-Go-SDK](https://github.com/Alainy/OmiseGo-Go-SDK) (Golang) Please note that these community tools and libraries are **not maintained by the OmiseGO team.** diff --git a/apps/activity_logger/lib/activity_logger/application.ex b/apps/activity_logger/lib/activity_logger/application.ex index a88c20591..e63b30848 100644 --- a/apps/activity_logger/lib/activity_logger/application.ex +++ b/apps/activity_logger/lib/activity_logger/application.ex @@ -24,7 +24,8 @@ defmodule ActivityLogger.Application do DeferredConfig.populate(:activity_logger) children = [ - supervisor(ActivityLogger.Repo, []) + supervisor(ActivityLogger.Repo, []), + supervisor(ActivityLogger.Vault, []) ] opts = [strategy: :one_for_one, name: ActivityLogger.Supervisor] diff --git a/apps/activity_logger/lib/activity_logger/vault.ex b/apps/activity_logger/lib/activity_logger/vault.ex index 9a2ca327c..2379e19e4 100644 --- a/apps/activity_logger/lib/activity_logger/vault.ex +++ b/apps/activity_logger/lib/activity_logger/vault.ex @@ -17,30 +17,37 @@ defmodule ActivityLogger.Vault do use Cloak.Vault, otp_app: :activity_logger - @impl Cloak.Vault + @impl GenServer def init(config) do - env = Mix.env() + env = Application.get_env(:ewallet, :env) config = Keyword.put( config, :ciphers, - default: {Cloak.Ciphers.AES.GCM, tag: "AES.GCM.V1", key: secret_key(env)} + default: { + Cloak.Ciphers.AES.GCM, + tag: "AES.GCM.V1", key: secret_key(env) + } ) {:ok, config} end - defp secret_key(:prod), do: decode_env("EWALLET_SECRET_KEY") - - defp secret_key(_), - do: - <<126, 194, 0, 33, 217, 227, 143, 82, 252, 80, 133, 89, 70, 211, 139, 150, 209, 103, 94, - 240, 194, 108, 166, 100, 48, 144, 207, 242, 93, 244, 27, 144>> + defp secret_key(t) when is_binary(t) do + t + |> String.to_atom() + |> secret_key() + end - defp decode_env(var) do - var + defp secret_key(:prod) do + "EWALLET_SECRET_KEY" |> System.get_env() |> Base.decode64!() end + + defp secret_key(_) do + <<126, 194, 0, 33, 217, 227, 143, 82, 252, 80, 133, 89, 70, 211, 139, 150, 209, 103, 94, 240, + 194, 108, 166, 100, 48, 144, 207, 242, 93, 244, 27, 144>> + end end diff --git a/apps/activity_logger/mix.exs b/apps/activity_logger/mix.exs index 88e4d1639..af4444172 100644 --- a/apps/activity_logger/mix.exs +++ b/apps/activity_logger/mix.exs @@ -4,7 +4,7 @@ defmodule ActivityLogger.MixProject do def project do [ app: :activity_logger, - version: "1.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", @@ -39,13 +39,13 @@ defmodule ActivityLogger.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:postgrex, ">= 0.0.0"}, - {:poison, "~> 3.1"}, - {:ecto, "~> 2.1.6"}, + {:cloak, "~> 0.9.1"}, {:deferred_config, "~> 0.1.0"}, + {:ecto, "~> 2.1.6"}, {:ex_machina, "~> 2.2", only: :test}, - {:cloak, "~> 0.7.0-alpha"}, - {:utils, in_umbrella: true} + {:poison, "~> 3.1"}, + {:postgrex, ">= 0.0.0"}, + {:utils, in_umbrella: true}, ] end diff --git a/apps/activity_logger/priv/repo/migrations/20181129054318_add_test_document_table.exs b/apps/activity_logger/priv/repo/migrations/20181129054318_add_test_document_table.exs index cf3dc02e7..ddefffcc4 100644 --- a/apps/activity_logger/priv/repo/migrations/20181129054318_add_test_document_table.exs +++ b/apps/activity_logger/priv/repo/migrations/20181129054318_add_test_document_table.exs @@ -16,7 +16,7 @@ defmodule ActivityLogger.Repo.Migrations.AddTestDocumentTable do use Ecto.Migration def change do - if Mix.env == :test do + if Application.get_env(:ewallet, :env) == :test do create table(:test_document, primary_key: false) do add :uuid, :uuid, primary_key: true add :id, :string, null: false diff --git a/apps/activity_logger/priv/repo/migrations/20181129055336_add_test_users.exs b/apps/activity_logger/priv/repo/migrations/20181129055336_add_test_users.exs index 840812339..01d6c430a 100644 --- a/apps/activity_logger/priv/repo/migrations/20181129055336_add_test_users.exs +++ b/apps/activity_logger/priv/repo/migrations/20181129055336_add_test_users.exs @@ -16,7 +16,7 @@ defmodule ActivityLogger.Repo.Migrations.AddTestUsers do use Ecto.Migration def change do - if Mix.env == :test do + if Application.get_env(:ewallet, :env) == :test do create table(:test_user, primary_key: false) do add :uuid, :uuid, primary_key: true add :id, :string, null: false diff --git a/apps/admin_api/mix.exs b/apps/admin_api/mix.exs index 52bda737a..0e07bd2a3 100644 --- a/apps/admin_api/mix.exs +++ b/apps/admin_api/mix.exs @@ -4,7 +4,7 @@ defmodule AdminAPI.Mixfile do def project do [ app: :admin_api, - version: "1.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", @@ -44,18 +44,18 @@ defmodule AdminAPI.Mixfile do # Type `mix help deps` for examples and options. defp deps do [ - {:phoenix, "~> 1.3.0"}, - {:plug_cowboy, "~> 1.0"}, - {:cors_plug, "~> 1.5"}, - {:sentry, "~> 6.4"}, - {:bodyguard, "~> 2.2"}, - {:deferred_config, "~> 0.1.0"}, - {:csv, "~> 2.0.0"}, {:appsignal, "~> 1.0"}, + {:bodyguard, "~> 2.2"}, {:bypass, "~> 1.0.0", only: [:test]}, + {:cors_plug, "~> 1.5"}, + {:csv, "~> 2.0.0"}, + {:deferred_config, "~> 0.1.0"}, + {:ewallet, in_umbrella: true}, {:ewallet_config, in_umbrella: true}, {:ewallet_db, in_umbrella: true}, - {:ewallet, in_umbrella: true} + {:phoenix, "~> 1.3.0"}, + {:plug_cowboy, "~> 1.0"}, + {:sentry, "~> 6.4"} ] end diff --git a/apps/admin_api/test/admin_api/global/controllers/status_controller_test.exs b/apps/admin_api/test/admin_api/global/controllers/status_controller_test.exs index f8dde8f44..84c9863a9 100644 --- a/apps/admin_api/test/admin_api/global/controllers/status_controller_test.exs +++ b/apps/admin_api/test/admin_api/global/controllers/status_controller_test.exs @@ -17,6 +17,8 @@ defmodule AdminAPI.StatusControllerTest do describe "GET request to /" do test "returns status ok" do + Application.put_env(:ewallet, :version, "0.9.9") + response = build_conn() |> get(@base_dir <> "/") @@ -24,7 +26,7 @@ defmodule AdminAPI.StatusControllerTest do assert response == %{ "success" => true, - "ewallet_version" => "1.1.0", + "ewallet_version" => "0.9.9", "api_versions" => [ %{"name" => "v1", "media_type" => "application/vnd.omisego.v1+json"} ] diff --git a/apps/admin_panel/config/prod.exs b/apps/admin_panel/config/prod.exs index d2d855e6d..7585e97d3 100644 --- a/apps/admin_panel/config/prod.exs +++ b/apps/admin_panel/config/prod.exs @@ -1 +1,3 @@ use Mix.Config + +config :admin_panel, AdminPanel.Endpoint, cache_static_manifest: "priv/static/cache_manifest.json" diff --git a/apps/admin_panel/mix.exs b/apps/admin_panel/mix.exs index 8f5d35ad0..65fd13d33 100644 --- a/apps/admin_panel/mix.exs +++ b/apps/admin_panel/mix.exs @@ -4,7 +4,7 @@ defmodule AdminPanel.Mixfile do def project do [ app: :admin_panel, - version: "1.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", @@ -43,9 +43,10 @@ defmodule AdminPanel.Mixfile do # Type `mix help deps` for examples and options. defp deps do [ + {:ewallet_config, in_umbrella: true}, + {:ewallet_db, in_umbrella: true}, {:phoenix, "~> 1.3.0"}, - {:cowboy, "~> 1.0"}, - {:ewallet_db, in_umbrella: true} + {:plug_cowboy, "~> 1.0"} ] end end diff --git a/apps/ewallet/config/config.exs b/apps/ewallet/config/config.exs index 403959068..0527620f1 100644 --- a/apps/ewallet/config/config.exs +++ b/apps/ewallet/config/config.exs @@ -4,6 +4,7 @@ use Mix.Config config :ewallet, ecto_repos: [], + version: "1.1.0-pre.0", settings: [ :base_url, :sender_email, diff --git a/apps/ewallet/lib/ewallet/release_tasks.ex b/apps/ewallet/lib/ewallet/release_tasks.ex new file mode 100644 index 000000000..2c710b092 --- /dev/null +++ b/apps/ewallet/lib/ewallet/release_tasks.ex @@ -0,0 +1,137 @@ +defmodule EWallet.ReleaseTasks do + @moduledoc """ + Provides a task for use within release. + """ + alias Ecto.Migrator + alias EWallet.Seeder.CLI + alias EWalletConfig.Config + alias ActivityLogger.System + + # + # Utils + # + + defp ensure_app_started({app_name, _}), do: ensure_app_started(app_name) + + defp ensure_app_started(app_name) do + case Application.ensure_all_started(app_name) do + {:ok, _} -> + repos = Application.get_env(app_name, :ecto_repos, []) + Enum.each(repos, & &1.start_link(pool_size: 1)) + + _ -> + nil + end + end + + # + # Seed + # + + @seed_start_apps [:crypto, :ssl, :postgrex, :ecto, :cloak, :ewallet] + @seed_std_spec [{:ewallet_config, :seeds_settings}, {:ewallet_db, :seeds}] + @seed_e2e_spec [{:ewallet_config, :seeds_settings}, {:ewallet_db, :seeds_test}] + + def seed, do: seed_with(@seed_std_spec) + def seed_e2e, do: seed_with(@seed_e2e_spec) + + defp seed_with(spec) do + Enum.each(@seed_start_apps, &Application.ensure_all_started/1) + Enum.each(spec, &ensure_app_started/1) + _ = CLI.run(spec, true) + :init.stop() + end + + # + # Initdb + # + + @initdb_start_apps [:crypto, :ssl, :postgrex, :ecto] + @initdb_apps [:ewallet_config, :activity_logger, :ewallet_db, :local_ledger_db] + + def initdb do + Enum.each(@initdb_start_apps, &Application.ensure_all_started/1) + Enum.each(@initdb_apps, &initdb/1) + :init.stop() + end + + defp initdb(app_name) do + :ok = Application.load(app_name) + repos = Application.get_env(app_name, :ecto_repos, []) + + Enum.each(repos, &run_create_for/1) + Enum.each(repos, & &1.start_link(pool_size: 1)) + Enum.each(repos, &run_migrations_for/1) + end + + defp run_create_for(repo) do + case repo.__adapter__.storage_up(repo.config) do + :ok -> + IO.puts("The database for #{inspect(repo)} has been created") + + {:error, :already_up} -> + IO.puts("The database for #{inspect(repo)} has already been created") + + {:error, term} when is_binary(term) -> + IO.puts("The database for #{inspect(repo)} couldn't be created: #{term}") + + {:error, term} -> + IO.puts("The database for #{inspect(repo)} couldn't be created: #{inspect(term)}") + end + end + + defp run_migrations_for(repo) do + migrations_path = priv_path_for(repo, "migrations") + IO.puts("Running migration for #{inspect(repo)}...") + Migrator.run(repo, migrations_path, :up, all: true) + end + + defp priv_dir(app), do: "#{:code.priv_dir(app)}" + + defp priv_path_for(repo, filename) do + app = Keyword.get(repo.config, :otp_app) + repo_underscore = repo |> Module.split() |> List.last() |> Macro.underscore() + Path.join([priv_dir(app), repo_underscore, filename]) + end + + # + # Config + # + + @config_start_apps [:crypto, :ssl, :postgrex, :ecto, :cloak, :ewallet] + @config_apps [:activity_logger, :ewallet_config] + + def config do + case :init.get_plain_arguments() do + [key, value] -> + Enum.each(@config_start_apps, &Application.ensure_all_started/1) + Enum.each(@config_apps, &ensure_app_started/1) + config_update(key, value) + + _ -> + IO.puts("Usage: bin/ewallet config KEY VALUE") + :init.stop(1) + end + end + + def config_update(key, value) when not is_binary(key), do: config_update(to_string(key), value) + + def config_update(key, value) when not is_binary(value), + do: config_update(key, to_string(value)) + + def config_update(key, value) do + case Config.update(%{key => value, originator: %System{}}) do + {:ok, [{key, {:ok, _}}]} -> + IO.puts("Successfully updated #{key} to #{value}") + :init.stop() + + {:ok, [{key, {:error, :setting_not_found}}]} -> + IO.puts("Error: #{key} is not a valid settings") + :init.stop(1) + + _ -> + IO.puts("Error: unknown error") + :init.stop(1) + end + end +end diff --git a/apps/ewallet/lib/mix/tasks/omg.seed.ex b/apps/ewallet/lib/mix/tasks/omg.seed.ex index 5bf016186..2c69d5a8c 100644 --- a/apps/ewallet/lib/mix/tasks/omg.seed.ex +++ b/apps/ewallet/lib/mix/tasks/omg.seed.ex @@ -67,7 +67,7 @@ defmodule Mix.Tasks.Omg.Seed do end defp seed_spec(["--settings" | _t]) do - [{:ewallet_db, :seeds_settings}] + [{:ewallet_config, :seeds_settings}] end defp seed_spec(["--sample" | t]) do diff --git a/apps/ewallet/mix.exs b/apps/ewallet/mix.exs index 84707b4f5..caab6da82 100644 --- a/apps/ewallet/mix.exs +++ b/apps/ewallet/mix.exs @@ -4,7 +4,7 @@ defmodule EWallet.Mixfile do def project do [ app: :ewallet, - version: "1.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", @@ -39,21 +39,21 @@ defmodule EWallet.Mixfile do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:phoenix, "~> 1.3.0"}, - {:phoenix_html, "~> 2.11.0"}, - {:quantum, "~> 2.2.6"}, - {:timex, "~> 3.0"}, - {:bodyguard, "~> 2.2"}, {:bamboo, "~> 0.8"}, {:bamboo_smtp, "~> 1.4.0"}, + {:bodyguard, "~> 2.2"}, + {:bypass, "~> 1.0.0", only: [:test]}, {:decimal, "~> 1.0"}, {:deferred_config, "~> 0.1.0"}, - {:sentry, "~> 6.4"}, - {:bypass, "~> 1.0.0", only: [:test]}, - {:ewallet_db, in_umbrella: true}, {:ewallet_config, in_umbrella: true}, + {:ewallet_db, in_umbrella: true}, {:local_ledger, in_umbrella: true}, - {:local_ledger_db, in_umbrella: true} + {:local_ledger_db, in_umbrella: true}, + {:phoenix, "~> 1.3.0"}, + {:phoenix_html, "~> 2.11.0"}, + {:quantum, "~> 2.2.6"}, + {:sentry, "~> 6.4"}, + {:timex, "~> 3.0"}, ] end end diff --git a/apps/ewallet_api/mix.exs b/apps/ewallet_api/mix.exs index 0a8bf7ee1..70c6ddb56 100644 --- a/apps/ewallet_api/mix.exs +++ b/apps/ewallet_api/mix.exs @@ -4,7 +4,7 @@ defmodule EWalletAPI.Mixfile do def project do [ app: :ewallet_api, - version: "1.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", @@ -49,15 +49,16 @@ defmodule EWalletAPI.Mixfile do # Type `mix help deps` for examples and options. defp deps do [ - {:phoenix, "~> 1.3.0"}, - {:plug_cowboy, "~> 1.0"}, + {:bypass, "~> 1.0.0", only: [:test]}, {:cors_plug, "~> 1.5"}, - {:sentry, "~> 6.4"}, - {:peerage, "~> 1.0.2"}, {:deferred_config, "~> 0.1.0"}, - {:bypass, "~> 1.0.0", only: [:test]}, + {:ewallet, in_umbrella: true}, + {:ewallet_config, in_umbrella: true}, {:ewallet_db, in_umbrella: true}, - {:ewallet, in_umbrella: true} + {:peerage, "~> 1.0.2"}, + {:phoenix, "~> 1.3.0"}, + {:plug_cowboy, "~> 1.0"}, + {:sentry, "~> 6.4"}, ] end diff --git a/apps/ewallet_api/test/ewallet_api/global/controllers/status_controller_test.exs b/apps/ewallet_api/test/ewallet_api/global/controllers/status_controller_test.exs index 4b3a9a22f..399072900 100644 --- a/apps/ewallet_api/test/ewallet_api/global/controllers/status_controller_test.exs +++ b/apps/ewallet_api/test/ewallet_api/global/controllers/status_controller_test.exs @@ -17,6 +17,8 @@ defmodule EWalletAPI.StatusControllerTest do describe "GET request to root url" do test "returns status ok" do + Application.put_env(:ewallet, :version, "0.9.9") + response = build_conn() |> get(@base_dir <> "/") @@ -29,7 +31,7 @@ defmodule EWalletAPI.StatusControllerTest do "ewallet" => true, "local_ledger" => true }, - "ewallet_version" => "1.1.0", + "ewallet_version" => "0.9.9", "api_versions" => [ %{"name" => "v1", "media_type" => "application/vnd.omisego.v1+json"} ] diff --git a/apps/ewallet_config/lib/ewallet_config/application.ex b/apps/ewallet_config/lib/ewallet_config/application.ex index 82bb3e747..ae69775c7 100644 --- a/apps/ewallet_config/lib/ewallet_config/application.ex +++ b/apps/ewallet_config/lib/ewallet_config/application.ex @@ -29,9 +29,9 @@ defmodule EWalletConfig.Application do # List all child processes to be supervised children = [ - # Starts a worker by calling: EWalletConfig.Worker.start_link(arg) supervisor(EWalletConfig.Repo, []), - supervisor(EWalletConfig.Config, [[named: true]]) + supervisor(EWalletConfig.Config, [[named: true]]), + supervisor(EWalletConfig.Vault, []) ] # See https://hexdocs.pm/elixir/Supervisor.html diff --git a/apps/ewallet_config/lib/ewallet_config/config.ex b/apps/ewallet_config/lib/ewallet_config/config.ex index 886dae088..294b26892 100644 --- a/apps/ewallet_config/lib/ewallet_config/config.ex +++ b/apps/ewallet_config/lib/ewallet_config/config.ex @@ -122,7 +122,7 @@ defmodule EWalletConfig.Config do def update(attrs, pid \\ __MODULE__) do {config_pid, attrs} = get_config_pid(attrs) - case Mix.env() == :test do + case Application.get_env(:ewallet, :env) == :test do true -> GenServer.call(config_pid || pid, {:update_and_reload, attrs}) diff --git a/apps/ewallet_config/lib/ewallet_config/loaders/file_storage_settings_loader.ex b/apps/ewallet_config/lib/ewallet_config/loaders/file_storage_settings_loader.ex index c5868f000..e8117a924 100644 --- a/apps/ewallet_config/lib/ewallet_config/loaders/file_storage_settings_loader.ex +++ b/apps/ewallet_config/lib/ewallet_config/loaders/file_storage_settings_loader.ex @@ -25,7 +25,7 @@ defmodule EWalletConfig.FileStorageSettingsLoader do end defp load_file_storage(nil, _app) do - if Mix.env() != :test do + if Application.get_env(:ewallet, :env) != :test do Logger.warn(~s([File Storage Configuration]: Setting hasn't been generated.)) end end diff --git a/apps/ewallet_config/lib/ewallet_config/setting.ex b/apps/ewallet_config/lib/ewallet_config/setting.ex index 08a89c3a3..51b61cc59 100644 --- a/apps/ewallet_config/lib/ewallet_config/setting.ex +++ b/apps/ewallet_config/lib/ewallet_config/setting.ex @@ -179,7 +179,7 @@ defmodule EWalletConfig.Setting do {:ok, %Setting{}} | {:error, atom()} | {:error, Changeset.t()} def update(nil, _), do: {:error, :setting_not_found} - def update(key, attrs) when is_atom(key) and is_map(attrs) do + def update(key, attrs) when is_atom(key) do key |> Atom.to_string() |> update(attrs) diff --git a/apps/ewallet_config/lib/ewallet_config/setting_loader.ex b/apps/ewallet_config/lib/ewallet_config/setting_loader.ex index 9a27576dd..65506012d 100644 --- a/apps/ewallet_config/lib/ewallet_config/setting_loader.ex +++ b/apps/ewallet_config/lib/ewallet_config/setting_loader.ex @@ -55,7 +55,7 @@ defmodule EWalletConfig.SettingLoader do defp fetch_value(app, key) do case Setting.get(key) do nil -> - if Mix.env() != :test, do: warn(app, key) + if Application.get_env(:ewallet, :env) != :test, do: warn(app, key) nil setting -> diff --git a/apps/ewallet_config/lib/ewallet_config/vault.ex b/apps/ewallet_config/lib/ewallet_config/vault.ex index bcca3af93..d833a8afc 100644 --- a/apps/ewallet_config/lib/ewallet_config/vault.ex +++ b/apps/ewallet_config/lib/ewallet_config/vault.ex @@ -17,30 +17,37 @@ defmodule EWalletConfig.Vault do use Cloak.Vault, otp_app: :ewallet_config - @impl Cloak.Vault + @impl GenServer def init(config) do - env = Mix.env() + env = Application.get_env(:ewallet, :env) config = Keyword.put( config, :ciphers, - default: {Cloak.Ciphers.AES.GCM, tag: "AES.GCM.V1", key: secret_key(env)} + default: { + Cloak.Ciphers.AES.GCM, + tag: "AES.GCM.V1", key: secret_key(env) + } ) {:ok, config} end - defp secret_key(:prod), do: decode_env("EWALLET_SECRET_KEY") - - defp secret_key(_), - do: - <<126, 194, 0, 33, 217, 227, 143, 82, 252, 80, 133, 89, 70, 211, 139, 150, 209, 103, 94, - 240, 194, 108, 166, 100, 48, 144, 207, 242, 93, 244, 27, 144>> + defp secret_key(t) when is_binary(t) do + t + |> String.to_atom() + |> secret_key() + end - defp decode_env(var) do - var + defp secret_key(:prod) do + "EWALLET_SECRET_KEY" |> System.get_env() |> Base.decode64!() end + + defp secret_key(_) do + <<126, 194, 0, 33, 217, 227, 143, 82, 252, 80, 133, 89, 70, 211, 139, 150, 209, 103, 94, 240, + 194, 108, 166, 100, 48, 144, 207, 242, 93, 244, 27, 144>> + end end diff --git a/apps/ewallet_config/mix.exs b/apps/ewallet_config/mix.exs index 56644f561..9511745e7 100644 --- a/apps/ewallet_config/mix.exs +++ b/apps/ewallet_config/mix.exs @@ -4,7 +4,7 @@ defmodule EWalletConfig.MixProject do def project do [ app: :ewallet_config, - version: "1.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", @@ -39,17 +39,17 @@ defmodule EWalletConfig.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:postgrex, ">= 0.0.0"}, - {:ecto, "~> 2.1.6"}, - {:poison, "~> 3.1"}, - {:deferred_config, "~> 0.1.0"}, - {:cloak, "~> 0.7.0-alpha"}, + {:activity_logger, in_umbrella: true}, {:arc, "~> 0.11.0"}, {:arc_ecto, github: "omisego/arc_ecto"}, {:bcrypt_elixir, "~> 1.0"}, + {:cloak, "~> 0.9.1"}, + {:deferred_config, "~> 0.1.0"}, + {:ecto, "~> 2.1.6"}, {:plug, "~> 1.0"}, + {:poison, "~> 3.1"}, + {:postgrex, ">= 0.0.0"}, {:utils, in_umbrella: true}, - {:activity_logger, in_umbrella: true} ] end diff --git a/apps/ewallet_db/priv/repo/reporters/seeds_settings.exs b/apps/ewallet_config/priv/repo/reporters/seeds_settings.exs similarity index 100% rename from apps/ewallet_db/priv/repo/reporters/seeds_settings.exs rename to apps/ewallet_config/priv/repo/reporters/seeds_settings.exs diff --git a/apps/ewallet_db/priv/repo/seeds_settings/00_setting.exs b/apps/ewallet_config/priv/repo/seeds_settings/00_setting.exs similarity index 100% rename from apps/ewallet_db/priv/repo/seeds_settings/00_setting.exs rename to apps/ewallet_config/priv/repo/seeds_settings/00_setting.exs diff --git a/apps/ewallet_config/test/support/config_test_helper.ex b/apps/ewallet_config/test/support/config_test_helper.ex index 85021e885..5aec125d4 100644 --- a/apps/ewallet_config/test/support/config_test_helper.ex +++ b/apps/ewallet_config/test/support/config_test_helper.ex @@ -81,7 +81,7 @@ defmodule EWalletConfig.ConfigTestHelper do defp ensure_applications_started(node) do rpc(node, Application, :ensure_all_started, [:mix]) - rpc(node, Mix, :env, [Mix.env()]) + rpc(node, Mix, :env, [Application.get_env(:ewallet, :env)]) for {app_name, _, _} <- Application.loaded_applications() do rpc(node, Application, :ensure_all_started, [app_name]) diff --git a/apps/ewallet_db/lib/ewallet_db/application.ex b/apps/ewallet_db/lib/ewallet_db/application.ex index 8346d6122..efd60deee 100644 --- a/apps/ewallet_db/lib/ewallet_db/application.ex +++ b/apps/ewallet_db/lib/ewallet_db/application.ex @@ -55,7 +55,8 @@ defmodule EWalletDB.Application do # List all child processes to be supervised children = [ - supervisor(EWalletDB.Repo, []) + supervisor(EWalletDB.Repo, []), + supervisor(EWalletDB.Vault, []) ] children = diff --git a/apps/ewallet_db/lib/ewallet_db/uploaders/avatar.ex b/apps/ewallet_db/lib/ewallet_db/uploaders/avatar.ex index 5cc867a14..beec6f857 100644 --- a/apps/ewallet_db/lib/ewallet_db/uploaders/avatar.ex +++ b/apps/ewallet_db/lib/ewallet_db/uploaders/avatar.ex @@ -44,7 +44,9 @@ defmodule EWalletDB.Uploaders.Avatar do # Override the storage directory: def storage_dir(_version, {_file, scope}) do - "public/uploads/#{Mix.env()}/#{get_schema_name(scope)}/avatars/#{scope.id}" + "public/uploads/#{Application.get_env(:ewallet, :env)}/#{get_schema_name(scope)}/avatars/#{ + scope.id + }" end defp get_schema_name(scope) do diff --git a/apps/ewallet_db/lib/ewallet_db/vault.ex b/apps/ewallet_db/lib/ewallet_db/vault.ex index 0c4048955..4931377ef 100644 --- a/apps/ewallet_db/lib/ewallet_db/vault.ex +++ b/apps/ewallet_db/lib/ewallet_db/vault.ex @@ -17,30 +17,37 @@ defmodule EWalletDB.Vault do use Cloak.Vault, otp_app: :ewallet_db - @impl Cloak.Vault + @impl GenServer def init(config) do - env = Mix.env() + env = Application.get_env(:ewallet, :env) config = Keyword.put( config, :ciphers, - default: {Cloak.Ciphers.AES.GCM, tag: "AES.GCM.V1", key: secret_key(env)} + default: { + Cloak.Ciphers.AES.GCM, + tag: "AES.GCM.V1", key: secret_key(env) + } ) {:ok, config} end - defp secret_key(:prod), do: decode_env("EWALLET_SECRET_KEY") - - defp secret_key(_), - do: - <<126, 194, 0, 33, 217, 227, 143, 82, 252, 80, 133, 89, 70, 211, 139, 150, 209, 103, 94, - 240, 194, 108, 166, 100, 48, 144, 207, 242, 93, 244, 27, 144>> + defp secret_key(t) when is_binary(t) do + t + |> String.to_atom() + |> secret_key() + end - defp decode_env(var) do - var + defp secret_key(:prod) do + "EWALLET_SECRET_KEY" |> System.get_env() |> Base.decode64!() end + + defp secret_key(_) do + <<126, 194, 0, 33, 217, 227, 143, 82, 252, 80, 133, 89, 70, 211, 139, 150, 209, 103, 94, 240, + 194, 108, 166, 100, 48, 144, 207, 242, 93, 244, 27, 144>> + end end diff --git a/apps/ewallet_db/mix.exs b/apps/ewallet_db/mix.exs index 8fe6bcbcd..1b2797e8e 100644 --- a/apps/ewallet_db/mix.exs +++ b/apps/ewallet_db/mix.exs @@ -4,7 +4,7 @@ defmodule EWalletDB.Mixfile do def project do [ app: :ewallet_db, - version: "1.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", @@ -43,17 +43,19 @@ defmodule EWalletDB.Mixfile do # Type `mix help deps` for examples and options. defp deps do [ - {:postgrex, ">= 0.0.0"}, - {:ecto, "~> 2.1.6"}, - {:ex_machina, "~> 2.2", only: :test}, - {:timex, "~> 3.0"}, - {:poison, "~> 3.1"}, - {:bcrypt_elixir, "~> 1.0"}, - {:cloak, "~> 0.7.0-alpha"}, - {:plug, "~> 1.0"}, + {:activity_logger, in_umbrella: true}, {:arc, "~> 0.11.0"}, {:arc_ecto, github: "omisego/arc_ecto"}, + {:bcrypt_elixir, "~> 1.0"}, + {:cloak, "~> 0.9.1"}, {:deferred_config, "~> 0.1.0"}, + {:ecto, "~> 2.1.6"}, + {:ewallet_config, in_umbrella: true}, + {:ex_machina, "~> 2.2", only: :test}, + {:plug, "~> 1.0"}, + {:poison, "~> 3.1"}, + {:postgrex, ">= 0.0.0"}, + {:timex, "~> 3.0"}, # arc GCS dependencies {:arc_gcs, "~> 0.0.3", runtime: false}, @@ -63,9 +65,6 @@ defmodule EWalletDB.Mixfile do {:ex_aws_s3, "~> 2.0"}, {:hackney, "~> 1.6"}, {:sweet_xml, "~> 0.6"}, - - {:ewallet_config, in_umbrella: true}, - {:activity_logger, in_umbrella: true} ] end diff --git a/apps/load_tester/mix.exs b/apps/load_tester/mix.exs index ba68e4d78..9f71733cc 100644 --- a/apps/load_tester/mix.exs +++ b/apps/load_tester/mix.exs @@ -4,7 +4,7 @@ defmodule LoadTester.MixProject do def project do [ app: :load_tester, - version: "1.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", @@ -27,7 +27,7 @@ defmodule LoadTester.MixProject do defp deps do [ {:chaperon, "~> 0.2.3"}, - {:deferred_config, "~> 0.1.0"} + {:deferred_config, "~> 0.1.0"}, ] end end diff --git a/apps/local_ledger/mix.exs b/apps/local_ledger/mix.exs index 6d0268199..07e30ba98 100644 --- a/apps/local_ledger/mix.exs +++ b/apps/local_ledger/mix.exs @@ -4,7 +4,7 @@ defmodule LocalLedger.Mixfile do def project do [ app: :local_ledger, - version: "1.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", @@ -33,10 +33,10 @@ defmodule LocalLedger.Mixfile do defp deps do [ {:deferred_config, "~> 0.1.0"}, + {:ewallet_config, in_umbrella: true}, + {:local_ledger_db, in_umbrella: true}, {:quantum, ">= 2.2.6"}, {:timex, "~> 3.0"}, - {:local_ledger_db, in_umbrella: true}, - {:ewallet_config, in_umbrella: true} ] end end diff --git a/apps/local_ledger_db/config/config.exs b/apps/local_ledger_db/config/config.exs index 37893613f..121345ca7 100644 --- a/apps/local_ledger_db/config/config.exs +++ b/apps/local_ledger_db/config/config.exs @@ -2,7 +2,8 @@ # and its dependencies with the aid of the Mix.Config module. use Mix.Config -config :local_ledger_db, ecto_repos: [LocalLedgerDB.Repo] +config :local_ledger_db, + ecto_repos: [LocalLedgerDB.Repo] # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. diff --git a/apps/local_ledger_db/lib/local_ledger_db/application.ex b/apps/local_ledger_db/lib/local_ledger_db/application.ex index bbbc6860f..cac53560e 100644 --- a/apps/local_ledger_db/lib/local_ledger_db/application.ex +++ b/apps/local_ledger_db/lib/local_ledger_db/application.ex @@ -25,9 +25,8 @@ defmodule LocalLedgerDB.Application do # List all child processes to be supervised children = [ - supervisor(LocalLedgerDB.Repo, []) - # Starts a worker by calling: LocalLedgerDB.Worker.start_link(arg) - # {LocalLedgerDB.Worker, arg}, + supervisor(LocalLedgerDB.Repo, []), + supervisor(LocalLedgerDB.Vault, []) ] # See https://hexdocs.pm/elixir/Supervisor.html diff --git a/apps/local_ledger_db/lib/local_ledger_db/vault.ex b/apps/local_ledger_db/lib/local_ledger_db/vault.ex index 756b86c88..22d1660fb 100644 --- a/apps/local_ledger_db/lib/local_ledger_db/vault.ex +++ b/apps/local_ledger_db/lib/local_ledger_db/vault.ex @@ -17,30 +17,37 @@ defmodule LocalLedgerDB.Vault do use Cloak.Vault, otp_app: :local_ledger_db - @impl Cloak.Vault + @impl GenServer def init(config) do - env = Mix.env() + env = Application.get_env(:ewallet, :env) config = Keyword.put( config, :ciphers, - default: {Cloak.Ciphers.AES.GCM, tag: "AES.GCM.V1", key: secret_key(env)} + default: { + Cloak.Ciphers.AES.GCM, + tag: "AES.GCM.V1", key: secret_key(env) + } ) {:ok, config} end - defp secret_key(:prod), do: decode_env("LOCAL_LEDGER_SECRET_KEY") - - defp secret_key(_), - do: - <<81, 98, 218, 231, 73, 11, 210, 156, 118, 252, 177, 144, 224, 97, 197, 156, 196, 13, 183, - 9, 154, 170, 231, 61, 6, 26, 166, 46, 16, 246, 150, 61>> + defp secret_key(t) when is_binary(t) do + t + |> String.to_atom() + |> secret_key() + end - defp decode_env(var) do - var + defp secret_key(:prod) do + "LOCAL_LEDGER_SECRET_KEY" |> System.get_env() |> Base.decode64!() end + + defp secret_key(_) do + <<81, 98, 218, 231, 73, 11, 210, 156, 118, 252, 177, 144, 224, 97, 197, 156, 196, 13, 183, 9, + 154, 170, 231, 61, 6, 26, 166, 46, 16, 246, 150, 61>> + end end diff --git a/apps/local_ledger_db/mix.exs b/apps/local_ledger_db/mix.exs index a88989257..a5a35205f 100644 --- a/apps/local_ledger_db/mix.exs +++ b/apps/local_ledger_db/mix.exs @@ -4,7 +4,7 @@ defmodule LocalLedgerDB.Mixfile do def project do [ app: :local_ledger_db, - version: "1.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", @@ -34,12 +34,13 @@ defmodule LocalLedgerDB.Mixfile do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:postgrex, ">= 0.0.0"}, - {:ecto, "~> 2.1.6"}, - {:poison, "~> 3.1"}, - {:cloak, "~> 0.7.0-alpha"}, + {:cloak, "~> 0.9.1"}, {:deferred_config, "~> 0.1.0"}, + {:ecto, "~> 2.1.6"}, + {:ewallet_config, in_umbrella: true}, {:ex_machina, "~> 2.2", only: :test}, + {:poison, "~> 3.1"}, + {:postgrex, ">= 0.0.0"}, ] end diff --git a/apps/url_dispatcher/mix.exs b/apps/url_dispatcher/mix.exs index 71f203446..9e95ebedb 100644 --- a/apps/url_dispatcher/mix.exs +++ b/apps/url_dispatcher/mix.exs @@ -4,7 +4,7 @@ defmodule UrlDispatcher.Mixfile do def project do [ app: :url_dispatcher, - version: "1.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", @@ -33,15 +33,16 @@ defmodule UrlDispatcher.Mixfile do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:quantum, "~> 2.2.6"}, - {:timex, "~> 3.0"}, - {:plug, "~> 1.2"}, - {:cowboy, "~> 1.0"}, - {:deferred_config, "~> 0.1.0"}, - {:ewallet, in_umbrella: true}, {:admin_api, in_umbrella: true}, {:admin_panel, in_umbrella: true}, - {:ewallet_api, in_umbrella: true} + {:deferred_config, "~> 0.1.0"}, + {:ewallet, in_umbrella: true}, + {:ewallet_api, in_umbrella: true}, + {:ewallet_config, in_umbrella: true}, + {:plug, "~> 1.2"}, + {:plug_cowboy, "~> 1.0"}, + {:quantum, "~> 2.2.6"}, + {:timex, "~> 3.0"} ] end end diff --git a/apps/url_dispatcher/test/url_dispatcher/plug_test.exs b/apps/url_dispatcher/test/url_dispatcher/plug_test.exs index 1b65864fb..0c95074f2 100644 --- a/apps/url_dispatcher/test/url_dispatcher/plug_test.exs +++ b/apps/url_dispatcher/test/url_dispatcher/plug_test.exs @@ -25,12 +25,14 @@ defmodule UrlDispatcher.PlugTest do describe "call/2" do test "returns success status when requesting /" do + Application.put_env(:ewallet, :version, "0.9.9") + conn = request("/") refute conn.halted assert conn.status == 200 - assert conn.resp_body == ~s({"status":true,"ewallet_version":"1.1.0"}) + assert conn.resp_body == ~s({"status":true,"ewallet_version":"0.9.9"}) end test "returns a 200 response when requesting /api" do diff --git a/apps/utils/mix.exs b/apps/utils/mix.exs index cf79ae4b7..84ec70204 100644 --- a/apps/utils/mix.exs +++ b/apps/utils/mix.exs @@ -4,7 +4,7 @@ defmodule Utils.MixProject do def project do [ app: :utils, - version: "0.1.0", + version: "1.1.0-pre.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", diff --git a/config/config.exs b/config/config.exs index 6a9be76f7..4aab8faa3 100644 --- a/config/config.exs +++ b/config/config.exs @@ -9,7 +9,9 @@ use Mix.Config # back to each application for organization purposes. import_config "../apps/*/config/config.exs" -config :ewallet, root: File.cwd!(), version: "1.1.0" +config :ewallet, + root: {:apply, {File, :cwd!, []}}, + env: Mix.env() # Configures Elixir's Logger config :logger, :console, diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..eec21a886 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,43 @@ +--- +version: "3" + +services: + postgres: + image: postgres:9.6.9-alpine + restart: always + volumes: + - postgres-db:/var/lib/postgresql/data + networks: + - intnet + environment: + POSTGRESQL_PASSWORD: passw0rd + healthcheck: + test: ["CMD-SHELL", "pg_isready", "-U", "postgres"] + interval: 30s + retries: 3 + + mail: + image: mailhog/mailhog:v1.0.0 + restart: always + networks: + - intnet + + ewallet: + image: omisego/ewallet:dev + restart: always + networks: + - intnet + depends_on: + - postgres + - mail + environment: + DATABASE_URL: "postgresql://postgres:passw0rd@postgres:5432/ewallet" + LOCAL_LEDGER_DATABASE_URL: "postgresql://postgres:passw0rd@postgres:5432/local_ledger" + EWALLET_SECRET_KEY: "CHANGE_ME" + LOCAL_LEDGER_SECRET_KEY: "CHANGE_ME" + +networks: + intnet: + +volumes: + postgres-db: diff --git a/docker-gen.sh b/docker-gen.sh new file mode 100755 index 000000000..5c7a1de42 --- /dev/null +++ b/docker-gen.sh @@ -0,0 +1,122 @@ +#!/bin/sh + +OPTS=hdi:n:p:k:K:f: +ARGS=$(getopt $OPTS "$*" 2>/dev/null) + +print_usage() { + printf "Usage: %s [-%s]\\n" "$0" "$OPTS" + printf "\\n" + printf " -h Print this help.\\n" + printf " -d Generate a development override.\\n" + printf "\\n" + printf "Config:\\n" + printf "\\n" + printf " -i image Specify an alternative eWallet image name.\\n" + printf " -n network Specify an external network.\\n" + printf " -p passwd Specify a PostgreSQL password.\\n" + printf " -k key1 Specify an eWallet secret key.\\n" + printf " -K key2 Specify a local ledger secret key.\\n" + printf " -f env Specify an env file.\\n" + printf "\\n" +} + +# shellcheck disable=SC2181 +if [ $? != 0 ]; then + print_usage + exit 1 +fi + +# shellcheck disable=SC2086 +set -- $ARGS + +IMAGE_NAME="" +POSTGRES_PASSWORD="" +EXTERNAL_NETWORK="" +EWALLET_SECRET_KEY="" +LOCAL_LEDGER_SECRET_KEY="" +DEV_MODE=0 + +while true; do + case "$1" in + -i ) IMAGE_NAME=$2; shift; shift;; + -n ) EXTERNAL_NETWORK=$2; shift; shift;; + -p ) POSTGRES_PASSWORD=$2; shift; shift;; + -k ) EWALLET_SECRET_KEY=$2; shift; shift;; + -K ) LOCAL_LEDGER_SECRET_KEY=$2; shift; shift;; + -f ) ENV_FILE=$2; shift; shift;; + -d ) DEV_MODE=1; shift;; + -h ) print_usage; exit 2;; + * ) break;; + esac +done + +[ -z "$EWALLET_SECRET_KEY" ] && EWALLET_SECRET_KEY=$(openssl rand -base64 32) +[ -z "$LOCAL_LEDGER_SECRET_KEY" ] && LOCAL_LEDGER_SECRET_KEY=$(openssl rand -base64 32) +[ -z "$POSTGRES_PASSWORD" ] && POSTGRES_PASSWORD=$(openssl rand -base64 24 | tr '+/' '-_') + +if [ -z "$IMAGE_NAME" ]; then + if [ $DEV_MODE = 1 ]; then + IMAGE_NAME="omisegoimages/ewallet-builder:stable" + else + IMAGE_NAME="omisego/ewallet:dev" + fi +fi + +YML_SERVICES=" + postgres: + environment: + POSTGRESQL_PASSWORD: $POSTGRES_PASSWORD\ +" # EOF + +YML_SERVICES=" + ewallet: + image: $IMAGE_NAME + environment: + DATABASE_URL: postgresql://postgres:$POSTGRES_PASSWORD@postgres:5432/ewallet + LOCAL_LEDGER_DATABASE_URL: postgresql://postgres:$POSTGRES_PASSWORD@postgres:5432/local_ledger + EWALLET_SECRET_KEY: $EWALLET_SECRET_KEY + LOCAL_LEDGER_SECRET_KEY: $LOCAL_LEDGER_SECRET_KEY\ +" # EOF + +if [ -n "$ENV_FILE" ]; then + YML_SERVICES="$YML_SERVICES + env_file: + - .env\ +" # EOF +fi + +if [ $DEV_MODE = 1 ]; then + YML_SERVICES="$YML_SERVICES + user: root + volumes: + - .:/app + - ewallet-deps:/app/deps + - ewallet-builds:/app/_build + - ewallet-node:/app/apps/admin_panel/assets/node_modules + working_dir: /app + command: + - mix + - omg.server + ports: + - \"4000:4000\"\ +" # EOF + + YML_VOLUMES=" + ewallet-deps: + ewallet-builds: + ewallet-node:\ +" # EOF +fi + +if [ -n "$EXTERNAL_NETWORK" ]; then + YML_NETWORKS=" + intnet: + external: + name: $EXTERNAL_NETWORK\ +" # EOF +fi + +printf "version: \"3\"\\n" +if [ -n "$YML_SERVICES" ]; then printf "\\nservices:%s\\n" "$YML_SERVICES"; fi +if [ -n "$YML_NETWORKS" ]; then printf "\\nnetworks:%s\\n" "$YML_NETWORKS"; fi +if [ -n "$YML_VOLUMES" ]; then printf "\\nvolumes:%s\\n" "$YML_VOLUMES"; fi diff --git a/mix.exs b/mix.exs index 853299f89..96917e783 100644 --- a/mix.exs +++ b/mix.exs @@ -18,7 +18,8 @@ defmodule EWallet.Umbrella.Mixfile do dialyzer: [ flags: [:underspecs, :unknown, :unmatched_returns], plt_add_apps: [:iex, :mix], - ignore_warnings: ".dialyzer_ignore.exs" + ignore_warnings: ".dialyzer_ignore.exs", + flags: ~w(-Wunmatched_returns -Werror_handling -Wunderspecs) ] ] end @@ -31,9 +32,11 @@ defmodule EWallet.Umbrella.Mixfile do defp deps do [ {:credo, "0.10.0", only: [:dev, :test], runtime: false}, + {:dialyxir, "~> 1.0.0-rc.3", only: [:dev], runtime: false}, + {:distillery, "~> 1.5", runtime: false}, {:ex_doc, "~> 0.16", only: :dev, runtime: false}, {:excoveralls, "~> 0.8", only: :test, runtime: false}, - {:dialyxir, "~> 1.0.0-rc.3", only: [:dev], runtime: false} + {:junit_formatter, "~> 2.2", only: :test} ] end diff --git a/mix.lock b/mix.lock index e2fc6fab1..8351ad021 100644 --- a/mix.lock +++ b/mix.lock @@ -11,7 +11,7 @@ "bypass": {:hex, :bypass, "1.0.0", "b78b3dcb832a71aca5259c1a704b2e14b55fd4e1327ff942598b4e7d1a7ad83d", [:mix], [{:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: false]}], "hexpm"}, "certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], [], "hexpm"}, "chaperon": {:hex, :chaperon, "0.2.3", "9edff95a1acdc7066ef915a0b26d479efcd80c527eecc5580233f654f53d5d80", [:mix], [{:e_q, "~> 1.0.0", [hex: :e_q, repo: "hexpm", optional: false]}, {:histogrex, "~> 0.0.4", [hex: :histogrex, repo: "hexpm", optional: false]}, {:httpoison, "~> 0.11.1", [hex: :httpoison, repo: "hexpm", optional: false]}, {:instream, "~> 0.16.0", [hex: :instream, repo: "hexpm", optional: false]}, {:poison, "~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}, {:uuid, "~> 1.1", [hex: :uuid, repo: "hexpm", optional: false]}, {:websockex, "~> 0.2", [hex: :websockex, repo: "hexpm", optional: false]}], "hexpm"}, - "cloak": {:hex, :cloak, "0.7.0", "3257357acd51e55eb08d00a41ca3e2ab2c83b8d6561633b1cee7262c5f6be527", [:mix], [{:ecto, ">= 1.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:flow, "~> 0.13", [hex: :flow, repo: "hexpm", optional: false]}, {:pbkdf2, "~> 2.0", [hex: :pbkdf2, repo: "hexpm", optional: true]}, {:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"}, + "cloak": {:hex, :cloak, "0.9.1", "d8980aa34b472cc6a07978f93b918db2f1cb603c53aabe1e4eb3a4aa3d8fb3f2", [:mix], [{:ecto, ">= 1.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:flow, "~> 0.14", [hex: :flow, repo: "hexpm", optional: false]}, {:pbkdf2, "~> 2.0", [hex: :pbkdf2, repo: "hexpm", optional: true]}, {:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"}, "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, "cors_plug": {:hex, :cors_plug, "1.5.2", "72df63c87e4f94112f458ce9d25800900cc88608c1078f0e4faddf20933eda6e", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, @@ -25,8 +25,9 @@ "decorator": {:hex, :decorator, "1.2.4", "31dfff6143d37f0b68d0bffb3b9f18ace14fea54d4f1b5e4f86ead6f00d9ff6e", [:mix], [], "hexpm"}, "deferred_config": {:hex, :deferred_config, "0.1.1", "ec912e9ee3c99b90a8d4bdec8fbd15309f4bd6729f30789e0ff6f595d06bbce5", [:mix], [], "hexpm"}, "dialyxir": {:hex, :dialyxir, "1.0.0-rc.3", "774306f84973fc3f1e2e8743eeaa5f5d29b117f3916e5de74c075c02f1b8ef55", [:mix], [], "hexpm"}, + "distillery": {:hex, :distillery, "1.5.3", "b2f4fc34ec71ab4f1202a796f9290e068883b042319aa8c9aa45377ecac8597a", [:mix], [], "hexpm"}, "e_q": {:hex, :e_q, "1.0.0", "7b4dab148b8f482fac6be0e3b5ecf5b4ca86d6148b33b96ee7ca9f2e2fcf2fb7", [:mix], [], "hexpm"}, - "earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"}, + "earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], [], "hexpm"}, "ecto": {:hex, :ecto, "2.1.6", "29b45f393c2ecd99f83e418ea9b0a2af6078ecb30f401481abac8a473c490f84", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, "elixir_make": {:hex, :elixir_make, "0.4.2", "332c649d08c18bc1ecc73b1befc68c647136de4f340b548844efc796405743bf", [:mix], [], "hexpm"}, "ex_aws": {:hex, :ex_aws, "2.1.0", "b92651527d6c09c479f9013caa9c7331f19cba38a650590d82ebf2c6c16a1d8a", [:mix], [{:configparser_ex, "~> 2.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1 or 1.8.6 or ~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:xml_builder, "~> 0.1.0", [hex: :xml_builder, repo: "hexpm", optional: true]}], "hexpm"}, @@ -36,7 +37,7 @@ "ex_ulid": {:git, "https://github.com/omisego/ex_ulid.git", "2572a88f2687c3aebc8e8657a999fa77bc769fa3", []}, "excoveralls": {:hex, :excoveralls, "0.9.2", "299ea4903be7cb2959af0f919d258af116736ca8d507f86c12ef2184698e21a0", [:mix], [{:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, - "flow": {:hex, :flow, "0.14.2", "84687153dcd10e321a2b09b5d1db9511ed704337a553a46e8b0758fde0b7e75c", [:mix], [{:gen_stage, "~> 0.14.0", [hex: :gen_stage, repo: "hexpm", optional: false]}], "hexpm"}, + "flow": {:hex, :flow, "0.14.3", "0d92991fe53035894d24aa8dec10dcfccf0ae00c4ed436ace3efa9813a646902", [:mix], [{:gen_stage, "~> 0.14.0", [hex: :gen_stage, repo: "hexpm", optional: false]}], "hexpm"}, "gen_smtp": {:hex, :gen_smtp, "0.12.0", "97d44903f5ca18ca85cb39aee7d9c77e98d79804bbdef56078adcf905cb2ef00", [:rebar3], [], "hexpm"}, "gen_stage": {:hex, :gen_stage, "0.14.1", "9d46723fda072d4f4bb31a102560013f7960f5d80ea44dcb96fd6304ed61e7a4", [:mix], [], "hexpm"}, "gettext": {:hex, :gettext, "0.16.0", "4a7e90408cef5f1bf57c5a39e2db8c372a906031cc9b1466e963101cb927dafc", [:mix], [], "hexpm"}, @@ -49,8 +50,10 @@ "jason": {:hex, :jason, "1.1.1", "d3ccb840dfb06f2f90a6d335b536dd074db748b3e7f5b11ab61d239506585eb2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, "json_web_token": {:hex, :json_web_token, "0.2.10", "61041d56369422c5e3a770cf7d7bf27224b3c4c12d3a7d79b43a002df766db22", [:mix], [{:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, + "junit_formatter": {:hex, :junit_formatter, "2.2.0", "da6093f0740c58a824f9585ebb7cb1b960efaecf48d1fa969e95d9c47c6b19dd", [:mix], [], "hexpm"}, "makeup": {:hex, :makeup, "0.5.5", "9e08dfc45280c5684d771ad58159f718a7b5788596099bdfb0284597d368a882", [:mix], [{:nimble_parsec, "~> 0.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, "makeup_elixir": {:hex, :makeup_elixir, "0.10.0", "0f09c2ddf352887a956d84f8f7e702111122ca32fbbc84c2f0569b8b65cbf7fa", [:mix], [{:makeup, "~> 0.5.5", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, + "meck": {:hex, :meck, "0.8.8", "eeb3efe811d4346e1a7f65b2738abc2ad73cbe1a2c91b5dd909bac2ea0414fa6", [:rebar3], [], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, @@ -70,6 +73,7 @@ "postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, "quantum": {:hex, :quantum, "2.2.7", "134277fdd2b9173d0bb53cb33b61f8f6cc5de75bd61c2e789850a202f72f9b0f", [:mix], [{:calendar, "~> 0.17", [hex: :calendar, repo: "hexpm", optional: true]}, {:crontab, "~> 1.1", [hex: :crontab, repo: "hexpm", optional: false]}, {:gen_stage, "~> 0.12", [hex: :gen_stage, repo: "hexpm", optional: false]}, {:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: true]}], "hexpm"}, "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"}, + "recon": {:hex, :recon, "2.3.4", "b406c2fccdeaa0d94e23b5e30ae3d635a2d461e363a5c9c6316897037cf050d2", [:rebar3], [], "hexpm"}, "sentry": {:hex, :sentry, "6.4.2", "71b3cf8ce6dbf7816b8086eb8f221fd7fd71cefdbf7461094c628785cae6a67c", [:mix], [{:hackney, "~> 1.8 or 1.6.5", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.3", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, "~> 1.6", [hex: :plug, repo: "hexpm", optional: true]}, {:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, "sweet_xml": {:hex, :sweet_xml, "0.6.5", "dd9cde443212b505d1b5f9758feb2000e66a14d3c449f04c572f3048c66e6697", [:mix], [], "hexpm"}, diff --git a/rel/commands/config.sh b/rel/commands/config.sh new file mode 100644 index 000000000..96f0e77c2 --- /dev/null +++ b/rel/commands/config.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +# shellcheck disable=SC2068 +"$RELEASE_ROOT_DIR/bin/ewallet" command Elixir.EWallet.ReleaseTasks config $@ diff --git a/rel/commands/initdb.sh b/rel/commands/initdb.sh new file mode 100644 index 000000000..aeda0ed9d --- /dev/null +++ b/rel/commands/initdb.sh @@ -0,0 +1,2 @@ +#!/bin/sh +"$RELEASE_ROOT_DIR/bin/ewallet" command Elixir.EWallet.ReleaseTasks initdb diff --git a/rel/commands/seed.sh b/rel/commands/seed.sh new file mode 100644 index 000000000..ac6d3f764 --- /dev/null +++ b/rel/commands/seed.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +seed_spec=seed + +while [ "$#" -gt 0 ]; do case $1 in + -e|--e2e) seed_spec=seed_e2e;; + *) echo "$0: illegal option -- $1"; exit 1;; +esac; shift; done + +"$RELEASE_ROOT_DIR/bin/ewallet" command Elixir.EWallet.ReleaseTasks "${seed_spec}" diff --git a/rel/config.exs b/rel/config.exs new file mode 100644 index 000000000..a71b31ca8 --- /dev/null +++ b/rel/config.exs @@ -0,0 +1,43 @@ +Path.join(["rel", "plugins", "*.exs"]) +|> Path.wildcard() +|> Enum.map(&Code.eval_file(&1)) + +use Mix.Releases.Config, + default_release: :ewallet, + default_environment: Mix.env + +environment :dev do + set dev_mode: true + set include_erts: false + set cookie: :dev +end + +environment :prod do + set include_erts: true + set include_src: false + set cookie: :prod +end + +release :ewallet do + set version: current_version(:ewallet) + set vm_args: "rel/vm.args" + set applications: [ + :runtime_tools, + activity_logger: :permanent, + admin_api: :permanent, + admin_panel: :permanent, + ewallet: :permanent, + ewallet_api: :permanent, + ewallet_config: :permanent, + ewallet_db: :permanent, + local_ledger: :permanent, + local_ledger_db: :permanent, + url_dispatcher: :permanent, + ] + + set commands: [ + "config": "rel/commands/config.sh", + "initdb": "rel/commands/initdb.sh", + "seed": "rel/commands/seed.sh", + ] +end diff --git a/rel/vm.args b/rel/vm.args new file mode 100644 index 000000000..23babce72 --- /dev/null +++ b/rel/vm.args @@ -0,0 +1,7 @@ +-name <%= release_name %>@${NODE_HOST} +-setcookie ${ERLANG_COOKIE} + +# Min/max port for Erlang to connect to nodes. +# Used for clustering. +-kernel inet_dist_listen_min 6900 +-kernel inet_dist_listen_max 6909 \ No newline at end of file diff --git a/rootfs/entrypoint b/rootfs/entrypoint new file mode 100644 index 000000000..7a09275a5 --- /dev/null +++ b/rootfs/entrypoint @@ -0,0 +1,74 @@ +#!/bin/execlineb -S0 + +with-contenv +cd /app +s6-setuidgid ewallet + +## NODE_HOST +## +## Used in clustering; combine with NODE_NAME, this is used for identifying +## and connecting each nodes. By default use the container hostname. +## +backtick -n default_host { s6-hostname } +importas -iu default_host default_host +importas -D $default_host NODE_HOST NODE_HOST +s6-env NODE_HOST=$NODE_HOST + +## ERLANG_COOKIE +## +## Used in clustering; all nodes in the cluster is required to have the same +## Erlang Cookie set. Randomly generated default cookie is only useful for +## the single instance scenario. +## +backtick -n default_cookie { + pipeline { + s6-head -c 6 /dev/urandom + } foreground { base64 } +} + +importas -iu default_cookie default_cookie +importas -D $default_cookie ERLANG_COOKIE ERLANG_COOKIE +s6-env ERLANG_COOKIE=$ERLANG_COOKIE + +## NODE_NAME +## +## Used in clustering; NODE_NAME along with NODE_HOST are used for identifying +## and connecting each nodes. By default use "ewallet". +## +importas -D ewallet NODE_NAME NODE_NAME +s6-env NODE_NAME=$NODE_NAME + +## NODE_DNS +## +## Used in clustering; by default eWallet is configure to discover nodes via +## DNS. Registering nodes to the cluster is a responsibility of cluster tools +## e.g. Kubernetes. +## +importas -D localhost NODE_DNS NODE_DNS +s6-env NODE_DNS=$NODE_DNS + +## HOME +## +## Home is required to be set since some tools use it to create e.g. cache. +## By default eWallet will run with a limited privileges so HOME need to be +## somewhere writable. +## +s6-env HOME=/app + +## REPLACE_OS_VARS +## +## Used by Distillery to replace environment variables in settings to the +## value of environment variable. +## +s6-env REPLACE_OS_VARS=yes + +## Known commands +## +ifelse { test $1 == "foreground" } { /app/bin/ewallet $@ } +ifelse { test $1 == "initdb" } { /app/bin/ewallet $@ } +ifelse { test $1 == "seed" } { /app/bin/ewallet $@ } + +## Fallback; if we're not running the known command, just run it as is. +## This is to allow e.g. administrator attaching a shell into the container. +## +exec $@ diff --git a/update-versions.sh b/update-versions.sh new file mode 100755 index 000000000..d6f05e578 --- /dev/null +++ b/update-versions.sh @@ -0,0 +1,37 @@ +#!/bin/sh +BASE_DIR=$(cd "$(dirname "$0")" || exit; pwd -P) +FILE_LIST="/tmp/update_version_files" + +if [ -z "$1" ]; then + printf "Usage: %s NEW_VERSION\\n\\n" "$0" + printf "Update version string in mix.exs and config.exs with NEW_VERSION\\n" + printf "by scanning lines with version: string. This script will try its\\n" + printf "best to retain the indention of the original string.\\n" + exit 2 +fi + +# POSIX sh doesn't supported piping a list of files into another command +# so we need to use intermediate file list and read from it. +trap 'rm $FILE_LIST' 0 1 2 3 6 14 15 +find "$BASE_DIR/apps" \ + -not -name "$(printf "*\\n*")" \ + \( -iname "mix.exs" -or -iname "config.exs" \) \ +> "$FILE_LIST" + +printf "Updating versions...\\n" + +while IFS= read -r file; do + if ! grep -E -q "^[\ ]+version:" "$file"; then + continue + fi + + printf "* %-40s" "${file#$BASE_DIR/*}..." + NEW_VERSION=$1 awk ' + m = match($0, "^([\ ]+version:[\ ]+)") { + print substr($0, RSTART, RLENGTH-1) " \"" ENVIRON["NEW_VERSION"] "\"," + } ! m { print } + ' < "$file" > "$file.tmp" + + mv "$file.tmp" "$file" + printf " OK\\n" +done < "$FILE_LIST"