\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename onboarding.info @include version.texi @settitle Notes for taler.net admins and developers @value{VERSION} @c Define a new index for options. @defcodeindex op @c Combine everything into one index (arbitrarily chosen to be the @c concept index). @syncodeindex op cp @c %**end of header @copying Howtos for taler.net admins and developers (version @value{VERSION}, @value{UPDATED}), Copyright @copyright{} 2017 INRIA @quotation Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''. @end quotation @end copying @c If your manual is published on paper by the FSF, it should include @c The standard FSF Front-Cover and Back-Cover Texts, as given in @c maintain.texi. @c @c Titlepage @c @titlepage @title Notes for taler.net admins and developers @subtitle Version @value{VERSION} @subtitle @value{UPDATED} @author Marcello Stanisci (@email{marcello@@taler.net}) @page @vskip 0pt plus 1filll @insertcopying @end titlepage @c @summarycontents @contents @ifnottex @node Top @top Notes for taler.net admins and developers @insertcopying @end ifnottex @menu * Taler.net:: Sysadmins notes for server at taler.net * Standalone deployment:: Deploy Taler in your homepage * Deployment on demo.taler.net:: Deploy Taler in a "blue/green" fashion * Testing components:: How to make and run tests. * Releases:: Releases patterns @end menu @node Taler.net @chapter Taler.net @section Landing page The 'landing' page is the first page that should be visited during a "demo session". It is statically served and hosted at @code{$USER/landing/}, where @code{$USER} is one of @code{test-@{blue,green@}} or @code{demo-@{blue,green@}}. Its source code is available at the repository: @code{git://taler.net/landing}. Before being served, the site needs to be compiled, to make the i18n content. The compilation is done in the following way: @example $ cd $ git submodule update --force --init $ AUTOMAKE="automake --foreign" autoreconf -fiv $ ./configure $ cd demo/ $ make # NOTE: the sysadmin will _hardly_ need to do this manually, as there are deployment # scripts in charge of the compilation. @end example The most interesting part of nginx's configuration that serves the landing page is the following one: @example location / @{ ... # always default to english rewrite ^/$ /en/ redirect; # explicit append of "index.html" rewrite ^/(..)/$ /$1/index.html break; ... # NOTE: /home/test/landing and /home/demo/landing # are symlinks to the currently active "blue or green" party. # Next chapters explain the "blue/green" deployment technique. root /home/<'test' or 'demo'>/landing/demo; ... @} @end example @section Git Git at @code{taler.net} is managed by @emph{gitolite}. Creation and deletion of repositories, as well as users management, is done entirely by editing the @code{gitolite.conf} file within the @code{gitolite-admin} repository. Please refer to gitolite official documentation, if more information is needed: @code{http://gitolite.com/gitolite/}. This section documents the set-up of our main server @code{taler.net}. @section Buildbot @quotation Note 'worker' and 'slave' are used interchangeably @end quotation The user running the buildbot master is @emph{containers}. The authentication credentials for the allowed users are kept in minimalistic Python module that should be installed before the Buildbot is run. The location for its content is @code{/home/containers/buildbot/taler_bb_userpass_db}; whenever a new user/pass tuple is added, simply @code{cd} in that directory and run @code{pip install .} @subsection Master To start the master, log in as @emph{containers}, and run: @example $ ~/buildbot/start.sh # To stop it, run: $ ~/buildbot/stop.sh @end example There is also a "restart" script, runnable as follows: @example $ ~/buildbot/restart.sh @end example NOTE: the following command reloads the configuration without the need to restart the bot. @example $ source ~/buildbot/venv/bin/activate $ buildbot reconfig ~/buildbot/master/ @end example @subsection Start/stop workers @cartouche @quotation Every worker is run by a dedicated user in the system, and runs in "virtualenv". The latter is installed within @code{/buildbot/venv}. The worker setup lies into @code{/buildbot/}, where @code{} has an "obvious" name, like @code{worker}, @code{slave}, @code{}, @code{} or any combination of these. The following commands show how to start and stop a worker. @example # log in as the worker user. # cwd is $HOME. # this activated the virtualenv. $ source buildbot/venv/bin/activate # this starts the worker. $ buildbot-worker start buildbot/ # this stops the worker. $ buildbot-worker stop buildbot/ @end example @end quotation @end cartouche @subsection Debug worker This worker is used to test the Buildbot and it is run by the user @code{debug-builder}. Its scheduler monitors @code{help.git}, which is the repository where debug pushes have to be done. Note that this worker might not be activated all the time, as it is not needed by any production codebase. @subsection Python linter This worker is responsible for running Python static analysis, and it is served by the user @code{linter}. @subsection Documentation worker This worker is responsible for building all the documentation on @code{https://docs.taler.net}. It is run by the user @code{docbuilder}, whose home directory must have all the repositories with documentation to be built. Namely, @subsection Demo-checks worker. This worker has the simple task of checking whether all the Web services offered under "*.demo.taler.net" are up and running. It is run by the @code{demo} user itself. @itemize @item @emph{exchange} @item @emph{merchant} @item @emph{merchant-frontend-examples} @item @emph{deployment} - because of "onboarding" documentation @item @emph{api} @end itemize @cartouche @quotation Note use the @code{--umask=022} option when creating this worker, because Buildbot gives default @code{077} umask to its processes and this makes generated files unreadable. @end quotation @end cartouche @subsection Wallet worker This worker is responsible for running wallet testcases. It is run by the @emph{containers} user. @subsection Selenium worker This worker is responsible for running the Selenium wallet test: an automatic clicker that performs the cycle withdraw-and-spend. The @emph{containers} user is also responsible for running the Selenium buildbot worker. @subsection Lcov worker The worker is implemented by the @emph{lcovslave} user and is responsible for generating the HTML showing the coverage of our tests, then available on @emph{https://lcov.taler.net}. @b{NOTE:} a Postgres "per-user" database service should always be running, as @emph{lcovslave} is deployed in a standalone environment. Start the database service in the following way: @example # Assuming you already sourced ~/activate $ taler-deployment-arm -s $ taler-deployment-arm -i taler-postgres-standalone # Stop it this way: $ taler-deployment-arm -k taler-postgres-standalone # To stop 'arm', issue: $ taler-deployment-arm -e @end example @subsection Switcher worker Taler.net uses a "blue/green" fashion to update the code it uses in demos. Practically, there are two users: @emph{test-green} and @emph{test-blue}, and only one of them is "active" at any time. Being @emph{active} means that whenever nginx receives a HTTP request for one of the Taler services (at our demo), it routes the request to either test-blue or test-green via unix domain sockets. Upon any push to any of the Taler's subprojects, this worker is responsible for building the code hosted at the inactive user and, if all tests succeed, switching the active user to the one whose code has just been compiled and tested. The worker is implemented by the @emph{testswitcher} user. This user has some additional "sudo" rights, since it has to act as @emph{test-blue}, `test-gree@emph{$1}est` user in order to accompish its task. Note that the "sudo file" is tracked in this (@emph{deployment}) repository, under the @emph{sudoers} directory. @subsection Auditor worker. This worker runs the periodic task of generating the auditing reports. It is run by the @code{auditor-slave} user. @subsection Wallet builder. TBD @subsection Selenium builder TBD @subsection Tip reserve topper This worker is also responsible to run the script which tops the tip reserve up; however, this task is triggered by a "periodic scheduler" once every 10 days. A "force build" button is also offered to run this task. @subsection Manual switch After the desired blue/green party has been compiled, it is possible to log-in as @emph{test} and run the script @code{$HOME/.ln-.sh}, in order to make @code{test-} active. @subsection Website lcov.taler.net The directory @code{/var/www/lcov.taler.net} contains the following two symlinks @itemize @item exchange --> @code{/home/lcovslave/exchange/doc/coverage} @item merchant --> @code{/home/lcovslave/merchant/doc/coverage} @end itemize The pointed locations are updated by the @emph{lcovslave}. @subsection Hooks Whenever a push occurs into one of Taler repositories, Buildbot gets notified via the Git @emph{hooks} system. We use the hook in [1]. Following a @emph{gitolite}-policy, all the hook must be committed under @code{gitolite-admin/local/hooks/repo-specific/post-receive.buildbot}, so that gitolite will copy it in the right place -- the sysadmin does @strong{not} have to manually move it. Once the hook is versioned under gitolite, every repository meant to benefit from it must get the @code{option hook.pre-receive = pre-receive.buildbot} statement from the gitolite config file. On the Buildbot side, we need to allow the hook to connect to the build master. This is done by defining a @code{PBChangeSource} class in the following way: @example cs = changes.PBChangeSource(user='tony', passwd='hey') @end example NOTE: those credentials must match the ones in the hook; change the top level variables @code{username} and @code{auth} in the hook to suit your setup. The following line will finally "activate" the hook within the build master: @example c['change_source'].append(cs) @end example From now on, every buildbot scheduler will receive notifications from @code{cs} and verify if there is a match with the @code{ChangeFilter} driving the scheduler. If there is a match, the scheduler will fire its builders up, otherwise no action is taken. [1] @url{https://github.com/buildbot/buildbot-contrib/blob/master/master/contrib/git_buildbot.py} @section Playground The playground repository (@url{https://git.taler.net/playground}) contains various experiments and tests, for example to cover APIs that are not used by the other demo merchant frontends. It also serves to test various behaviors of wallets. At present, it is only deployed on @code{test.taler.net}, but @emph{not} on @code{demo.taler.net}. @node Standalone deployment @chapter Standalone deployment This tecnique aims to set a thorough Taler installation up on a machine whose nginx configuration is configured by config files from @emph{https://git.taler.net/deployment.git/tree/etc/nginx}. This installation assumes that all the steps are run with @code{$HOME} as @code{$CWD}. The first step is to fetch the @cite{deployment} repository, which hosts all the needed scripts. @example # Adapt the repository's URL to your needs. $ git clone /var/git/deployment.git/ @end example The next step is to fetch all the codebases from all the components. @example $ ./deployment/bootstrap-standalone @end example If the previous step succeeded, a file named @code{activate} should be now in the @code{$CWD}. It contains environmental definitions for @code{$PATH} and database names. @cartouche @quotation Note Please @emph{ignore} the output from the previous script when it succeeds, which is @quotation @smallexample WARNING: enabling "trust" authentication for local connections You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb. Success. You can now start the database server using: /usr/lib/postgresql/9.5/bin/pg_ctl -D talerdb -l logfile start @end smallexample The reason is that this message is generated by Postgresql's utilities and you never need to start your database manually; it will be started by the init script that launches all the Taler processes. @end quotation @end quotation @end cartouche Now we need to compile and install all the downloaded codebases. @example # We first update `@w{`}$PATH`@w{`}, in order to make all the compilation # and configuration utilities available. $ source activate # Double check if the previous step worked: $PATH should # contain $HOME/local/bin. $ echo $PATH # Then we need to install GNUnet beforehand, as it provides the 'ARM' # utility that is used to start the database service. $ cd deployment/taler-build/ $ make gnunet-stamp # Now we can start the database, with ($CWD is irrelevant now): $ taler-deployment-arm -s $ taler-deployment-arm -i taler-postgres-standalone # Configuration file can be generated now. NOTE: this step must # be run before the main build, as some components (Python ones notably) # do require ~/.config/taler.conf to exist. $ taler-deployment-config-generate # If the previous commands succeeded, then we can install all the remaining # components and run checks for them. Issue: $ taler-deployment-build @end example The following one will place signatures inside wireformat JSON files. @example $ taler-deployment-config-sign @end example The next step is to generate @cite{signkeys} and @cite{denomkeys}. Note that it will also get the denomkeys signed by the (local mock) auditor. @example $ taler-deployment-keyup @end example @cartouche @quotation Note A database error about non existent auditor-related tables might be returned while generating keys. Fix it by running: @smallexample taler-auditor -m $(taler-config -s exchange -o master_public_key) -r @end smallexample This is likely to happen after database resets, and @code{taler-auditor} is responsible for creating all auditor-related tables. @end quotation @end cartouche @c An error of "invalid currency name" might be related to the current @c policy of 12-chars limit for currency names; which is likely going to @c be changed. It may be necessary to define database tables for the exchange. The following command does that. Note that you have to manually start the database, with the following command. @example taler-deployment-arm -s taler-deployment-arm -i taler-postrges-standalone @end example @example # Erase all the data! $ taler-exchange-dbinit -r @end example As of the merchant backend, it creates tables at launch time, so it is not required to define tables before launching it. @cite{However}, if some table's definition changed over the time, and there is a need to force a redefinition of tables, then the following command accomplishes that for the merchant: @example # Erase all the data! $ taler-merchant-dbinit -r @end example If all previous steps succeeded, it is now possible to launch all the processes. That is accomplished by the following command: @example $ taler-deployment-start @end example @cartouche @quotation Note Please make sure your nginx works correctly with its configuration at @code{/etc/nginx}. @end quotation @end cartouche @node Deployment on demo.taler.net @chapter Deployment on demo.taler.net This section describes how to upgrade the whole Taler setup on the @url{taler.net} Web site. Here, the deployment scripts include a ``stable'' setup at @url{demo.taler.net} and an ``experimental'' setup at @url{test.taler.net}. This section documents the steps for moving the ``experimental'' logic to the ``stable'' site. It is mostly useful for administrators of @url{taler.net}, but given that all of the configuration files are public, it may also make a good starting point for others. @c FIXME: what does this line mean? First, make sure that the deployment @emph{AND} the deployment scripts work on the @cite{test.taler.net} deployment. For all repositories that have a separate stable branch (currently exchange.git, merchant.git, donations.git, blog.git, bank.git, landing.git) do: @example $ cd $REPO $ git pull origin master stable $ git checkout stable # option a: resolve conflicts resulting from hotfixes $ git merge master $ ... # option b: force stable to master $ git update-ref refs/heads/stable master $ git push # possibly with --force # continue development $ git checkout master @end example Log into taler.net with the account that is @emph{not} active by looking at the @cite{sockets} symlink of the @cite{demo} account. The following instructions wipe out the old deployment completely. @example $ ls -l ~demo/sockets [...] sockets -> /home/demo-green/sockets/ @end example In this case, @cite{demo-green} is the active deployment, and @cite{demo-blue} should be updated. After the update is over, the @cite{/home/demo/sockets} symlink will be pointed to @cite{demo-blue}. @example # Remove all existing files; this won't delete dot-files. $ rm -fr * $ git clone /var/git/deployment.git # Pick color depending on which one is inactive and being rebuilt. $ ./deployment/bootstrap-bluegreen demo [blue|green] # set environment appropriately $ . activate $ taler-deployment-build # (re)generate configuration $ taler-deployment-config-generate # generate signatures $ taler-deployment-config-sign # upgrade the database! this process depends on the specific # version. However, exchange and merchant have the # taler-@{exchange,merchant@}-dbinit -r command that resets all # the tables; the bank might need a tables reset too: refer to # django documentation for how to apply migrations to the database. # generate denomination keys: this is OPTIONAL, # as the keys under ~/shared-data might be okay # to use. $ taler-deployment-keyup $ taler-deployment-start # look at the logs, verify that everything is okay @end example Now the symlink can be updated. @node Testing components @chapter Testing components @c CMDs @c Traits @c Twister setup This chapter is a VERY ABSTRACT description of how testing is implemented in Taler, and in NO WAY wants to substitute the reading of the actual source code by the user. In Taler, a test case is a array of @code{struct TALER_TESTING_Command}, informally referred to as @code{CMD}, that is iteratively executed by the testing interpreter. This latter is transparently initiated by the testing library. However, the developer does not have to defined CMDs manually, but rather call the proper constructor provided by the library. For example, if a CMD is supposed to test feature @code{x}, then the library would provide the @code{TALER_TESTING_cmd_x ()} constructor for it. Obviously, each constructor has its own particular arguments that make sense to test @code{x}, and all constructor are thoroughly commented within the source code. Internally, each CMD has two methods: @code{run ()} and @code{cleanup ()}. The former contains the main logic to test feature @code{x}, whereas the latter cleans the memory up after execution. In a test life, each CMD needs some internal state, made by values it keeps in memory. Often, the test has to @emph{share} those values with other CMDs: for example, CMD1 may create some key material and CMD2 needs this key material to encrypt data. The offering of internal values from CMD1 to CMD2 is made by @emph{traits}. A trait is a @code{struct TALER_TESTING_Trait}, and each CMD contains a array of traits, that it offers via the public trait interface to other commands. The definition and filling of such array happens transparently to the test developer. For example, the following example shows how CMD2 takes an amount object offered by CMD1 via the trait interface. Note: the main interpreter and the most part of CMDs and traits are hosted inside the exchange codebase, but nothing prevents the developer from implementing new CMDs and traits within other codebases. @example /* Withouth loss of generality, let's consider the * following logic to exist inside the run() method of CMD1 */ .. struct TALER_Amount *a; /** * the second argument (0) points to the first amount object offered, * in case multiple are available. */ if (GNUNET_OK != TALER_TESTING_get_trait_amount_obj (cmd2, 0, &a)) return GNUNET_SYSERR; ... use(a); /* 'a' points straight into the internal state of CMD2 */ @end example In the Taler realm, there is also the possibility to alter the behaviour of supposedly well-behaved components. This is needed when, for example, we want the exchange to return some corrupted signature in order to check if the merchant backend detects it. This alteration is accomplished by another service called @emph{twister}. The twister acts as a proxy between service A and B, and can be programmed to tamper with the data exchanged by A and B. Please refer to the Twister codebase (under the @code{test} directory) in order to see how to configure it. @node Releases @chapter Releases @section Release Process and Checklists This document describes the process for releasing a new version of the various Taler components to the official GNU mirrors. The following components are published on the GNU mirrors @itemize @item taler-exchange (exchange.git) @item taler-merchant (merchant.git) @item talerdonations (donations.git) @item talerblog (blog.git) @item taler-bank (bank.git) @item taler-wallet-webex (wallet-webex.git) @end itemize @section Tagging Tag releases with an @b{annotated} commit, like @example git tag -a v0.1.0 -m "Official release v0.1.0" git push origin v0.1.0 @end example @section Database for tests For tests in the exchange and merchant to run, make sure that a database @emph{talertest} is accessible by @emph{$USER}. Otherwise tests involving the database logic are skipped. @section Exchange, merchant Set the version in @code{configure.ac}. The commit being tagged should be the change of the version. For the exchange test cases to pass, @code{make install} must be run first. Without it, test cases will fail because plugins can't be located. @example ./bootstrap ./configure # add required options for your system make dist tar -xf taler-$COMPONENT-$VERSION.tar.gz cd taler-$COMPONENT-$VERSION make install check @end example @section Wallet WebExtension The version of the wallet is in @emph{manifest.json}. The @code{version_name} should be adjusted, and @emph{version} should be increased independently on every upload to the WebStore. @example ./configure make dist @end example @c FIXME: selenium test cases @section Upload to GNU mirrors See @emph{https://www.gnu.org/prep/maintain/maintain.html#Automated-FTP-Uploads} Directive file: @example version: 1.2 directory: taler filename: taler-exchange-0.1.0.tar.gz @end example Upload the files in @b{binary mode} to the ftp servers. @bye