ansible-taler-exchange

Ansible playbook to deploy a production Taler Exchange
Log | Files | Refs | README | LICENSE

commit 3ce7e8b9320a793b36ee5cec5b2bb2ee025d908c
parent 6c0bbf20f13835957ddf5eaed996af0257dad80a
Author: Hernâni Marques <hernani+magikoopa@vecirex.net>
Date:   Sat, 19 Sep 2026 19:49:55 +0200

hacktivism goa: deploy scripts + inventory + role stubs

Include GOA inventory host + wire-gateway URL override; sync with upstream
libeufin_port rename and inventory cleanup.

Diffstat:
Adeploy-hacktivism-goa.sh | 25+++++++++++++++++++++++++
Minventories/default | 5+++++
Ainventories/host_vars/taler-hacktivism-exchange-ansible/public.yml | 31+++++++++++++++++++++++++++++++
Ainventories/host_vars/taler-hacktivism-exchange-ansible/secrets.yml | 6++++++
Aplaybooks/setup-hacktivism-goa.yml | 14++++++++++++++
Mroles/exchange/templates/etc/taler-exchange/conf.d/exchange-business.conf.j2 | 2+-
Mroles/exchange/templates/etc/taler-exchange/secrets/exchange-accountcredentials-primary.secret.conf.j2 | 5+++++
Aroles/hacktivism_goa/README.md | 41+++++++++++++++++++++++++++++++++++++++++
Aroles/hacktivism_goa/defaults/main.yml | 24++++++++++++++++++++++++
Aroles/hacktivism_goa/files/denominations-goa.conf | 331+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroles/hacktivism_goa/files/terms/no-privacy-v0.en.rst | 15+++++++++++++++
Aroles/hacktivism_goa/files/terms/no-terms-v0.en.rst | 16++++++++++++++++
Aroles/hacktivism_goa/tasks/coins.yml | 31+++++++++++++++++++++++++++++++
Aroles/hacktivism_goa/tasks/db.yml | 10++++++++++
Aroles/hacktivism_goa/tasks/health.yml | 31+++++++++++++++++++++++++++++++
Aroles/hacktivism_goa/tasks/main.yml | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroles/hacktivism_goa/tasks/offline.yml | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Aroles/hacktivism_goa/tasks/packages.yml | 39+++++++++++++++++++++++++++++++++++++++
Aroles/hacktivism_goa/tasks/postgres.yml | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroles/hacktivism_goa/tasks/site_config.yml | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroles/hacktivism_goa/tasks/start.yml | 17+++++++++++++++++
Aroles/hacktivism_goa/tasks/systemd_container.yml | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroles/hacktivism_goa/templates/etc/taler-exchange/conf.d/setup.conf.j2 | 29+++++++++++++++++++++++++++++
Aroles/hacktivism_goa/templates/etc/taler-exchange/exchange-overrides.conf.j2 | 42++++++++++++++++++++++++++++++++++++++++++
Aroles/hacktivism_goa/templates/etc/taler-exchange/secrets/exchange-accountcredentials.secret.conf.j2 | 5+++++
Arun-container-koopa.sh | 45+++++++++++++++++++++++++++++++++++++++++++++
26 files changed, 1120 insertions(+), 1 deletion(-)

