gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-deployment] branch master updated: taler-local: arranging code, c


From: gnunet
Subject: [taler-deployment] branch master updated: taler-local: arranging code, check state before starting
Date: Mon, 27 Sep 2021 18:15:38 +0200

This is an automated email from the git hooks/post-receive script.

ms pushed a commit to branch master
in repository deployment.

The following commit(s) were added to refs/heads/master by this push:
     new 1a41de4  taler-local: arranging code, check state before starting
1a41de4 is described below

commit 1a41de419330ab450ff524583eebe758a3b39672
Author: ms <ms@taler.net>
AuthorDate: Mon Sep 27 18:15:30 2021 +0200

    taler-local: arranging code, check state before starting
---
 bin/WIP/taler-local | 620 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 365 insertions(+), 255 deletions(-)

diff --git a/bin/WIP/taler-local b/bin/WIP/taler-local
index af7d633..6bfcbca 100755
--- a/bin/WIP/taler-local
+++ b/bin/WIP/taler-local
@@ -15,6 +15,8 @@
 # You should have received a copy of the GNU General Public License
 # along with GNU Taler.  If not, see <https://www.gnu.org/licenses/>.
 
+import signal
+import socket
 import shutil
 import atexit
 import click
@@ -35,7 +37,7 @@ from shutil import copy
 from multiprocessing import Process
 from string import ascii_letters, ascii_uppercase
 from sys import exit
-from urllib.parse import urljoin
+from urllib.parse import urljoin, quote
 from os import remove
 import requests
 from collections import OrderedDict
@@ -48,6 +50,12 @@ from flask import Flask, request, Response
 from werkzeug.datastructures import Headers
 from werkzeug.exceptions import HTTPException
 
+
+TALER_ROOT_DIR = Path.home() / ".taler"
+# Print No Newline.
+def print_nn(msg):
+    print(msg, end="")
+
 @dataclass
 class Repo:
     name: str
@@ -295,7 +303,7 @@ repos = {
 }
 
 def get_repos_names() -> List[str]:
-    r_dir = Path.home() / ".taler-sources"
+    r_dir = TALER_ROOT_DIR / "sources"
     return [el for el in listdir(r_dir) if isdir(join(r_dir, el)) and 
repos.get(el)]
 
 # Get the installed repositories from the sources directory.
@@ -304,7 +312,7 @@ def load_repos(reposNames) -> List[Repo]:
 
 def update_repos(repos: List[Repo]) -> None:
     for r in repos:
-        r_dir = Path.home() / ".taler-sources" / r.name
+        r_dir = TALER_ROOT_DIR / "sources" / r.name
         subprocess.run(["git", "-C", str(r_dir), "fetch"], check=True)
         res = subprocess.run(
             ["git", "-C", str(r_dir), "status", "-sb"],
@@ -322,7 +330,7 @@ def get_stale_repos(repos: List[Repo]) -> List[Repo]:
     timestamps = {}
     stale = []
     for r in repos:
-        r_dir = Path.home() / ".taler-sources" / r.name
+        r_dir = TALER_ROOT_DIR / "sources" / r.name
         s = r_dir / "taler-buildstamp"
         if not s.exists():
             timestamps[r.name] = time.time()
@@ -367,23 +375,10 @@ def build(without_repos) -> None:
         diff = set(r.deps) - set(repos_names)
         if len(diff) > 0:
             print(f"WARNING: those dependencies are not being built: {diff}")
-        p = Path.home() / ".taler-sources" / r.name
+        p = TALER_ROOT_DIR / "sources" / r.name
         os.chdir(str(p))
         r.builder(r, p)
 
-# Download the repository.
-def checkout_repos(repos: List[Repo]):
-    if len(repos) == 0:
-        print("No repositories can be checked out.  Spelled correctly?")
-        return
-    home = Path.home()
-    sources = home / ".taler-sources"
-    for r in repos:
-        r_dir = home / ".taler-sources" / r.name
-        if not r_dir.exists():
-            r_dir.mkdir(parents=True, exist_ok=True)
-            subprocess.run(["git", "-C", str(sources), "clone", r.url], 
check=True)
-
 @cli.command()
 @click.option(
     "--repos", "-r",
@@ -395,20 +390,50 @@ def checkout_repos(repos: List[Repo]):
 def bootstrap(repos) -> None:
 
     """Clone all the specified repositories."""
-    home = Path.home()
+
+    # Download the repository.
+    def checkout_repos(repos: List[Repo]):
+        if len(repos) == 0:
+            print("No repositories can be checked out.  Spelled correctly?")
+            return
+        sources = TALER_ROOT_DIR / "sources"
+        for r in repos:
+            r_dir = sources / r.name
+            if not r_dir.exists():
+                r_dir.mkdir(parents=True, exist_ok=True)
+                subprocess.run(["git", "-C", str(sources), "clone", r.url], 
check=True)
+
     reposList = split_repos_list(repos)    
     checkout_repos(load_repos(reposList))
 
 class TalerReverseProxy(Flask):
+    def __init__(self, log_dir, unix_sockets_dir):
+        super().__init__("taler-proxy")
+        all_methods = [
+            "GET", "POST", "HEAD",
+            "DELETE", "OPTIONS", "PUT"
+        ]
+        self.log_dir = log_dir
+        self.unix_sockets_dir = unix_sockets_dir
+        self.add_url_rule("/", view_func=self.index)
+        self.add_url_rule("/<component>", view_func=self.proxy, 
methods=all_methods)
+        self.add_url_rule("/<component>/", view_func=self.proxy, 
methods=all_methods)
+        self.add_url_rule("/<component>/<path:path>", view_func=self.proxy, 
methods=all_methods)
+
     def stop(self):
         self.proc.terminate()
         self.proc.join()
         del os.environ["WERKZEUG_RUN_MAIN"]
 
+    def get_log_filename(self):
+        return self.logger.handlers[0].baseFilename
+
     def start(self):
-        logging.basicConfig(filename="/tmp/reverse-proxy.log", filemode="a")
-        logger = logging.getLogger("werkzeug")
-        logger.setLevel(logging.DEBUG)
+        if not self.log_dir.is_dir():
+            os.makedirs(self.log_dir)
+        logging.basicConfig(filename=self.log_dir / "reverse-proxy.log", 
filemode="a")
+        self.logger = logging.getLogger("werkzeug")
+        self.logger.setLevel(logging.DEBUG)
         self.proc = Process(
             target=self.run,
             kwargs=dict(debug=False, port=8080, host="localhost")
@@ -424,7 +449,8 @@ class TalerReverseProxy(Flask):
         logger = logging.getLogger("werkzeug")
         logger.setLevel(logging.DEBUG)
         s = Session()
-        uri = f"http+unix://%2Ftmp%2F{component}.sock/{path}"
+        sockets_dir_urlenc = quote(str(self.unix_sockets_dir), safe="")
+        uri = f"http+unix://%2F{sockets_dir_urlenc}%2F{component}.sock/{path}"
         raw_data = request.get_data()
         if len(request.args) > 0:
             uri += f"?{request.query_string.decode()}"
@@ -455,17 +481,6 @@ class TalerReverseProxy(Flask):
     def get_app(self):
         return self
 
-    def __init__(self):
-        super().__init__("taler-proxy")
-        all_methods = [
-            "GET", "POST", "HEAD",
-            "DELETE", "OPTIONS", "PUT"
-        ]
-        self.add_url_rule("/", view_func=self.index)
-        self.add_url_rule("/<component>", view_func=self.proxy, 
methods=all_methods)
-        self.add_url_rule("/<component>/", view_func=self.proxy, 
methods=all_methods)
-        self.add_url_rule("/<component>/<path:path>", view_func=self.proxy, 
methods=all_methods)
-
 @cli.command()
 def prepare():
 
@@ -474,69 +489,12 @@ def prepare():
     def fail(reason=None):
         if reason:
             print("ERROR: " + reason)
-        print("See logs in /tmp/$component.log")
         exit(1)
-
-    # Print No Newline.
-    def print_nn(msg):
-        print(msg, end="")
-    
-    # Runs a command synchronously.
-    def cmd(
-            args, env=os.environ,
-            custom_name=None, return_stdout=False
-    ):
-        handle = launch(
-            args, env=env,
-            custom_name=custom_name,
-            return_stdout=return_stdout
-        )
-        return_code = handle.wait()
-        if return_code != 0:
-            print("\nCommand: " + " ".join(args) + " failed, return code: " + 
str(return_code))
-            name = custom_name if custom_name else args[0]
-            print(f"See logs in /tmp/{name}.log")
-            exit(return_code)
-        return handle
     
     def kill(proc):
         proc.terminate()
         proc.wait()
-    
-    # Runs a command in the background.
-    def launch(cmd, env=os.environ, custom_name=None, return_stdout=False):
-        name = custom_name if custom_name else cmd[0]
-        log_file = open(f"/tmp/{name}.log", "a+")
-        try:
-            handle = Popen(
-                cmd,
-                stdin=DEVNULL,
-                stdout=log_file if not return_stdout else PIPE,
-                stderr=log_file,
-                env=env
-            )
-        except Exception as error:
-            fail(f"Could not launch: {name}: {error}")
-        atexit.register(lambda: kill(handle))
-        return handle
-    
-    def check_running(check_url):
-        for i in range(10):
-            print_nn(".")
-            try:
-                # Raises if the service is not reachable.
-                response = requests.get(check_url)
-                # Raises if the request gets a non 200 OK.
-                response.raise_for_status()
-            except:
-                if i == 9:
-                    print("FAIL")
-                    return False
-                time.sleep(0.5)
-                continue
-            break
-        return True
-    
+
     def get_nexus_cli_env(
         username, password,
         nexus_url
@@ -571,7 +529,7 @@ def prepare():
         env
     ):
         # make connection
-        cmd(
+        Command(
             [
                 "libeufin-cli", "connections",
                 "new-ebics-connection",
@@ -582,25 +540,26 @@ def prepare():
                 bank_connection_name
             ],
             env
-        )
+        ).run()
+
         # connect
-        cmd(
+        Command(
             [
                 "libeufin-cli", "connections",
                 "connect", bank_connection_name
             ],
             env
-        )
+        ).run()
         # Import bank account
-        cmd(
+        Command(
             [
                 "libeufin-cli", "connections",
                 "download-bank-accounts",
                 bank_connection_name
             ],
             env
-        )
-        cmd(
+        ).run()
+        Command(
             [
                 "libeufin-cli", "connections",
                 "import-bank-account",
@@ -611,9 +570,9 @@ def prepare():
                 bank_connection_name
             ],
             env
-        )
+        ).run()
         # Set background tasks.
-        cmd(
+        Command(
             [
                 "libeufin-cli", "accounts",
                 "task-schedule", bank_account_name_nexus,
@@ -622,8 +581,8 @@ def prepare():
                 "--task-cronspec", "* * *"
             ],
             env
-        )
-        cmd(
+        ).run()
+        Command(
             [
                 "libeufin-cli", "accounts",
                 "task-schedule", bank_account_name_nexus,
@@ -634,7 +593,7 @@ def prepare():
                 "--task-param-range-type", "latest"
             ],
             env
-        )
+        ).run()
     
     def prepare_sandbox_account(
         currency,
@@ -647,7 +606,7 @@ def prepare():
         bank_account_iban,
         env
     ):
-        cmd(
+        Command(
             [
                 "libeufin-cli", "sandbox",
                 "--sandbox-url", sandbox_url,
@@ -657,8 +616,8 @@ def prepare():
                 "--user-id", ebics_user_id
             ],
             env
-        )
-        cmd(
+        ).run()
+        Command(
             [
                 "libeufin-cli", "sandbox",
                 "--sandbox-url", sandbox_url,
@@ -673,8 +632,120 @@ def prepare():
                 "--currency", currency
             ],
             env
-        )
+        ).run()
+    
+    CURRENCY = "EUR"
+    WIRE_METHOD = "sepa"
+
+    # Filesystem's paths
+    CFG_OUTDIR = TALER_ROOT_DIR / "config"
+    UNIX_SOCKETS_DIR = TALER_ROOT_DIR / "sockets"
+    TALER_RUNTIME_DIR = TALER_ROOT_DIR / "runtime"
+    TALER_DATA_DIR = TALER_ROOT_DIR / "data"
+    LOG_DIR = TALER_ROOT_DIR / "logs"
     
+    # IBANs
+    IBAN_EXCHANGE = "EX00000000000000000000"
+    IBAN_MERCHANT = "ME00000000000000000001"
+    IBAN_CUSTOMER = "WA00000000000000000000"
+    
+    # Credentials / API keys
+    SANDBOX_ADMIN_USERNAME = "admin"
+    SANDBOX_ADMIN_PASSWORD = "secret"
+    EXCHANGE_NEXUS_USERNAME = "exchange-nexus-user"
+    EXCHANGE_NEXUS_PASSWORD = "exchange-nexus-password"
+    FRONTENDS_API_TOKEN = "secret:secret"
+    TALER_MERCHANT_TOKEN = "secret:secret" # same as above?
+        
+    # URLs
+    REV_PROXY = "http://localhost:8080";
+    SANDBOX_URL = REV_PROXY + "/sandbox"
+    NEXUS_URL = REV_PROXY + "/nexus"
+    
+    # EBICS
+    EBICS_HOST_ID = "ebicsDeployedHost"
+    EXCHANGE_EBICS_USER_ID = "exchangeEbicsUserId"
+    EXCHANGE_EBICS_PARTNER_ID = "exchangeEbicsPartnerId"
+    EBICS_URL = REV_PROXY + "/sandbox/ebicsweb"
+
+    # euFin
+    NEXUS_DB_FILE = "/tmp/nexus.sqlite"
+    SANDBOX_DB_FILE = "/tmp/sandbox.sqlite"
+    EXCHANGE_BANK_ACCOUNT_NEXUS = "exchange-imported-account-nexus"
+    EXCHANGE_BANK_ACCOUNT_SANDBOX = "exchange-account-sandbox"
+    EXCHANGE_BANK_CONNECTION = "exchange-ebics-connection"
+    EXCHANGE_FACADE_NAME = "exchange-taler-facade"
+
+    class Command:
+        def __init__(
+                self, cmd, env=os.environ, log_dir=LOG_DIR,
+                custom_name=None, capture_stdout=False
+            ):
+            if len(cmd) == 0:
+                fail("Could not find a command to execute")
+            self.name = custom_name if custom_name else cmd[0]
+            self.cmd = cmd
+            self.env=env
+            self.capture_stdout=capture_stdout
+            self.log_dir = log_dir
+
+        @staticmethod
+        def is_serving(check_url):
+            for i in range(10):
+                print_nn(".")
+                try:
+                    # Raises if the service is not reachable.
+                    response = requests.get(check_url)
+                    # Raises if the request gets a non 200 OK.
+                    response.raise_for_status()
+                except:
+                    if i == 9:
+                        return False
+                    time.sleep(0.5)
+                    continue
+                break
+            return True
+
+        def run(self):
+            self.do()
+            return_code = self.handle.wait()
+            if return_code != 0:
+                fail(f"Command {self.name} failed. Logs in 
{self.get_log_filename()}")
+            self.cleanup()
+            if self.capture_stdout:
+                return self.handle.communicate()[0].decode("utf-8").rstrip()
+
+        def launch(self):
+            self.do()
+            return self
+
+        def stop(self):
+            self.cleanup()
+            self.handle.terminate()
+            self.handle.wait()
+
+        def get_log_filename(self):
+            return self.log_file.name
+
+        def cleanup(self):
+            if not self.log_file.closed:
+                self.log_file.close()
+        def do(self):
+            if not self.log_dir.is_dir():
+                os.makedirs(self.log_dir)
+            self.log_file = open(self.log_dir / (self.name + ".log"), "a+")
+            try:
+                self.handle = Popen(
+                    self.cmd,
+                    stdin=DEVNULL,
+                    stdout=self.log_file if not self.capture_stdout else PIPE,
+                    stderr=self.log_file,
+                    env=self.env
+                )
+            except Exception as error:
+                fail(f"Could not launch: {self.name}: {error}")
+            atexit.register(self.stop)
+
     class ConfigFile:
         def __init__(self, filename):
             self.sections = OrderedDict()
@@ -689,8 +760,9 @@ def prepare():
             s[key] = value
     
         def cfg_write(self, outdir):
-    
             if outdir:
+                if not os.path.isdir(outdir):
+                    os.makedirs(outdir)
                 fstream = open(os.path.join(outdir, self.filename), "w")
             else:
                 fstream = open(sys.stdout)
@@ -701,14 +773,36 @@ def prepare():
                     fstream.write(key + " = " + value + "\n")
                 fstream.write("\n")
             fstream.close()
-    # Writes on disk too, like the other config_* functions.
+
+    def config_specify_master_pub(
+            filename,
+            currency,
+            exchange_master_pub
+    ):
+        Command([
+            "taler-config", "-c", filename,
+            "-s", "exchange", "-o", "master_public_key",
+            "-V", exchange_master_pub
+        ]).run()
+        Command([
+            "taler-config", "-c", filename,
+            "-s", f"merchant-exchange-{currency}",
+            "-o", "master_key",
+            "-V", exchange_master_pub
+        ]).run()
+
+    # When called, there is no exchange master pub yet.
+    # taler-exchange-offline will prouce the key _after_
+    # taler.conf is generated.  Only after that, we'll
+    # specify the master key where it is missing; namely
+    # in the merchant backend and exchange HTTP daemon sections.
     def config_main(
         filename,
         outdir,
+        unix_sockets_dir,
         currency,
         rev_proxy_url,
         wire_method,
-        exchange_master_pub,
         exchange_wire_address,
         merchant_wire_address,
         exchange_wire_gateway_username,
@@ -742,8 +836,8 @@ def prepare():
             obj.cfg_put(sec, "rsa_keysize", rsa_keysize)
     
         obj = ConfigFile("taler.conf")
-        obj.cfg_put("paths", "TALER_DATA_HOME", "${HOME}/.taler-data")
-        if not os.path.isdir(taler_runtime_dir):
+        obj.cfg_put("paths", "TALER_DATA_HOME", str(TALER_DATA_DIR))
+        if not taler_runtime_dir.is_dir():
             os.makedirs(taler_runtime_dir)
         obj.cfg_put("paths", "TALER_RUNTIME_DIR", str(taler_runtime_dir))
         obj.cfg_put("taler", "CURRENCY", currency)
@@ -751,7 +845,7 @@ def prepare():
     
         obj.cfg_put("bank", "serve", "uwsgi")
         obj.cfg_put("bank", "uwsgi_serve", "unix")
-        obj.cfg_put("bank", "uwsgi_unixpath", "/tmp/bank.sock")
+        obj.cfg_put("bank", "uwsgi_unixpath", str(unix_sockets_dir / 
"bank.sock"))
         obj.cfg_put("bank", "uwsgi_unixpath_mode", "660")
         obj.cfg_put("bank", "database", "taler")
         obj.cfg_put("bank", "max_debt", "%s:500.0" % currency)
@@ -763,27 +857,27 @@ def prepare():
     
         obj.cfg_put("donations", "serve", "uwsgi")
         obj.cfg_put("donations", "uwsgi_serve", "unix")
-        obj.cfg_put("donations", "uwsgi_unixpath", "/tmp/donations.sock")
+        obj.cfg_put("donations", "uwsgi_unixpath", str(unix_sockets_dir / 
"DONATIONS.Sock"))
         obj.cfg_put("donations", "uwsgi_unixpath_mode", "660")
     
         obj.cfg_put("landing", "serve", "uwsgi")
         obj.cfg_put("landing", "uwsgi_serve", "unix")
-        obj.cfg_put("landing", "uwsgi_unixpath", "/tmp/landing.sock")
+        obj.cfg_put("landing", "uwsgi_unixpath", str(unix_sockets_dir / 
"landing.sock"))
         obj.cfg_put("landing", "uwsgi_unixpath_mode", "660")
     
         obj.cfg_put("blog", "serve", "uwsgi")
         obj.cfg_put("blog", "uwsgi_serve", "unix")
-        obj.cfg_put("blog", "uwsgi_unixpath", "/tmp/blog.sock")
+        obj.cfg_put("blog", "uwsgi_unixpath", str(unix_sockets_dir / 
"blog.sock"))
         obj.cfg_put("blog", "uwsgi_unixpath_mode", "660")
     
         obj.cfg_put("survey", "serve", "uwsgi")
         obj.cfg_put("survey", "uwsgi_serve", "unix")
-        obj.cfg_put("survey", "uwsgi_unixpath", "/tmp/survey.sock")
+        obj.cfg_put("survey", "uwsgi_unixpath", str(unix_sockets_dir / 
"survey.sock"))
         obj.cfg_put("survey", "uwsgi_unixpath_mode", "660")
         obj.cfg_put("survey", "bank_password", "x")
     
         obj.cfg_put("merchant", "serve", "unix")
-        obj.cfg_put("merchant", "unixpath", "/tmp/merchant-backend.sock")
+        obj.cfg_put("merchant", "unixpath", str(unix_sockets_dir / 
"merchant-backend.sock"))
         obj.cfg_put("merchant", "wire_transfer_delay", "0 s")
         obj.cfg_put("merchant", "default_max_wire_fee", currency + ":" + 
"0.01")
         obj.cfg_put("merchant", "default_max_deposit_fee", currency + ":" + 
"0.05")
@@ -794,35 +888,34 @@ def prepare():
             "merchant-exchange-{}".format(currency),
             "exchange_base_url", rev_proxy_url + "/exchange/",
         )
-        obj.cfg_put(
-            "merchant-exchange-{}".format(currency),
-            "master_key", exchange_master_pub,
-        )
-    
         obj.cfg_put("auditor", "serve", "unix")
         # FIXME: both below used?
         obj.cfg_put("auditor", "base_url", rev_proxy_url + "/auditor")
         obj.cfg_put("auditor", "auditor_url", rev_proxy_url + "/auditor")
-        obj.cfg_put("auditor", "unixpath", "/tmp/auditor.sock")
+        obj.cfg_put("auditor", "unixpath", str(unix_sockets_dir / 
"auditor.sock"))
         obj.cfg_put("auditor", "tiny_amount", currency + ":0.01")
     
-        obj.cfg_put("taler-exchange-secmod-eddsa", "unixpath", 
"/tmp/exchange-secmod-eddsa.sock")
-        obj.cfg_put("taler-exchange-secmod-rsa", "unixpath", 
"/tmp/exchange-secmod-rsa.sock")
+        obj.cfg_put(
+            "taler-exchange-secmod-eddsa",
+            "unixpath",
+            str(unix_sockets_dir / "exchange-secmod-eddsa.sock")
+        )
+        obj.cfg_put(
+            "taler-exchange-secmod-rsa",
+            "unixpath",
+            str(unix_sockets_dir / "exchange-secmod-rsa.sock")
+        )
         obj.cfg_put("taler-exchange-secmod-rsa", "sm_priv_key",
-                    
"/tmp/.taler-data/taler-exchange-secmod-rsa/secmod-private-key"
+                    
"${TALER_DATA_HOME}/taler-exchange-secmod-rsa/secmod-private-key"
         )
         obj.cfg_put("exchange", "base_url", rev_proxy_url + "/exchange/")
-        obj.cfg_put("exchange", "master_public_key", exchange_master_pub)
-    
         obj.cfg_put("exchange", "serve", "unix")
-        obj.cfg_put("exchange", "unixpath", "/tmp/exchange.sock")
-    
+        obj.cfg_put("exchange", "unixpath", str(unix_sockets_dir / 
"exchange.sock"))
         obj.cfg_put("exchange", "terms_etag", "0")
         obj.cfg_put("exchange", "terms_dir", 
"$HOME/.local/share/taler-exchange/tos")
         obj.cfg_put("exchange", "privacy_etag", "0")
         obj.cfg_put("exchange", "privacy_dir", 
"$HOME/.local/share/taler-exchange/pp")
     
-    
         obj.cfg_put("exchangedb-postgres", "db_conn_str", "postgres:///taler")
         obj.cfg_put("exchangedb-postgres", "config", "postgres:///taler")
         obj.cfg_put("auditordb-postgres", "db_conn_str", "postgres:///taler")
@@ -854,11 +947,11 @@ def prepare():
         obj.cfg_write(outdir)
         return obj
     
-    def config_sync(filename, outdir, currency, api_key, rev_proxy_url):
+    def config_sync(filename, outdir, unix_sockets_dir, currency, api_key, 
rev_proxy_url):
         obj = ConfigFile(filename)
         obj.cfg_put("taler", "currency", currency)
         obj.cfg_put("sync", "serve", "unix")
-        obj.cfg_put("sync", "unixpath", "$HOME/sockets/sync.http")
+        obj.cfg_put("sync", "unixpath", str(unix_sockets_dir / "sync.sock"))
         obj.cfg_put("sync", "apikey", f"Bearer {api_key}")
         obj.cfg_put("sync", "annual_fee", f"{currency}:0.1")
         obj.cfg_put("sync", "fulfillment_url", "taler://fulfillment-success/")
@@ -866,12 +959,12 @@ def prepare():
         obj.cfg_put("syncdb-postgres", "config", f"postgres:///taler")
         obj.cfg_write(outdir)
     
-    def config_anastasis(filename, outdir, currency, rev_proxy_url, api_key):
+    def config_anastasis(filename, outdir, unix_sockets_dir, currency, 
rev_proxy_url, api_key):
         obj = ConfigFile(filename)
         obj.cfg_put("taler", "currency", currency)
         obj.cfg_put("anastasis", "serve", "unix")
         obj.cfg_put("anastasis", "business_name", f"GNU Taler Demo Anastasis 
Provider")
-        obj.cfg_put("anastasis", "unixpath", "/tmp/anastasis.sock")
+        obj.cfg_put("anastasis", "unixpath", str(unix_sockets_dir / 
"anastasis.sock"))
         obj.cfg_put("anastasis", "annual_fee", f"{currency}:0")
         obj.cfg_put("anastasis", "question_cost", f"{currency}:0")
         obj.cfg_put("anastasis", "insurance", f"{currency}:0")
@@ -887,68 +980,35 @@ def prepare():
         obj.cfg_put("authorization-question", "cost", f"{currency}:0")
         obj.cfg_put("authorization-question", "enabled", "yes")
         obj.cfg_write(outdir)
-
-    CURRENCY = "EUR"
-    WIRE_METHOD = "sepa"
-
-    # Directories
-    CFG_OUTDIR = Path.home() / ".config"
-    TALER_RUNTIME_DIR = Path.home() / ".taler-runtime"
-    TALER_DATA_DIR = Path.home() / ".taler-data"
-    
-    # IBANs
-    IBAN_EXCHANGE = "EX00000000000000000000"
-    IBAN_MERCHANT = "ME00000000000000000001"
-    IBAN_CUSTOMER = "WA00000000000000000000"
-    
-    # Credentials / API keys
-    SANDBOX_ADMIN_USERNAME = "admin"
-    SANDBOX_ADMIN_PASSWORD = "secret"
-    EXCHANGE_NEXUS_USERNAME = "exchange-nexus-user"
-    EXCHANGE_NEXUS_PASSWORD = "exchange-nexus-password"
-    FRONTENDS_API_TOKEN = "secret:secret"
-    TALER_MERCHANT_TOKEN = "secret:secret" # same as above?
         
-    # URLs
-    REV_PROXY = "http://localhost:8080";
-    SANDBOX_URL = REV_PROXY + "/sandbox"
-    NEXUS_URL = REV_PROXY + "/nexus"
-    
-    # EBICS
-    EBICS_HOST_ID = "ebicsDeployedHost"
-    EXCHANGE_EBICS_USER_ID = "exchangeEbicsUserId"
-    EXCHANGE_EBICS_PARTNER_ID = "exchangeEbicsPartnerId"
-    EBICS_URL = REV_PROXY + "/sandbox/ebicsweb"
+    print_nn("Ensure no service is running...")
+    if Command.is_serving(REV_PROXY + "/"):
+        fail("Reverse proxy is unexpectedly running!")
+    if UNIX_SOCKETS_DIR.is_dir():
+        for left_socket in os.listdir(UNIX_SOCKETS_DIR):
+            s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+            socket_file = str(UNIX_SOCKETS_DIR / left_socket)
+            if s.connect_ex(socket_file.encode("utf-8")) == 0:
+                fail(f"A service is unexpectedly running and bound to 
{socket_file}!")
+    print(" OK")
 
-    # euFin
-    NEXUS_DB_FILE = "/tmp/nexus.sqlite"
-    SANDBOX_DB_FILE = "/tmp/sandbox.sqlite"
-    EXCHANGE_BANK_ACCOUNT_NEXUS = "exchange-imported-account-nexus"
-    EXCHANGE_BANK_ACCOUNT_SANDBOX = "exchange-account-sandbox"
-    EXCHANGE_BANK_CONNECTION = "exchange-ebics-connection"
-    EXCHANGE_FACADE_NAME = "exchange-taler-facade"
-    
-    print_nn("Remove stale data..")
+    print_nn("Remove stale data and config...")
     if TALER_DATA_DIR.exists():
         shutil.rmtree(TALER_DATA_DIR)
     if TALER_RUNTIME_DIR.exists():
         shutil.rmtree(TALER_RUNTIME_DIR)
+    if CFG_OUTDIR.exists():
+        shutil.rmtree(CFG_OUTDIR)
     print(" OK")
-    print_nn("Generate exchange's master key...")
-    res = cmd(
-        ["taler-exchange-offline", "setup"],
-        return_stdout=True
-    )
-    EXCHANGE_MASTER_PUB = res.communicate()[0].decode("utf-8").rstrip()
-    print(" OK")
-    
+
+    print_nn("Generate preliminary taler.conf...")
     mc = config_main(
         "taler.conf",
         outdir=CFG_OUTDIR,
+        unix_sockets_dir=UNIX_SOCKETS_DIR,
         currency=CURRENCY,
         rev_proxy_url=REV_PROXY,
         wire_method=WIRE_METHOD,
-        exchange_master_pub=EXCHANGE_MASTER_PUB,
         exchange_wire_address=IBAN_EXCHANGE,
         merchant_wire_address=IBAN_MERCHANT,
         exchange_wire_gateway_username=EXCHANGE_NEXUS_USERNAME,
@@ -956,65 +1016,104 @@ def prepare():
         frontend_api_key=FRONTENDS_API_TOKEN,
         taler_runtime_dir=TALER_RUNTIME_DIR
     )
+    print(" OK")
+    print_nn("Generate exchange's master key...")
+    EXCHANGE_MASTER_PUB = Command(
+        [
+            "taler-exchange-offline",
+            "-c", CFG_OUTDIR / "taler.conf",
+            "setup"
+        ],
+        capture_stdout=True
+    ).run()
+    print(" OK")
+    print_nn("Specify exchange master pub in taler.conf...")
+    config_specify_master_pub(
+        CFG_OUTDIR / "taler.conf",
+        CURRENCY,
+        EXCHANGE_MASTER_PUB
+    )
+    print(" OK")
+    print_nn("Generating sync.conf...")
     config_sync(
         "sync.conf",
         outdir=CFG_OUTDIR,
+        unix_sockets_dir=UNIX_SOCKETS_DIR,
         currency=CURRENCY,
         api_key=FRONTENDS_API_TOKEN,
         rev_proxy_url=REV_PROXY
     )
+    print(" OK")
+    print_nn("Generating anastasis.conf...")
     config_anastasis(
         "anastasis.conf",
         outdir=CFG_OUTDIR,
+        unix_sockets_dir=UNIX_SOCKETS_DIR,
         currency=CURRENCY,
         rev_proxy_url=REV_PROXY,
         api_key=FRONTENDS_API_TOKEN
     )
-    
-    print_nn("Reset and init exchange DB..")
-    cmd(["taler-exchange-dbinit", "--reset"])
     print(" OK")
-    
-    print_nn("Remove previous key and data files..")
-    cmd(
-        ["rm", "-fr", Path.home() / ".taler-data" / "*"],
-        custom_name="remove-taler-data"
-    )
+    print_nn("Reset and init exchange DB..")
+    Command([
+        "taler-exchange-dbinit",
+        "-c", CFG_OUTDIR / "taler.conf",
+        "--reset"]
+    ).run()
     print(" OK")
-
     print_nn("Launching the reverse proxy...")
-    rev_proxy = TalerReverseProxy()
+    rev_proxy = TalerReverseProxy(LOG_DIR, UNIX_SOCKETS_DIR)
     rev_proxy.start()
-    if not check_running(REV_PROXY + "/"):
-        fail("Reverse proxy did not start correctly.")
+    if not Command.is_serving(REV_PROXY + "/"):
+        fail(f"Reverse proxy did not start correctly.  \
+Logs: {rev_proxy.get_log_filename()}"
+        )
     # Do check.
     print(" OK")
     print_nn("Launching the exchange RSA helper...")
-    exchange_rsa_handle = launch(["taler-exchange-secmod-rsa"])
+    exchange_rsa_handle = Command([
+        "taler-exchange-secmod-rsa",
+        "-c", CFG_OUTDIR / "taler.conf"
+    ]).launch()
     print(" OK")
     print_nn("Launching the exchange EDDSA helper...")
-    exchange_eddsa_handle = launch(["taler-exchange-secmod-eddsa"])
+    exchange_eddsa_handle = Command([
+        "taler-exchange-secmod-eddsa",
+        "-c", CFG_OUTDIR / "taler.conf"
+    ]).launch()
     print(" OK")
     print_nn("Launching the exchange...")
-    exchange_handle = launch(["taler-exchange-httpd"])
-    if not check_running(REV_PROXY + "/exchange/"):
-        fail("Exchange did not start correctly.")
+    exchange_handle = Command([
+        "taler-exchange-httpd",
+        "-c", CFG_OUTDIR / "taler.conf"
+    ]).launch()
+    if not Command.is_serving(REV_PROXY + "/exchange/"):
+        fail(f"Exchange did not start correctly.  Logs: 
{exchange_handle.get_log_filename()}")
     print(" OK")
     print_nn("exchange-offline: signing key material...")
-    cmd(["taler-exchange-offline", "download", "sign", "upload"])
+    Command([
+        "taler-exchange-offline",
+        "-c", CFG_OUTDIR / "taler.conf",
+        "download", "sign", "upload"
+    ]).run()
     print(" OK")
     PAYTO_URI=mc.sections["exchange-account-1"]["payto_uri"]
     print_nn(f"exchange-offline: enabling {PAYTO_URI}...")
-    cmd(["taler-exchange-offline", "enable-account", PAYTO_URI, "upload"])
+    Command([
+        "taler-exchange-offline",
+        "-c", CFG_OUTDIR / "taler.conf",
+        "enable-account", PAYTO_URI, "upload"]
+    ).run()
     print(" OK") 
     # Set up wire fees for next 5 years
     NOW = datetime.now()
     YEAR = NOW.year
     print_nn("Setting wire fees for the next 5 years...")
     for year in range(YEAR, YEAR+5):
-        cmd(
+        Command(
             [
                 "taler-exchange-offline",
+                "-c", CFG_OUTDIR / "taler.conf",
                 "wire-fee",
                 str(year),
                 WIRE_METHOD,
@@ -1023,21 +1122,22 @@ def prepare():
                 "upload"
             ],
             custom_name="set-wire-fee"
-        )
+        ).run()
     print(" OK")
     print_nn("Stopping exchange HTTP daemon and crypto helpers...")
-    kill(exchange_rsa_handle)
-    kill(exchange_eddsa_handle)
-    kill(exchange_handle)
+    exchange_rsa_handle.stop()
+    exchange_eddsa_handle.stop()
+    exchange_handle.stop()
     print(" OK")
     print_nn("Add this exchange to the auditor...")
-    cmd(
+    Command(
         [
             "taler-auditor-exchange",
+            "-c", CFG_OUTDIR / "taler.conf",
             "-m", EXCHANGE_MASTER_PUB,
             "-u", REV_PROXY + "/exchange/"
         ],
-    )
+    ).run()
     print(" OK")
     ## Step 4:  Set up euFin
     print_nn("Resetting euFin databases...")
@@ -1050,7 +1150,7 @@ def prepare():
     print(" OK")
     
     print_nn("Create Sandbox superuser...")
-    cmd(
+    Command(
         [
             "libeufin-sandbox", "superuser",
              SANDBOX_ADMIN_USERNAME,
@@ -1058,23 +1158,26 @@ def prepare():
         ],
         custom_name="sandbox-superuser",
         env=get_sandbox_server_env(SANDBOX_DB_FILE)
-    )
+    ).run()
     print(" OK")
+    # FIXME: tested until here.  To proceed, euFin needs to
+    # bind to Unix domain sockets.
+    exit(1)
+
     print_nn("Launching Sandbox...")
-    handle_sandbox = launch(
+    sandbox_handle = Command(
         [
             "libeufin-sandbox", "serve",
-            "--with-unix-socket", "/tmp/sandbox.sock",
+            "--with-unix-socket", UNIX_SOCKETS_DIR / "sandbox.sock",
         ],
         env=get_sandbox_server_env(SANDBOX_DB_FILE)
-    )
-    if not check_running(SANDBOX_URL):
-        fail("Sandbox did not start correctly")
+    ).launch()
+    if not Command.is_serving(SANDBOX_URL):
+        fail(f"Sandbox did not start correctly.  Logs: 
{sandbox_handle.get_log_filename()}")
     print(" OK")
-    exit(22)
 
     print_nn("Make Sandbox EBICS host...")
-    cmd(
+    Command(
         [
             "libeufin-cli", "sandbox",
             "--sandbox-url", SANDBOX_URL,
@@ -1086,7 +1189,7 @@ def prepare():
             SANDBOX_ADMIN_PASSWORD
         ),
         custom_name="sandbox-create-ebicshost",
-    )
+    ).run()
     print(" OK")
     
     prepare_sandbox_account(
@@ -1132,22 +1235,22 @@ def prepare():
         )
     )
     print_nn("Make Nexus superuser ...")
-    cmd(
+    Command(
         [
             "libeufin-nexus", "superuser",
             EXCHANGE_NEXUS_USERNAME,
             "--password", EXCHANGE_NEXUS_PASSWORD
         ],
         custom_name="nexus-superuser",
-    )
+    ).run()
     print(" OK")
     print_nn("Launching Nexus...")
-    handle_nexus = launch("nexus", [
+    nexus_handle = Command("nexus", [
         "libeufin-nexus", "serve",
-        "--with-unix-socket", "/tmp/nexus.sock"
-    ])
-    if not check_running(NEXUS_URL):
-        fail("Nexus did not start correctly")
+        "--with-unix-socket", UNIX_SOCKETS_DIR / "nexus.sock"
+    ]).launch()
+    if not Command.is_serving(NEXUS_URL):
+        fail(f"Nexus did not start correctly.  Logs: 
{nexus_handle.get_log_filename()}")
     print(" OK")
     
     prepare_nexus_account(
@@ -1165,7 +1268,7 @@ def prepare():
         )
     )
     print_nn("Create Taler facade ...")
-    cmd(
+    Command(
         [
             "libeufin-cli", "facades",
             "new-taler-wire-gateway-facade",
@@ -1180,7 +1283,7 @@ def prepare():
             NEXUS_URL
         ),
         custom_name="create-taler-facade",
-    )
+    ).run()
     print(" OK")
     try:
         response = requests.get(
@@ -1197,45 +1300,52 @@ def prepare():
     FACADE_URL=response.json().get("facade")[0].get("baseUrl")
     
     print_nn("Terminating Nexus...")
-    kill(handle_nexus)
+    nexus_handle.stop()
     print(" OK")
     print_nn("Terminating Sandbox...")
-    kill(handle_sandbox)
+    sandbox_handle.stop()
     print(" OK")
     
     # Point the exchange to the facade.
-    cmd(
+    Command(
         [
-            "taler-config", "-s"
+            "taler-config", "-s",
+            "-c", CFG_OUTDIR / "taler.conf",
             f"exchange-account-credentials-1",
             "-o" "wire_gateway_url",
             "-V", FACADE_URL
         ],
         custom_name="specify-facade-url",
-    )
-    cmd(
+    ).run()
+    Command(
         [
-            "taler-config", "-s"
-            f"exchange-account-credentials-1",
+            "taler-config", "-s",
+            "-c", CFG_OUTDIR / "taler.conf",
+            "exchange-account-credentials-1",
             "-o" "username",
             "-V", EXCHANGE_NEXUS_USERNAME
         ],
         custom_name="specify-username-for-facade",
-    )
-    cmd(
+    ).run()
+    Command(
         [
-            "taler-config", "-s"
-            f"exchange-account-credentials-1",
+            "taler-config", "-s",
+            "-c", CFG_OUTDIR / "taler.conf",
+            "exchange-account-credentials-1",
             "-o" "password",
             "-V", EXCHANGE_NEXUS_PASSWORD
         ],
         custom_name="specify-password-for-facade",
-    )
+    ).run()
     
     ## Step 6: Set up merchant
     
     print_nn("Reset and init merchant database...")
-    cmd(["taler-merchant-dbinit", "--reset"])
+    Command([
+        "taler-merchant-dbinit",
+        "-c", CFG_OUTDIR / "taler.conf",
+        "--reset"
+    ]).run()
     print(" OK")
     
     def ensure_instance(
@@ -1282,12 +1392,12 @@ def prepare():
     print_nn("Start merchant (with TALER_MERCHANT_TOKEN into the env)...")
     auth_env = os.environ.copy()
     auth_env["TALER_MERCHANT_TOKEN"] = TALER_MERCHANT_TOKEN
-    merchant_handle = launch(
-        ["taler-merchant-httpd"],
+    merchant_handle = Command(
+        ["taler-merchant-httpd", "-c", CFG_OUTDIR / "taler.conf"],
         env=auth_env
-    )
-    if not check_running("/merchant-backend"):
-        fail("Merchant backend did not start correctly")
+    ).launch()
+    if not Command.is_serving(REV_PROXY + "/merchant-backend"):
+        fail(f"Merchant backend did not start correctly.  Logs: 
{merchant_handle.get_log_filename()}")
     print(" OK")
 
     ensure_instance(
@@ -1300,13 +1410,13 @@ def prepare():
         auth_token=FRONTENDS_API_TOKEN
     )
     print_nn("Stopping the merchant...")
-    kill(merchant_handle)
+    merchant_handle.stop()
     print(" OK")
     print_nn("Restarting the merchant WITHOUT the auth-token in the env...")
-    merchant_handle = launch(["taler-merchant-httpd"])
-    if not check_running("/merchant-backend"):
+    merchant_handle.launch()
+    if not Command.is_serving(REV_PROXY + "/merchant-backend"):
         # check_running logs errors already.
-        fail("Merchant backend did not start correctly")
+        fail(f"Merchant backend did not re start correctly.  Logs: 
{merchant_handle.get_log_filename()}")
     print(" OK")
     print_nn("Creating the 'donations' instance...")
     ensure_instance(

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]