diff --git a/deploy-hacktivism-goa.sh b/deploy-hacktivism-goa.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# Deploy event-currency GOA exchange (regional-currency flow + systemd). +# Prerequisites on koopa: +# 1) ./run-container-koopa.sh # systemd container, port 9011 +# 2) this script +# Inventory: ansible_connection=podman +set -eu +cd "$(dirname "$0")" +export PATH="${HOME}/venv-ansible/bin:${PATH}" +export ANSIBLE_HOST_KEY_CHECKING=False +if [ ! -f vault_pass.txt ]; then + echo unused > vault_pass.txt +fi + +# Refuse obvious non-systemd targets early +if ! podman exec taler-hacktivism-exchange-ansible cat /proc/1/comm 2>/dev/null | grep -qx systemd; then + echo "error: container PID1 is not systemd. Run ./run-container-koopa.sh first." >&2 + exit 1 +fi + +exec ansible-playbook -v \ + --limit taler-hacktivism-exchange-ansible \ + -e @inventories/host_vars/taler-hacktivism-exchange-ansible/public.yml \ + -e @inventories/host_vars/taler-hacktivism-exchange-ansible/secrets.yml \ + playbooks/setup-hacktivism-goa.yml diff --git a/inventories/default b/inventories/default @@ -5,9 +5,14 @@ spec ansible_port=22 ansible_user=root ansible_host=spec.taler-ops.ch rusty ansible_port=22 ansible_user=root ansible_host=rusty.taler-ops.ch podman-localhost ansible_port=8022 ansible_host=127.0.0.1 +# hacktivism GOA exchange: podman container on koopa (API host:9011 only; ansible via podman) +# Run ansible ON koopa. No SSH publish — ports stay in 9000 range (9011 exchange). +taler-hacktivism-exchange-ansible ansible_connection=podman ansible_user=root + [testing] rusty podman-localhost +taler-hacktivism-exchange-ansible [production] spec diff --git a/inventories/host_vars/taler-hacktivism-exchange-ansible/public.yml b/inventories/host_vars/taler-hacktivism-exchange-ansible/public.yml @@ -0,0 +1,31 @@ +--- +# Event currency (GOA) — aligned with regional-currency without fiat. +# Target: Caddy → host :9011 → container exchange. + +domain_name: "hacktivism.ch" +exchange_domain: "exchange.hacktivism.ch" +TARGET_HOST_NAME: "taler-hacktivism-exchange-ansible" + +taler_repo_suites: trixie + +# regional-currency style flags (systemd required) +require_systemd: true +do_conversion: false +# greenfield with new offline key: set true after offline key exists in container +do_offline: false +exchange_account_id: "1" +use_static_goa_coins: true +exchange_wire_method: x-taler-bank + +CURRENCY: GOA +CURRENCY_ROUND_UNIT: "GOA:0.00000001" +EXCHANGE_BASE_URL: "https://exchange.hacktivism.ch/" +EXCHANGE_HTTP_PORT: 9011 + +EXCHANGE_MASTER_PUB: TW6K5FXF81VYCAH0YWYX0SX98KBBSJ42VX27WAX01FTFH400QG10 + +EXCHANGE_TERMS_ETAG: "no-terms-v0" +EXCHANGE_PP_ETAG: "no-privacy-v0" + +EXCHANGE_BANK_ACCOUNT_PAYTO: "payto://x-taler-bank/bank.hacktivism.ch/exchange?receiver-name=GOA%20Exchange" +EXCHANGE_WIRE_GATEWAY_URL: "https://bank.hacktivism.ch/accounts/exchange/taler-wire-gateway/" diff --git a/inventories/host_vars/taler-hacktivism-exchange-ansible/secrets.yml b/inventories/host_vars/taler-hacktivism-exchange-ansible/secrets.yml @@ -0,0 +1,6 @@ +--- +# Minimal secrets for hacktivism GOA (no EBICS/KYC/challenger). +HAVE_SECRETS: true + +EXCHANGE_ATTRIBUTE_ENCRYPTION_KEY: "6f5e035859774b6b2d6d99bba52d3556c436d6ceb463cef73b7ba947a2b7f30a" +EXCHANGE_WIRE_GATEWAY_TOKEN: "secret-token:QGN4QNHJ6G7RDK1T32KMD866AV4N1ZE00QHHYZPDJ2MNA9X98ZW0" diff --git a/playbooks/setup-hacktivism-goa.yml b/playbooks/setup-hacktivism-goa.yml @@ -0,0 +1,14 @@ +--- +# Lean GOA exchange deploy for hacktivism (koopa podman). +# Target config = live stack: GOA, :9011, x-taler-bank → bank.hacktivism.ch, +# Caddy on host terminates TLS. No nexus/IBAN, no LE, no KYC stack. +- name: Deploy hacktivism GOA exchange + hosts: taler-hacktivism-exchange-ansible + any_errors_fatal: true + pre_tasks: + - name: Require secrets + ansible.builtin.fail: + msg: "HAVE_SECRETS not set — load inventories/host_vars/taler-hacktivism-exchange-ansible/secrets.yml" + when: HAVE_SECRETS is undefined + roles: + - role: hacktivism_goa diff --git a/roles/exchange/templates/etc/taler-exchange/conf.d/exchange-business.conf.j2 b/roles/exchange/templates/etc/taler-exchange/conf.d/exchange-business.conf.j2 @@ -48,7 +48,7 @@ ENABLE_DEBIT = YES # Make sure to URL-encode spaces in $NAME! PAYTO_URI = {{ exchange_bank_account_payto }} -WIRE_METHOD = iban +WIRE_METHOD = {{ EXCHANGE_WIRE_METHOD | default('iban') }} {% if sanction_list is defined %} [exchange-sanctionscheck] diff --git a/roles/exchange/templates/etc/taler-exchange/secrets/exchange-accountcredentials-primary.secret.conf.j2 b/roles/exchange/templates/etc/taler-exchange/secrets/exchange-accountcredentials-primary.secret.conf.j2 @@ -1,4 +1,9 @@ [exchange-accountcredentials-primary] WIRE_GATEWAY_AUTH_METHOD = bearer +{% if EXCHANGE_WIRE_GATEWAY_URL is defined %} +WIRE_GATEWAY_URL = "{{ EXCHANGE_WIRE_GATEWAY_URL }}" +TOKEN = {{ EXCHANGE_WIRE_GATEWAY_TOKEN }} +{% else %} WIRE_GATEWAY_URL = "http://localhost:{{ libeufin_port }}/taler-wire-gateway/" TOKEN = {{ ansible_local['libeufin-nexus-access-token'] }} +{% endif %} diff --git a/roles/hacktivism_goa/README.md b/roles/hacktivism_goa/README.md @@ -0,0 +1,41 @@ +# Role `hacktivism_goa` + +Event currency **GOA** for hacktivism, structured like +`taler-deployment/regional-currency/setup-exchange.sh`, **with systemd**. + +## Requirements + +- Container PID1 = **systemd** (`./run-container-koopa.sh`) +- Host port **9011** only; TLS on host Caddy +- Bank already at `bank.hacktivism.ch` (x-taler-bank wire gateway) + +Snapshot / `sleep infinity` images are **rejected** (`require_systemd: true`). + +## Flow + +| Step | regional-currency | this role | +|------|-------------------|-----------| +| packages | apt exchange/postgres | `packages.yml` | +| config | `conf.d/setup.conf` + wire secret | `site_config.yml` + GOA overrides | +| coins | `taler-harness gen-coin-config` | static GOA ladder by default | +| db | `taler-exchange-dbconfig` | `db.yml` | +| start | `systemctl restart taler-exchange.target` | `start.yml` | +| offline | `taler-exchange-offline` + timer | `offline.yml` if `do_offline` | +| health | `/config` `/keys` | `health.yml` | +| conversion | optional nexus/IBAN | **not supported** | + +## GOA specifics (host_vars) + +- `CURRENCY=GOA`, `CURRENCY_ROUND_UNIT=GOA:0.00000001` +- `SERVE=tcp` `PORT=9011` +- `exchange_account_id: "1"` (live name; set `default` for pure regional) +- `use_static_goa_coins: true` +- `do_offline: false` until offline master key is available in-container + +## Usage (koopa) + +```bash +cd ~/ansible-taler-exchange +./run-container-koopa.sh # rebuilds systemd container (replaces current) +./deploy-hacktivism-goa.sh # ansible → systemctl path +``` diff --git a/roles/hacktivism_goa/defaults/main.yml b/roles/hacktivism_goa/defaults/main.yml @@ -0,0 +1,24 @@ +--- +# Modelled after taler-deployment/regional-currency (event currency, no fiat). +# Requires systemd as PID 1 (podman --systemd=always + /usr/sbin/init). +# Host TLS (Caddy) + port map stay outside this role. + +# Require systemd (regional-currency uses systemctl throughout). +require_systemd: true + +# regional-currency: DO_CONVERSION — always false here (no EBICS/IBAN) +do_conversion: false + +# regional-currency: DO_OFFLINE — sign keys + enable-account + wire-fee +# true = greenfield offline keying; false = MASTER_PUBLIC_KEY already set +# and keys already on exchange (or offline step done separately). +do_offline: false + +# Account section: live hacktivism used "1"; pure regional uses "default" +exchange_account_id: "1" + +# Wire fee method (regional enable-account) +exchange_wire_method: x-taler-bank + +# Coins: static GOA ladder (harness gen-coin-config is for 0.01-scale) +use_static_goa_coins: true diff --git a/roles/hacktivism_goa/files/denominations-goa.conf b/roles/hacktivism_goa/files/denominations-goa.conf @@ -0,0 +1,331 @@ +# GOA denominations for exchange.hacktivism.ch +# Units: 1 GOA = 1000 mGOA = 1_000_000 uGOA +# VALUE uses base currency; coin sections cover 1–2–5 ladders at u/m/whole scale. + +# --- uGOA (10^-6 GOA) --- +[coin_goa_0_000001] +VALUE = GOA:0.000001 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_000002] +VALUE = GOA:0.000002 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_000005] +VALUE = GOA:0.000005 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_00001] +VALUE = GOA:0.00001 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_00002] +VALUE = GOA:0.00002 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_00005] +VALUE = GOA:0.00005 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_0001] +VALUE = GOA:0.0001 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_0002] +VALUE = GOA:0.0002 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_0005] +VALUE = GOA:0.0005 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +# --- mGOA (10^-3 GOA) --- +[coin_goa_0_001] +VALUE = GOA:0.001 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_002] +VALUE = GOA:0.002 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_005] +VALUE = GOA:0.005 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_01] +VALUE = GOA:0.01 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_02] +VALUE = GOA:0.02 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_05] +VALUE = GOA:0.05 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_1] +VALUE = GOA:0.1 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_2] +VALUE = GOA:0.2 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_0_5] +VALUE = GOA:0.5 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +# --- whole GOA --- +[coin_goa_1_0] +VALUE = GOA:1 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_2_0] +VALUE = GOA:2 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_5_0] +VALUE = GOA:5 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_10_0] +VALUE = GOA:10 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +# --- large whole GOA (align with common_amounts 20…1000) --- +[coin_goa_20_0] +VALUE = GOA:20 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_50_0] +VALUE = GOA:50 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_100_0] +VALUE = GOA:100 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_200_0] +VALUE = GOA:200 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA + +[coin_goa_1000_0] +VALUE = GOA:1000 +DURATION_WITHDRAW = 7 days +DURATION_SPEND = 2 years +DURATION_LEGAL = 3 years +FEE_WITHDRAW = GOA:0 +FEE_DEPOSIT = GOA:0 +FEE_REFRESH = GOA:0 +FEE_REFUND = GOA:0 +RSA_KEYSIZE = 2048 +CIPHER = RSA diff --git a/roles/hacktivism_goa/files/terms/no-privacy-v0.en.rst b/roles/hacktivism_goa/files/terms/no-privacy-v0.en.rst @@ -0,0 +1,15 @@ +No Privacy Policy Required +========================== + +This is an **experimental / exploration** GNU Taler exchange for **GOA**. + +**No formal privacy policy is required** for this demo service. + +Note (high level): + +* Wire transfers via the regional bank may identify bank account holders. +* The exchange processes withdrawals, deposits, and related operations + as required by the GNU Taler protocol. +* Logs may be kept for operation and debugging. + +Do not use this service if that is unacceptable. diff --git a/roles/hacktivism_goa/files/terms/no-terms-v0.en.rst b/roles/hacktivism_goa/files/terms/no-terms-v0.en.rst @@ -0,0 +1,16 @@ +No Terms Required +================= + +This is an **experimental / exploration** GNU Taler exchange for the +currency **GOA** (hacktivism.ch). + +**No formal terms of service are required** to use this service. + +By withdrawing or using GOA coins you acknowledge that: + +* This service is for exploration and testing only. +* There is no guaranteed availability, support, or redemption. +* Operators may reset balances or change configuration without notice. +* Do not use real money you cannot afford to lose. + +If you do not agree, do not use this exchange. diff --git a/roles/hacktivism_goa/tasks/coins.yml b/roles/hacktivism_goa/tasks/coins.yml @@ -0,0 +1,31 @@ +--- +# regional uses: taler-harness deployment gen-coin-config +# GOA needs micro-scale denoms → keep static ladder from admin-log. + +- name: Place static GOA denominations + ansible.builtin.copy: + src: denominations-goa.conf + dest: /etc/taler-exchange/conf.d/exchange-coins.conf + owner: root + group: root + mode: "0644" + when: use_static_goa_coins | bool + +- name: Generate coins via taler-harness (regional-currency style) + ansible.builtin.shell: | + set -e + CUR="{{ CURRENCY }}" + taler-harness deployment gen-coin-config \ + --min-amount "${CUR}:0.01" \ + --max-amount "${CUR}:100" | + sed -e "s/FEE_DEPOSIT = ${CUR}:0.01/FEE_DEPOSIT = ${CUR}:0/" \ + | sed 's/coin-/coin_/i' \ + > "/etc/taler-exchange/conf.d/${CUR}-coins.conf" + args: + executable: /bin/bash + when: + - not (use_static_goa_coins | bool) + - ansible_facts.packages is not defined or true + register: harness_coins + failed_when: false + changed_when: harness_coins.rc == 0 diff --git a/roles/hacktivism_goa/tasks/db.yml b/roles/hacktivism_goa/tasks/db.yml @@ -0,0 +1,10 @@ +--- +# regional-currency: taler-exchange-dbconfig + +- name: Init / upgrade exchange DB + ansible.builtin.command: + cmd: taler-exchange-dbconfig -c /etc/taler-exchange/taler-exchange.conf + chdir: /tmp + register: dbconfig + changed_when: true + failed_when: dbconfig.rc != 0 diff --git a/roles/hacktivism_goa/tasks/health.yml b/roles/hacktivism_goa/tasks/health.yml @@ -0,0 +1,31 @@ +--- +# regional-currency: curl /config and /keys + +- name: Wait for local exchange /config + ansible.builtin.uri: + url: "http://127.0.0.1:{{ EXCHANGE_HTTP_PORT | default(9011) }}/config" + status_code: 200 + register: cfg + retries: 30 + delay: 2 + until: cfg is succeeded and cfg.status == 200 + +- name: Wait for local exchange /keys + ansible.builtin.uri: + url: "http://127.0.0.1:{{ EXCHANGE_HTTP_PORT | default(9011) }}/keys" + status_code: 200 + register: keys + retries: 60 + delay: 2 + until: keys is succeeded and keys.status == 200 + failed_when: false + +- name: Report health + ansible.builtin.debug: + msg: >- + /config={{ cfg.status }} + currency={{ cfg.json.currency | default('?') }} + /keys={{ keys.status | default('n/a') }} + systemd=yes + account={{ exchange_account_id }} + do_offline={{ do_offline }} diff --git a/roles/hacktivism_goa/tasks/main.yml b/roles/hacktivism_goa/tasks/main.yml @@ -0,0 +1,60 @@ +--- +# Event/regional exchange for hacktivism GOA + systemd. +# Flow = taler-deployment/regional-currency/setup-exchange.sh +# packages → config → coins → db → systemctl taler-exchange.target +# → optional offline → /config + /keys +# +# NOT included: nginx, certbot, nexus, EBICS, IBAN, KYC, snapshot/manual start. + +- name: Detect init model + ansible.builtin.command: cat /proc/1/comm + register: init_comm + changed_when: false + +- name: Set systemd_available fact + ansible.builtin.set_fact: + systemd_available: "{{ init_comm.stdout | trim == 'systemd' }}" + +- name: Require systemd (regional-currency model) + ansible.builtin.fail: + msg: >- + PID1 is '{{ init_comm.stdout | trim }}', not systemd. + Recreate the container with run-container-koopa.sh + (podman --systemd=always, image :base, /usr/sbin/init). + Snapshot/sleep-infinity images are not supported by this role. + when: + - require_systemd | bool + - not (systemd_available | bool) + +- name: Fail if conversion requested + ansible.builtin.fail: + msg: "do_conversion is not supported — use regional-currency host install for fiat/EBICS" + when: do_conversion | bool + +- name: Packages + ansible.builtin.include_tasks: packages.yml + +- name: Site config (regional setup.conf + GOA overrides + wire + terms) + ansible.builtin.include_tasks: site_config.yml + +- name: Denominations + ansible.builtin.include_tasks: coins.yml + +- name: Postgres (systemd) + ansible.builtin.include_tasks: postgres.yml + +- name: Database schema + ansible.builtin.include_tasks: db.yml + +- name: Systemd drop-ins for rootless podman + ansible.builtin.include_tasks: systemd_container.yml + +- name: Start exchange (systemctl, regional-currency) + ansible.builtin.include_tasks: start.yml + +- name: Offline keys / wire enable (regional) + ansible.builtin.include_tasks: offline.yml + when: do_offline | bool + +- name: Health checks + ansible.builtin.include_tasks: health.yml diff --git a/roles/hacktivism_goa/tasks/offline.yml b/roles/hacktivism_goa/tasks/offline.yml @@ -0,0 +1,50 @@ +--- +# regional-currency/setup-exchange.sh offline block (no conversion). +# Needs offline master key; if EXCHANGE_MASTER_PUB is pre-set it must match. + +- name: Wait for management/keys after start + ansible.builtin.uri: + url: "http://127.0.0.1:{{ EXCHANGE_HTTP_PORT | default(9011) }}/management/keys" + status_code: [200, 204] + register: mkeys + retries: 60 + delay: 2 + until: mkeys is succeeded + +- name: Offline download / sign / upload + ansible.builtin.command: + cmd: taler-exchange-offline download sign upload + become: true + become_user: taler-exchange-offline + register: offline_sign + changed_when: offline_sign.rc == 0 + +- name: Offline enable-account + wire-fee x-taler-bank + ansible.builtin.shell: | + set -e + taler-exchange-offline \ + enable-account "{{ EXCHANGE_BANK_ACCOUNT_PAYTO }}" \ + display-hint 0 "{{ CURRENCY }} Exchange" \ + wire-fee now {{ exchange_wire_method }} "{{ CURRENCY }}:0" "{{ CURRENCY }}:0" \ + global-fee now "{{ CURRENCY }}:0" "{{ CURRENCY }}:0" "{{ CURRENCY }}:0" 1h 6a 0 \ + upload + args: + executable: /bin/bash + become: true + become_user: taler-exchange-offline + register: offline_account + changed_when: offline_account.rc == 0 + +- name: Enable offline renewal timer (regional) + ansible.builtin.systemd: + name: taler-exchange-offline.timer + state: started + enabled: true + failed_when: false + +- name: Report offline step + ansible.builtin.debug: + msg: >- + management/keys={{ mkeys.status }}, + sign rc={{ offline_sign.rc }}, + enable-account rc={{ offline_account.rc }} diff --git a/roles/hacktivism_goa/tasks/packages.yml b/roles/hacktivism_goa/tasks/packages.yml @@ -0,0 +1,39 @@ +--- +# regional-currency/install_packages.sh — only exchange+postgres bits (no nginx/nexus) + +- name: Ensure apt keyrings dir + ansible.builtin.file: + path: /etc/apt/keyrings + state: directory + mode: "0755" + +- name: Deploy Taler apt key + ansible.builtin.copy: + src: "{{ role_path }}/../common_packages/files/etc/apt/keyrings/taler-systems.gpg" + dest: /etc/apt/keyrings/taler-systems.gpg + owner: root + group: root + mode: "0644" + +- name: Add GNU Taler apt list + ansible.builtin.copy: + dest: /etc/apt/sources.list.d/taler-systems.list + owner: root + group: root + mode: "0644" + content: | + deb [arch=amd64 signed-by=/etc/apt/keyrings/taler-systems.gpg] https://deb.taler.net/apt/debian {{ taler_repo_suites | default(ansible_facts['distribution_release']) }} main + when: ansible_facts["os_family"] == "Debian" + +- name: Install exchange + postgres + ansible.builtin.apt: + name: + - postgresql + - taler-exchange + - curl + - jq + - python3-psycopg2 + - sudo + state: present + update_cache: true + when: ansible_facts["os_family"] == "Debian" diff --git a/roles/hacktivism_goa/tasks/postgres.yml b/roles/hacktivism_goa/tasks/postgres.yml @@ -0,0 +1,69 @@ +--- +# regional-currency assumes package postgres under systemd. + +- name: Fix SSL key access for postgres in containers + ansible.builtin.shell: | + set -e + if [ -d /etc/ssl/private ]; then + chown root:ssl-cert /etc/ssl/private + chmod 710 /etc/ssl/private + fi + if [ -f /etc/ssl/private/ssl-cert-snakeoil.key ]; then + chown root:ssl-cert /etc/ssl/private/ssl-cert-snakeoil.key + chmod 640 /etc/ssl/private/ssl-cert-snakeoil.key + fi + usermod -aG ssl-cert postgres 2>/dev/null || true + args: + executable: /bin/bash + changed_when: true + +- name: Make postgresql cluster conf readable for peer-auth taler users + ansible.builtin.shell: | + set -e + for d in /etc/postgresql/*/*/ ; do + [ -d "$d" ] || continue + chmod 755 /etc/postgresql "$(dirname "$d")" "$d" 2>/dev/null || true + chmod 644 "$d"/*.conf 2>/dev/null || true + done + for u in taler-exchange-httpd taler-exchange-wire taler-exchange-aggregator \ + taler-exchange-closer taler-exchange-expire taler-exchange-offline \ + taler-exchange-secmod-rsa; do + id "$u" >/dev/null 2>&1 && usermod -aG postgres "$u" || true + done + args: + executable: /bin/bash + changed_when: true + +# Meta unit postgresql.service is oneshot; real work is postgresql@VER-main +- name: Ensure PostgreSQL meta unit enabled + ansible.builtin.systemd: + name: postgresql + enabled: true + daemon_reload: true + +- name: Discover postgres cluster unit + ansible.builtin.shell: | + set -e + if command -v pg_lsclusters >/dev/null; then + pg_lsclusters --no-header | awk '{print "postgresql@" $1 "-" $2 ".service"; exit}' + else + echo "postgresql@17-main.service" + fi + args: + executable: /bin/bash + register: pg_unit + changed_when: false + +- name: Start postgres cluster unit + ansible.builtin.systemd: + name: "{{ pg_unit.stdout | trim }}" + state: started + enabled: true + +- name: Wait until postgres accepts connections + ansible.builtin.command: pg_isready + register: pg_ready + retries: 15 + delay: 1 + until: pg_ready.rc == 0 + changed_when: false diff --git a/roles/hacktivism_goa/tasks/site_config.yml b/roles/hacktivism_goa/tasks/site_config.yml @@ -0,0 +1,66 @@ +--- +# regional-currency/setup-exchange.sh layout + GOA host port / units + +- name: Place regional-style conf.d/setup.conf + ansible.builtin.template: + src: etc/taler-exchange/conf.d/setup.conf.j2 + dest: /etc/taler-exchange/conf.d/setup.conf + owner: root + group: root + mode: "0644" + +# Package only inlines conf.d/*.conf + overrides.conf — not exchange-overrides.conf +- name: Place exchange-overrides.conf (currency-goa units) + ansible.builtin.template: + src: etc/taler-exchange/exchange-overrides.conf.j2 + dest: /etc/taler-exchange/exchange-overrides.conf + owner: root + group: root + mode: "0644" + +- name: Ensure main conf inlines exchange-overrides.conf + ansible.builtin.lineinfile: + path: /etc/taler-exchange/taler-exchange.conf + line: "@inline@ exchange-overrides.conf" + insertafter: EOF + state: present + +# Filename sorts after package exchange-system.conf (SERVE=unix) +- name: Place zz-serve-tcp.conf so PORT/SERVE win package defaults + ansible.builtin.copy: + dest: /etc/taler-exchange/conf.d/zz-serve-tcp.conf + owner: root + group: root + mode: "0644" + content: | + [exchange] + SERVE = tcp + PORT = {{ EXCHANGE_HTTP_PORT | default(9011) }} + +# regional: chown taler-exchange-wire, mode 0400 +- name: Place wire gateway secret + ansible.builtin.template: + src: etc/taler-exchange/secrets/exchange-accountcredentials.secret.conf.j2 + dest: "/etc/taler-exchange/secrets/exchange-accountcredentials-{{ exchange_account_id }}.secret.conf" + owner: taler-exchange-wire + group: taler-exchange-db + mode: "0440" + +- name: Ensure terms data dir + ansible.builtin.file: + path: /var/lib/taler-exchange/terms + state: directory + owner: taler-exchange-httpd + group: root + mode: "0755" + +- name: Install no-terms / no-privacy stubs + ansible.builtin.copy: + src: "terms/{{ item }}" + dest: "/var/lib/taler-exchange/terms/{{ item }}" + owner: taler-exchange-httpd + group: root + mode: "0644" + loop: + - no-terms-v0.en.rst + - no-privacy-v0.en.rst diff --git a/roles/hacktivism_goa/tasks/start.yml b/roles/hacktivism_goa/tasks/start.yml @@ -0,0 +1,17 @@ +--- +# regional-currency/setup-exchange.sh: +# systemctl enable taler-exchange.target +# systemctl restart taler-exchange.target + +- name: Stop exchange before reconfiguration (regional) + ansible.builtin.systemd: + name: taler-exchange.target + state: stopped + failed_when: false + +- name: Enable and restart taler-exchange.target + ansible.builtin.systemd: + daemon_reload: true + name: taler-exchange.target + state: restarted + enabled: true diff --git a/roles/hacktivism_goa/tasks/systemd_container.yml b/roles/hacktivism_goa/tasks/systemd_container.yml @@ -0,0 +1,112 @@ +--- +# Rootless podman + package units: +# 1) sandbox → CAP_SYS_ADMIN / 217 USER +# 2) socket activation → ignores SERVE=tcp PORT=9011 +# Fix: drop sandbox, mask .socket, install TCP-only httpd unit override. + +- name: Ensure runtime dirs for exchange + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + mode: "0755" + owner: "{{ item.owner }}" + group: "{{ item.group }}" + loop: + - { path: /run/taler-exchange, owner: root, group: root } + - { path: /run/taler-exchange/httpd, owner: taler-exchange-httpd, group: taler-exchange-secmod } + - { path: /run/taler-exchange/secmod-rsa, owner: taler-exchange-secmod-rsa, group: taler-exchange-secmod } + - { path: /run/taler-exchange/secmod-cs, owner: taler-exchange-secmod-cs, group: taler-exchange-secmod } + - { path: /run/taler-exchange/secmod-eddsa, owner: taler-exchange-secmod-eddsa, group: taler-exchange-secmod } + failed_when: false + +- name: Ensure drop-in directories for helper units + ansible.builtin.file: + path: "/etc/systemd/system/{{ item }}.service.d" + state: directory + mode: "0755" + loop: + - taler-exchange-secmod-rsa + - taler-exchange-secmod-cs + - taler-exchange-secmod-eddsa + - taler-exchange-aggregator + - taler-exchange-closer + - taler-exchange-wirewatch + - taler-exchange-transfer + - taler-exchange-expire + +- name: Install container-friendly drop-ins for helper units + ansible.builtin.copy: + dest: "/etc/systemd/system/{{ item }}.service.d/container.conf" + owner: root + group: root + mode: "0644" + content: | + [Service] + PrivateTmp=no + PrivateDevices=no + ProtectSystem=no + ProtectHome=no + ProtectKernelTunables=no + ProtectControlGroups=no + ProtectKernelModules=no + ProtectHostname=no + ProtectClock=no + RestrictNamespaces=no + NoNewPrivileges=no + AmbientCapabilities= + CapabilityBoundingSet= + loop: + - taler-exchange-secmod-rsa + - taler-exchange-secmod-cs + - taler-exchange-secmod-eddsa + - taler-exchange-aggregator + - taler-exchange-closer + - taler-exchange-wirewatch + - taler-exchange-transfer + - taler-exchange-expire + +- name: Mask package socket unit (forces TCP SERVE, not unix sock) + ansible.builtin.systemd: + name: taler-exchange-httpd.socket + masked: true + state: stopped + enabled: false + failed_when: false + +- name: Install TCP-only httpd unit override (no socket Requires) + ansible.builtin.copy: + dest: /etc/systemd/system/taler-exchange-httpd.service + owner: root + group: root + mode: "0644" + content: | + [Unit] + Description=GNU Taler payment system exchange REST API (container TCP) + AssertPathExists=/etc/taler-exchange/taler-exchange.conf + Requires=taler-exchange-secmod-cs.service taler-exchange-secmod-rsa.service taler-exchange-secmod-eddsa.service + After=postgresql.service network.target taler-exchange-secmod-cs.service taler-exchange-secmod-rsa.service taler-exchange-secmod-eddsa.service + PartOf=taler-exchange.target + + [Service] + User=taler-exchange-httpd + Type=simple + EnvironmentFile=-/etc/taler-exchange/taler-exchange.env + Restart=always + RestartMode=direct + RestartSec=1ms + StartLimitBurst=5 + StartLimitInterval=5s + ExecStart=/usr/bin/taler-exchange-httpd -c /etc/taler-exchange/taler-exchange.conf -L INFO + StandardOutput=journal + StandardError=journal + PrivateTmp=no + PrivateDevices=no + ProtectSystem=no + Slice=taler-exchange.slice + + [Install] + WantedBy=multi-user.target + +- name: Reload systemd after unit changes + ansible.builtin.systemd: + daemon_reload: true diff --git a/roles/hacktivism_goa/templates/etc/taler-exchange/conf.d/setup.conf.j2 b/roles/hacktivism_goa/templates/etc/taler-exchange/conf.d/setup.conf.j2 @@ -0,0 +1,29 @@ +# From taler-deployment/regional-currency/setup-exchange.sh (setup.conf). +# Event currency: x-taler-bank only (do_conversion=false → no IBAN account). + +[exchange] +CURRENCY = {{ CURRENCY }} +CURRENCY_ROUND_UNIT = {{ CURRENCY_ROUND_UNIT }} +TINY_AMOUNT = {{ CURRENCY_ROUND_UNIT }} +MASTER_PUBLIC_KEY = {{ EXCHANGE_MASTER_PUB }} +BASE_URL = {{ EXCHANGE_BASE_URL }} +# Caddy on host → container tcp port (must win over package SERVE=unix) +SERVE = tcp +PORT = {{ EXCHANGE_HTTP_PORT | default(9011) }} +STEFAN_ABS = {{ CURRENCY }}:0 +STEFAN_LOG = {{ CURRENCY }}:0 +STEFAN_LIN = 0 +TERMS_ETAG = {{ EXCHANGE_TERMS_ETAG }} +PRIVACY_ETAG = {{ EXCHANGE_PP_ETAG }} +ATTRIBUTE_ENCRYPTION_KEY = {{ EXCHANGE_ATTRIBUTE_ENCRYPTION_KEY }} + +[merchant-exchange-{{ domain_name }}] +MASTER_KEY = {{ EXCHANGE_MASTER_PUB }} +CURRENCY = {{ CURRENCY }} +EXCHANGE_BASE_URL = {{ EXCHANGE_BASE_URL }} + +[exchange-account-{{ exchange_account_id }}] +PAYTO_URI = {{ EXCHANGE_BANK_ACCOUNT_PAYTO }} +ENABLE_DEBIT = YES +ENABLE_CREDIT = YES +@inline-secret@ exchange-accountcredentials-{{ exchange_account_id }} ../secrets/exchange-accountcredentials-{{ exchange_account_id }}.secret.conf diff --git a/roles/hacktivism_goa/templates/etc/taler-exchange/exchange-overrides.conf.j2 b/roles/hacktivism_goa/templates/etc/taler-exchange/exchange-overrides.conf.j2 @@ -0,0 +1,42 @@ +# hacktivism extras on top of regional-style conf.d/setup.conf +# PORT/SERVE for Caddy→9011; GOA unit names; disable demo currencies. + +[exchange] +CURRENCY = {{ CURRENCY }} +CURRENCY_ROUND_UNIT = {{ CURRENCY_ROUND_UNIT }} +TINY_AMOUNT = {{ CURRENCY_ROUND_UNIT }} +DEFAULT_P2P_EXPIRATION = 14 days +BASE_URL = {{ EXCHANGE_BASE_URL }} +SERVE = tcp +PORT = {{ EXCHANGE_HTTP_PORT | default(9011) }} +MASTER_PUBLIC_KEY = {{ EXCHANGE_MASTER_PUB }} +ATTRIBUTE_ENCRYPTION_KEY = {{ EXCHANGE_ATTRIBUTE_ENCRYPTION_KEY }} + +TERMS_DIR = ${TALER_DATA_HOME}terms/ +TERMS_ETAG = {{ EXCHANGE_TERMS_ETAG }} +PRIVACY_DIR = ${TALER_DATA_HOME}terms/ +PRIVACY_ETAG = {{ EXCHANGE_PP_ETAG }} + +[currency-goa] +ENABLED = YES +name = "GOA exploration currency" +code = GOA +fractional_input_digits = 8 +fractional_normal_digits = 0 +fractional_trailing_zero_digits = 0 +alt_unit_names_are_symbols = NO +alt_unit_names = {"24":"Yotta-GOA","21":"Zetta-GOA","18":"Exa-GOA","15":"Peta-GOA","12":"Tera-GOA","9":"Giga-GOA","6":"Mega-GOA","3":"Kilo-GOA","0":"GOA","-1":"Deci-GOA","-2":"Centi-GOA","-3":"Milli-GOA","-6":"Micro-GOA","-7":"Deci-Micro-GOA","-8":"Atomic-GOA"} +common_amounts = "GOA:10 GOA:20 GOA:50 GOA:100 GOA:200 GOA:1000" + +[currency-kudos] +ENABLED = NO + +[currency-testkudos] +ENABLED = NO + +# Account also in conf.d/setup.conf (regional); keep here for live-compat / last-wins safety. +[exchange-account-{{ exchange_account_id }}] +PAYTO_URI = {{ EXCHANGE_BANK_ACCOUNT_PAYTO }} +ENABLE_CREDIT = YES +ENABLE_DEBIT = YES +@inline-secret@ exchange-accountcredentials-{{ exchange_account_id }} ../secrets/exchange-accountcredentials-{{ exchange_account_id }}.secret.conf diff --git a/roles/hacktivism_goa/templates/etc/taler-exchange/secrets/exchange-accountcredentials.secret.conf.j2 b/roles/hacktivism_goa/templates/etc/taler-exchange/secrets/exchange-accountcredentials.secret.conf.j2 @@ -0,0 +1,5 @@ +# regional-currency/setup-exchange.sh accountcredentials pattern +[exchange-accountcredentials-{{ exchange_account_id }}] +WIRE_GATEWAY_URL = {{ EXCHANGE_WIRE_GATEWAY_URL }} +WIRE_GATEWAY_AUTH_METHOD = bearer +TOKEN = {{ EXCHANGE_WIRE_GATEWAY_TOKEN }} diff --git a/run-container-koopa.sh b/run-container-koopa.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Recreate taler-hacktivism-exchange-ansible with systemd (regional-currency style). +# Image: Containerfile (debian + systemd + ssh). Port: only 9011. +# Ansible: ansible_connection=podman → systemctl inside container. +set -euo pipefail + +NAME=taler-hacktivism-exchange-ansible +IMAGE=localhost/taler-hacktivism-exchange-ansible:base +ROOT="$(cd "$(dirname "$0")" && pwd)" + +cd "$ROOT" +podman build -f Containerfile -t "$IMAGE" + +echo "Stopping/removing existing $NAME (if any)..." +podman rm -f "$NAME" 2>/dev/null || true + +podman run -d \ + --name "$NAME" \ + --hostname "$NAME" \ + --network pasta \ + --systemd=always \ + -p 9011:9011 \ + --label org.hacktivism.service=taler-exchange \ + --label org.hacktivism.host_port=9011 \ + --label org.hacktivism.site=exchange.hacktivism.ch \ + --label org.hacktivism.currency=GOA \ + --label org.hacktivism.managed_by=ansible-taler-exchange \ + --label org.hacktivism.init=systemd \ + "$IMAGE" \ + /usr/sbin/init + +echo "waiting for systemd..." +for i in $(seq 1 30); do + if podman exec "$NAME" systemctl is-system-running 2>/dev/null | grep -Eq 'running|degraded'; then + break + fi + sleep 1 +done + +podman ps --filter "name=$NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}\t{{.Image}}" +echo -n "PID1: " +podman exec "$NAME" cat /proc/1/comm +echo -n "systemd: " +podman exec "$NAME" systemctl is-system-running || true +echo "Next: ./deploy-hacktivism-goa.sh"