<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://agora.nasqueron.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dereckson</id>
	<title>Nasqueron Agora - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://agora.nasqueron.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dereckson"/>
	<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/Special:Contributions/Dereckson"/>
	<updated>2026-04-24T14:05:43Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.46.0-alpha</generator>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Keruald&amp;diff=2530</id>
		<title>Keruald</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Keruald&amp;diff=2530"/>
		<updated>2026-04-19T10:15:01Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Troubleshoot */ +arc unit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Keruald&#039;&#039;&#039; is a set of libraries to build PHP applications.&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ List of libraries&lt;br /&gt;
|-&lt;br /&gt;
! Package name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| keruald/omnitools || General purpose library&lt;br /&gt;
|-&lt;br /&gt;
| keruald/globalfunctions || Wrapper to replace our old old sites &amp;quot;core.php&amp;quot; by calls to omnitools&lt;br /&gt;
|-&lt;br /&gt;
| keruald/commands || Create simple CLI application&lt;br /&gt;
|-&lt;br /&gt;
| keruald/report || Reporting library&lt;br /&gt;
|-&lt;br /&gt;
| keruald/health || Site health check&lt;br /&gt;
|-&lt;br /&gt;
| keruald/dockerhub || Docker Hub, managing payload signatures&lt;br /&gt;
|-&lt;br /&gt;
| keruald/github || GitHub payloads for webhooks - managing payload signatures, class representations&lt;br /&gt;
|-&lt;br /&gt;
| keruald/mailgun || Mailgun API client&lt;br /&gt;
|-&lt;br /&gt;
| keruald/database || Database abstraction layer&lt;br /&gt;
|-&lt;br /&gt;
| keruald/broker || Wrapper around brokers like RabbitMQ&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Developer guide ==&lt;br /&gt;
=== Contribution workflow ===&lt;br /&gt;
&lt;br /&gt;
You&#039;ll find the general contribution guide at [[How to contribute code]]. Here some pointers specific for Keruald libraries.&lt;br /&gt;
&lt;br /&gt;
We use a &#039;&#039;&#039;monorepo&#039;&#039;&#039;: clone the rKERUALD repository on DevCentral, you&#039;ll find your library as a direct subdirectory on it.&lt;br /&gt;
&lt;br /&gt;
Each subdirectory matches:&lt;br /&gt;
* a resource folder, not included in packages, if starting by an underscore _ or a dot . &lt;br /&gt;
* a name of a package if starting by a letter, e.g. keruald/commands for commands/&lt;br /&gt;
&lt;br /&gt;
==== New version of a library ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;This should be automated through Jenkins.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To publish a new version of a library:&lt;br /&gt;
* Create a new tag using library/version format, e.g. foo/1.2.3&lt;br /&gt;
* Run &amp;lt;code&amp;gt;./_utils/repo/export-commits-to-manyrepo.sh foo&amp;lt;/code&amp;gt;&lt;br /&gt;
* Tag with versions the new commits in the library repository (tags propagation isn&#039;t currently automated)&lt;br /&gt;
** compare &amp;lt;code&amp;gt;git log&amp;lt;/code&amp;gt; from monorepo and library repo&lt;br /&gt;
** Add tag without any prefix in library repo, e.g. &amp;lt;code&amp;gt;git tag 1.2.3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to import an existing library? ===&lt;br /&gt;
&lt;br /&gt;
First, use [https://github.com/hraban/tomono tomono] in the PARENT DIRECTORY of the monorepo directory.&lt;br /&gt;
&lt;br /&gt;
If the name of the repository is NOT &amp;quot;core&amp;quot;, export it as MONOREPO_NAME environment variable.&lt;br /&gt;
&lt;br /&gt;
For example, to import Keruald/GitHub library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ export MONOREPO_NAME=keruald&lt;br /&gt;
$ echo &amp;quot;ssh://vcs@devcentral.nasqueron.org:5022/source/github.git github&amp;quot; | tomono --continue&lt;br /&gt;
From ssh://devcentral.nasqueron.org:5022/source/github&lt;br /&gt;
 * [new branch]      main       -&amp;gt; github/main&lt;br /&gt;
 * [new tag]         0.1.0      -&amp;gt; github/0.1.0&lt;br /&gt;
 * [new tag]         0.1.1      -&amp;gt; github/0.1.1&lt;br /&gt;
 * [new tag]         0.2.0      -&amp;gt; github/0.2.0&lt;br /&gt;
 * [new tag]         0.2.1      -&amp;gt; github/0.2.1&lt;br /&gt;
Updated 6 paths from the index&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then follow the procedure for a new library to update the monorepo metadata.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to use &amp;lt;code&amp;gt;composer dump-autoload&amp;lt;/code&amp;gt; to update your local Composer autoloader.&lt;br /&gt;
&lt;br /&gt;
=== How to create a new library? ===&lt;br /&gt;
To create a new library quux, we need a new empty manyrepo on DevCentral, a mirror on GitHub and to declare it on Packagist:&lt;br /&gt;
&lt;br /&gt;
# Declare your library in &amp;lt;code&amp;gt;metadata.yml&amp;lt;/code&amp;gt;&lt;br /&gt;
# Regenerate shared files with &amp;lt;code&amp;gt;make regenerate&amp;lt;/code&amp;gt; (you need Python and Jinja2): that will add your repository to files like phpcs.xml&lt;br /&gt;
# Create on DevCentral a new repository with a callsign starting by K for Keruald like KQUUX, and &amp;quot;quux&amp;quot; as shortname&lt;br /&gt;
# Create on GitHub a new repository called keruald/quux&lt;br /&gt;
# Publish on packagist&lt;br /&gt;
&lt;br /&gt;
If the shortname is already taken on DevCentral, it&#039;s time to create a new task to provide a map of subdirectory/package repository.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t commit anything in newly created repos but contribute as usual by creating quux/ subdirectory in the monorepo&lt;br /&gt;
&lt;br /&gt;
=== Troubleshoot ===&lt;br /&gt;
==== Run Arcanist unit tests ====&lt;br /&gt;
Before running an arc unit or arc diff command, you need to set the XDEBUG_MODE environment variable to &amp;quot;coverage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This is done automatically by the Arcanist code installed on devserver role. For local development, use arcanist with the patches from our production branch. It&#039;s available at https://github.com/nasqueron/arcanist&lt;br /&gt;
&lt;br /&gt;
==== Error: Class &amp;quot;Keruald\GitHub\XHubSignature&amp;quot; not found ====&lt;br /&gt;
When a new library is added to the repository, a new entry is added to composer.json to provide that library.&lt;br /&gt;
&lt;br /&gt;
The Composer autoloader needs then to be updated with &amp;lt;code&amp;gt;composer dump-autoload&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Annex A. IDE configuration ===&lt;br /&gt;
==== PhpStorm ====&lt;br /&gt;
&lt;br /&gt;
Clone the monorepo on your drive, then open it in PhpStorm to generate an .idea folder.&lt;br /&gt;
&lt;br /&gt;
* Edit keruald.iml with this modules content to declare the code namespaces: https://devcentral.nasqueron.org/P300&lt;br /&gt;
* For code style, you can use https://github.com/nasqueron/codestyle/blob/main/JetBrains/php-codestyle.xml&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=User:Dereckson/Devserver&amp;diff=2529</id>
		<title>User:Dereckson/Devserver</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=User:Dereckson/Devserver&amp;diff=2529"/>
		<updated>2026-04-13T12:44:02Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: Log is available per D4057&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== MediaWiki ==&lt;br /&gt;
=== Logs ===&lt;br /&gt;
tail -n 100 -f /var/log/www/dereckson.be/mediawiki-php.log&lt;br /&gt;
&lt;br /&gt;
=== Reinstall ===&lt;br /&gt;
* /var/51-wwwroot/mediawiki-dereckson/core: wikimedia/core repository&lt;br /&gt;
* /var/51-wwwroot/mediawiki-dereckson/core/extensions: symlink to &amp;lt;code&amp;gt;../extensions&amp;lt;/code&amp;gt;&lt;br /&gt;
** Clone all needed extensions in /var/51-wwwroot/mediawiki-dereckson/extensions&lt;br /&gt;
* /var/51-wwwroot/mediawiki-dereckson/core/skins: symlink to &amp;lt;code&amp;gt;../skins&amp;lt;/code&amp;gt;&lt;br /&gt;
** Same with git clone ssh://review/mediawiki/skins/&lt;br /&gt;
* /var/dataroot/mediawiki.dereckson.be/data contains:&lt;br /&gt;
** my_wiki.sqlite for the content&lt;br /&gt;
** wikicache.sqlite for the cache&lt;br /&gt;
&lt;br /&gt;
=== Update ===&lt;br /&gt;
* &#039;&#039;&#039;Core:&#039;&#039;&#039; mw-update-core (currently writing it)&lt;br /&gt;
&lt;br /&gt;
=== Create a new extension ===&lt;br /&gt;
;I. Wikimedia side&lt;br /&gt;
* [[mw:Manual:Developing_extensions]] &lt;br /&gt;
* [[mw:Gerrit/New repositories/Requests]]&lt;br /&gt;
* [https://phabricator.wikimedia.org/maniphest/task/edit/form/1/?projects=Project-Admins Create task for new Phabricator project]&lt;br /&gt;
&lt;br /&gt;
;II. WindRiver&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ setenv MW_EXTENSION foo&lt;br /&gt;
$ cd ~/dev/wikimedia/mediawiki/extensions&lt;br /&gt;
$ git clone ssh://review/mediawiki/extensions/$MW_EXTENSION || git init $MW_EXTENSION &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Extension is actually stored at /var/51-wwwroot/mediawiki-dereckson/extensions, so can immediately be configured to test locally.&lt;br /&gt;
&lt;br /&gt;
;III. SaaS deployment&lt;br /&gt;
* {{Ops file|pillar/saas/mediawiki.sls}}&lt;br /&gt;
* [https://devcentral.nasqueron.org/source/saas-mediawiki/browse/main/config/Settings.php config/Settings.php]&lt;br /&gt;
&lt;br /&gt;
=== Troubleshoot ===&lt;br /&gt;
==== SQLite database is read-only ====&lt;br /&gt;
Runtime error near line 2: attempt to write a readonly database (8)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
chown -R web-be-dereckson-mw:dereckson /var/dataroot/mediawiki.dereckson.be/data&lt;br /&gt;
chmod 771 /var/dataroot/mediawiki.dereckson.be/data&lt;br /&gt;
chmod 660 /var/dataroot/mediawiki.dereckson.be/data/my_wiki.sqlite&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Permissions to run tests and maintenance scripts ===&lt;br /&gt;
To run tests against wiki and maintenance scripts as user can be tricky:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
touch /tmp/mw-GlobalIdGenerator5001-UID-nodeid /tmp/mw-GlobalIdGenerator5001-UUID-128&lt;br /&gt;
chown web-be-dereckson-mw:dereckson /tmp/mw-GlobalIdGenerator5001-*&lt;br /&gt;
chmod 664 /tmp/mw-GlobalIdGenerator5001-*&lt;br /&gt;
&lt;br /&gt;
chmod 771 /var/dataroot/mediawiki.dereckson.be/data/locks&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zed ==&lt;br /&gt;
=== Useful paths ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Paths for Zed development&lt;br /&gt;
|-&lt;br /&gt;
! File path !! Managed by !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| /usr/local/etc/nginx/vhosts/dereckson.be/zed51.conf || Salt :: webserver-alkane&lt;br /&gt;
|-&lt;br /&gt;
| /var/51-wwwroot/zed/ || Salt :: wwwroot-51 (still to do) || Git repo: git@github.com:dereckson/zed.git&lt;br /&gt;
|-&lt;br /&gt;
| /var/dataroot/zed/content/ || Manually || Git repo: git@github.com:hypership/content.git&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
* nginx: &amp;lt;code&amp;gt;tail -n 100 -f /var/log/www/dereckson.be/zed51-error.log&amp;lt;/code&amp;gt;&lt;br /&gt;
* PHP: &amp;lt;code&amp;gt;tail -n 100 -f /var/log/www/dereckson.be/zed51-php.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Staging  ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note. Keruald is currently symlinked from the monorepo to vendor/keruald.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To recreate Zed staging area:&lt;br /&gt;
&lt;br /&gt;
    $ cd /var/dataroot/zed/content&lt;br /&gt;
    $ git init .&lt;br /&gt;
    $ git config --global --add safe.directory /var/dataroot/zed/content&lt;br /&gt;
    $ git remote add origin git@github.com:hypership/content.git&lt;br /&gt;
    $ git fetch --all&lt;br /&gt;
    $ git reset --hard origin/main&lt;br /&gt;
    $ git clone git@github.com:hypership/content_users.git users&lt;br /&gt;
    &lt;br /&gt;
    $ sudo -u web-be-dereckson-zed51 mkdir /var/dataroot/zed/cache/sessions&lt;br /&gt;
    $ sudo mkdir -p /var/dataroot/zed/content/users/_photos/tn&lt;br /&gt;
    $ sudo chown -R web-be-dereckson-zed51:dereckson /var/dataroot/zed/content/users/_photos&lt;br /&gt;
    $ sudo chmod 771 /var/dataroot/zed/content/users/_photos /var/dataroot/zed/content/users/_photos/tn&lt;br /&gt;
    &lt;br /&gt;
    $ mkdir -p /home/dereckson/dev/zed/hypership&lt;br /&gt;
    $ cd /home/dereckson/dev/zed/hypership&lt;br /&gt;
    $ ln -s /var/dataroot/zed/content&lt;br /&gt;
    &lt;br /&gt;
Note: Zed currently not defined in wwwroot-51 in rOPS, should be done for /var/51-wwwroot/zed&lt;br /&gt;
&lt;br /&gt;
== IRC ==&lt;br /&gt;
&lt;br /&gt;
=== Troubleshoot ===&lt;br /&gt;
==== Error loading module proxy/irc ====&lt;br /&gt;
When trying to load proxy module, I got:&lt;br /&gt;
&lt;br /&gt;
    22:00:09 -!- Irssi: Error loading module proxy/irc: /home/dereckson/.irssi/modules/libirc_proxy.so: Undefined symbol &amp;quot;g_input_add&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Proxy is now compiled by default, personal module needs to be deleted.&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=User:Dereckson/Devserver&amp;diff=2528</id>
		<title>User:Dereckson/Devserver</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=User:Dereckson/Devserver&amp;diff=2528"/>
		<updated>2026-04-13T12:19:27Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Zed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== MediaWiki ==&lt;br /&gt;
=== Logs ===&lt;br /&gt;
tail -n 100 -f /var/log/www/dereckson.be/mediawiki-php.log&lt;br /&gt;
&lt;br /&gt;
=== Reinstall ===&lt;br /&gt;
* /var/51-wwwroot/mediawiki-dereckson/core: wikimedia/core repository&lt;br /&gt;
* /var/51-wwwroot/mediawiki-dereckson/core/extensions: symlink to &amp;lt;code&amp;gt;../extensions&amp;lt;/code&amp;gt;&lt;br /&gt;
** Clone all needed extensions in /var/51-wwwroot/mediawiki-dereckson/extensions&lt;br /&gt;
* /var/51-wwwroot/mediawiki-dereckson/core/skins: symlink to &amp;lt;code&amp;gt;../skins&amp;lt;/code&amp;gt;&lt;br /&gt;
** Same with git clone ssh://review/mediawiki/skins/&lt;br /&gt;
* /var/dataroot/mediawiki.dereckson.be/data contains:&lt;br /&gt;
** my_wiki.sqlite for the content&lt;br /&gt;
** wikicache.sqlite for the cache&lt;br /&gt;
&lt;br /&gt;
=== Update ===&lt;br /&gt;
* &#039;&#039;&#039;Core:&#039;&#039;&#039; mw-update-core (currently writing it)&lt;br /&gt;
&lt;br /&gt;
=== Create a new extension ===&lt;br /&gt;
;I. Wikimedia side&lt;br /&gt;
* [[mw:Manual:Developing_extensions]] &lt;br /&gt;
* [[mw:Gerrit/New repositories/Requests]]&lt;br /&gt;
* [https://phabricator.wikimedia.org/maniphest/task/edit/form/1/?projects=Project-Admins Create task for new Phabricator project]&lt;br /&gt;
&lt;br /&gt;
;II. WindRiver&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ setenv MW_EXTENSION foo&lt;br /&gt;
$ cd ~/dev/wikimedia/mediawiki/extensions&lt;br /&gt;
$ git clone ssh://review/mediawiki/extensions/$MW_EXTENSION || git init $MW_EXTENSION &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Extension is actually stored at /var/51-wwwroot/mediawiki-dereckson/extensions, so can immediately be configured to test locally.&lt;br /&gt;
&lt;br /&gt;
;III. SaaS deployment&lt;br /&gt;
* {{Ops file|pillar/saas/mediawiki.sls}}&lt;br /&gt;
* [https://devcentral.nasqueron.org/source/saas-mediawiki/browse/main/config/Settings.php config/Settings.php]&lt;br /&gt;
&lt;br /&gt;
=== Troubleshoot ===&lt;br /&gt;
==== SQLite database is read-only ====&lt;br /&gt;
Runtime error near line 2: attempt to write a readonly database (8)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
chown -R web-be-dereckson-mw:dereckson /var/dataroot/mediawiki.dereckson.be/data&lt;br /&gt;
chmod 771 /var/dataroot/mediawiki.dereckson.be/data&lt;br /&gt;
chmod 660 /var/dataroot/mediawiki.dereckson.be/data/my_wiki.sqlite&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Permissions to run tests and maintenance scripts ===&lt;br /&gt;
To run tests against wiki and maintenance scripts as user can be tricky:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
touch /tmp/mw-GlobalIdGenerator5001-UID-nodeid /tmp/mw-GlobalIdGenerator5001-UUID-128&lt;br /&gt;
chown web-be-dereckson-mw:dereckson /tmp/mw-GlobalIdGenerator5001-*&lt;br /&gt;
chmod 664 /tmp/mw-GlobalIdGenerator5001-*&lt;br /&gt;
&lt;br /&gt;
chmod 771 /var/dataroot/mediawiki.dereckson.be/data/locks&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zed ==&lt;br /&gt;
=== Useful paths ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Paths for Zed development&lt;br /&gt;
|-&lt;br /&gt;
! File path !! Managed by !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| /usr/local/etc/nginx/vhosts/dereckson.be/zed51.conf || Salt :: webserver-alkane&lt;br /&gt;
|-&lt;br /&gt;
| /var/51-wwwroot/zed/ || Salt :: wwwroot-51 (still to do) || Git repo: git@github.com:dereckson/zed.git&lt;br /&gt;
|-&lt;br /&gt;
| /var/dataroot/zed/content/ || Manually || Git repo: git@github.com:hypership/content.git&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
* nginx: &amp;lt;code&amp;gt;tail -n 100 -f $LOG&amp;lt;/code&amp;gt; - still to provision, currently general one&lt;br /&gt;
* PHP: &amp;lt;code&amp;gt;tail -n 100 -f /var/log/www/dereckson.be/zed51-php.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Staging  ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note. Keruald is currently symlinked from the monorepo to vendor/keruald.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To recreate Zed staging area:&lt;br /&gt;
&lt;br /&gt;
    $ cd /var/dataroot/zed/content&lt;br /&gt;
    $ git init .&lt;br /&gt;
    $ git config --global --add safe.directory /var/dataroot/zed/content&lt;br /&gt;
    $ git remote add origin git@github.com:hypership/content.git&lt;br /&gt;
    $ git fetch --all&lt;br /&gt;
    $ git reset --hard origin/main&lt;br /&gt;
    $ git clone git@github.com:hypership/content_users.git users&lt;br /&gt;
    &lt;br /&gt;
    $ sudo -u web-be-dereckson-zed51 mkdir /var/dataroot/zed/cache/sessions&lt;br /&gt;
    $ sudo mkdir -p /var/dataroot/zed/content/users/_photos/tn&lt;br /&gt;
    $ sudo chown -R web-be-dereckson-zed51:dereckson /var/dataroot/zed/content/users/_photos&lt;br /&gt;
    $ sudo chmod 771 /var/dataroot/zed/content/users/_photos /var/dataroot/zed/content/users/_photos/tn&lt;br /&gt;
    &lt;br /&gt;
    $ mkdir -p /home/dereckson/dev/zed/hypership&lt;br /&gt;
    $ cd /home/dereckson/dev/zed/hypership&lt;br /&gt;
    $ ln -s /var/dataroot/zed/content&lt;br /&gt;
    &lt;br /&gt;
Note: Zed currently not defined in wwwroot-51 in rOPS, should be done for /var/51-wwwroot/zed&lt;br /&gt;
&lt;br /&gt;
== IRC ==&lt;br /&gt;
&lt;br /&gt;
=== Troubleshoot ===&lt;br /&gt;
==== Error loading module proxy/irc ====&lt;br /&gt;
When trying to load proxy module, I got:&lt;br /&gt;
&lt;br /&gt;
    22:00:09 -!- Irssi: Error loading module proxy/irc: /home/dereckson/.irssi/modules/libirc_proxy.so: Undefined symbol &amp;quot;g_input_add&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Proxy is now compiled by default, personal module needs to be deleted.&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Module:ProjectBox&amp;diff=2527</id>
		<title>Module:ProjectBox</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Module:ProjectBox&amp;diff=2527"/>
		<updated>2026-04-09T17:52:40Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Module:ProjectInfobox&lt;br /&gt;
-- Renders a structured infobox for a project page.&lt;br /&gt;
-- Usage: {{#invoke:ProjectInfobox|render}}&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Split a comma-separated string into a trimmed list.&lt;br /&gt;
local function splitList(value)&lt;br /&gt;
    local items = {}&lt;br /&gt;
    for item in value:gmatch(&amp;quot;[^,]+&amp;quot;) do&lt;br /&gt;
        table.insert(items, mw.text.trim(item))&lt;br /&gt;
    end&lt;br /&gt;
    return items&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Wrap a value in a table cell pair (label / value).&lt;br /&gt;
local function row(label, value)&lt;br /&gt;
    return mw.html.create(&amp;quot;tr&amp;quot;)&lt;br /&gt;
        :tag(&amp;quot;th&amp;quot;):addClass(&amp;quot;project-infobox__label&amp;quot;):wikitext(label):done()&lt;br /&gt;
        :tag(&amp;quot;td&amp;quot;):addClass(&amp;quot;project-infobox__value&amp;quot;):wikitext(value):done()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Render participants as a comma-separated inline list.&lt;br /&gt;
local function participantCell(raw)&lt;br /&gt;
    local names = splitList(raw)&lt;br /&gt;
    local linked = {}&lt;br /&gt;
    for _, name in ipairs(names) do&lt;br /&gt;
        table.insert(linked, &amp;quot;[[User:&amp;quot; .. name .. &amp;quot;|&amp;quot; .. name .. &amp;quot;]]&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return table.concat(linked, &amp;quot;, &amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.render(frame)&lt;br /&gt;
    local args = frame:getParent().args&lt;br /&gt;
&lt;br /&gt;
    local group        = mw.text.trim(args.group        or &amp;quot;&amp;quot;)&lt;br /&gt;
    local project      = mw.text.trim(args.project      or &amp;quot;&amp;quot;)&lt;br /&gt;
    local participants = mw.text.trim(args.participants or &amp;quot;&amp;quot;)&lt;br /&gt;
    local status       = mw.text.trim(args.status      or &amp;quot;&amp;quot;)&lt;br /&gt;
    local description  = mw.text.trim(args.description or &amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    local root  = mw.html.create(&amp;quot;table&amp;quot;):addClass(&amp;quot;project-infobox&amp;quot;)&lt;br /&gt;
    local tbody = root:tag(&amp;quot;tbody&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    -- Header row: project name as caption&lt;br /&gt;
    root:tag(&amp;quot;caption&amp;quot;)&lt;br /&gt;
        :addClass(&amp;quot;project-infobox__title&amp;quot;)&lt;br /&gt;
        :wikitext(project ~= &amp;quot;&amp;quot; and project or &amp;quot;Project&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if group ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        tbody:node(row(&amp;quot;Group&amp;quot;, group))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if project ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        tbody:node(row(&amp;quot;Project&amp;quot;, project))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if status ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        tbody:node(row(&amp;quot;Status&amp;quot;, status))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if participants ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        tbody:node(row(&amp;quot;Participants&amp;quot;, participantCell(participants)))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if description ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        tbody:tag(&amp;quot;tr&amp;quot;)&lt;br /&gt;
            :tag(&amp;quot;td&amp;quot;)&lt;br /&gt;
                :attr(&amp;quot;colspan&amp;quot;, &amp;quot;2&amp;quot;)&lt;br /&gt;
                :addClass(&amp;quot;project-infobox__description&amp;quot;)&lt;br /&gt;
                :wikitext(description)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return tostring(root)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Module:ProjectBox&amp;diff=2526</id>
		<title>Module:ProjectBox</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Module:ProjectBox&amp;diff=2526"/>
		<updated>2026-04-09T17:41:03Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local function renderRow(label, value)&lt;br /&gt;
    if not value or value == &amp;quot;&amp;quot; then&lt;br /&gt;
        return &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    return string.format(&lt;br /&gt;
        &#039;&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;%s&amp;lt;/th&amp;gt;&amp;lt;td&amp;gt;%s&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;,&lt;br /&gt;
        label, value&lt;br /&gt;
    )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.render(frame)&lt;br /&gt;
    local args = frame:getParent().args&lt;br /&gt;
&lt;br /&gt;
    local html = {}&lt;br /&gt;
&lt;br /&gt;
    table.insert(html, &#039;&amp;lt;table class=&amp;quot;infobox project-infobox&amp;quot;&amp;gt;&#039;)&lt;br /&gt;
&lt;br /&gt;
    -- Title&lt;br /&gt;
    if args.project and args.project ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        table.insert(html,&lt;br /&gt;
            string.format(&#039;&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;2&amp;quot; class=&amp;quot;infobox-title&amp;quot;&amp;gt;%s&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&#039;, args.project)&lt;br /&gt;
        )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Rows&lt;br /&gt;
    table.insert(html, renderRow(&amp;quot;Group&amp;quot;, args.group))&lt;br /&gt;
    table.insert(html, renderRow(&amp;quot;Participants&amp;quot;, args.participants))&lt;br /&gt;
&lt;br /&gt;
    table.insert(html, &#039;&amp;lt;/table&amp;gt;&#039;)&lt;br /&gt;
&lt;br /&gt;
    return table.concat(html, &#039;\n&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Module:ProjectBox&amp;diff=2525</id>
		<title>Module:ProjectBox</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Module:ProjectBox&amp;diff=2525"/>
		<updated>2026-04-09T17:38:42Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: Created page with &amp;quot;local p = {}  local function renderRow(label, value)     if not value or value == &amp;quot;&amp;quot; then         return &amp;quot;&amp;quot;     end     return string.format(         &amp;#039;&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;%s&amp;lt;/th&amp;gt;&amp;lt;td&amp;gt;%s&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;#039;,         label, value     ) end  function p.render(frame)     local args = frame:getParent().args      local html = {}     table.insert(html, &amp;#039;{| class=&amp;quot;infobox project-infobox&amp;quot;&amp;#039;)      -- Title (project name)     if args.project then         table.insert(html, string.format(&amp;#039;! colspan=&amp;quot;2&amp;quot; c...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local function renderRow(label, value)&lt;br /&gt;
    if not value or value == &amp;quot;&amp;quot; then&lt;br /&gt;
        return &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    return string.format(&lt;br /&gt;
        &#039;&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;%s&amp;lt;/th&amp;gt;&amp;lt;td&amp;gt;%s&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;,&lt;br /&gt;
        label, value&lt;br /&gt;
    )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.render(frame)&lt;br /&gt;
    local args = frame:getParent().args&lt;br /&gt;
&lt;br /&gt;
    local html = {}&lt;br /&gt;
    table.insert(html, &#039;{| class=&amp;quot;infobox project-infobox&amp;quot;&#039;)&lt;br /&gt;
&lt;br /&gt;
    -- Title (project name)&lt;br /&gt;
    if args.project then&lt;br /&gt;
        table.insert(html, string.format(&#039;! colspan=&amp;quot;2&amp;quot; class=&amp;quot;infobox-title&amp;quot; | %s&#039;, args.project))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    table.insert(html, &#039;|-&#039;)&lt;br /&gt;
&lt;br /&gt;
    -- Rows&lt;br /&gt;
    table.insert(html, renderRow(&amp;quot;Group&amp;quot;, args.group))&lt;br /&gt;
    table.insert(html, renderRow(&amp;quot;Participants&amp;quot;, args.participants))&lt;br /&gt;
&lt;br /&gt;
    table.insert(html, &#039;|}&#039;)&lt;br /&gt;
&lt;br /&gt;
    return table.concat(html, &#039;\n&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=User:Dereckson/Sandbox&amp;diff=2524</id>
		<title>User:Dereckson/Sandbox</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=User:Dereckson/Sandbox&amp;diff=2524"/>
		<updated>2026-04-09T17:37:22Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#invoke:ProjectBox|render&lt;br /&gt;
 | project = Some project&lt;br /&gt;
 | group = Nasqueron Operations SIG&lt;br /&gt;
 | participants = Dereckson ⬪ ptdradmin&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=User:Dereckson/Sandbox&amp;diff=2523</id>
		<title>User:Dereckson/Sandbox</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=User:Dereckson/Sandbox&amp;diff=2523"/>
		<updated>2026-04-09T17:37:10Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: Created page with &amp;quot;{{#invoke:ProjectInfobox|render  | project = Some project  | group = Nasqueron Operations SIG  | participants = Dereckson ⬪ ptdradmin }}&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#invoke:ProjectInfobox|render&lt;br /&gt;
 | project = Some project&lt;br /&gt;
 | group = Nasqueron Operations SIG&lt;br /&gt;
 | participants = Dereckson ⬪ ptdradmin&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Anubis&amp;diff=2522</id>
		<title>Operations grimoire/Anubis</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Anubis&amp;diff=2522"/>
		<updated>2026-04-09T17:30:58Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Anubis&#039;&#039;&#039; is a proxy to filter out AI scrapers requests. It will allow sites like [[Operations grimoire/DevCentral|DevCentral]] to stop to serve heavy traffic for LLM model training.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Challenges ==&lt;br /&gt;
We want to stop scraping traffic, but let legitimate traffic pass (e.g. CLI requests from Conduit).&lt;br /&gt;
&lt;br /&gt;
Anubis is used by a lot of similar software forges from open-source projects: [https://anubis.techaro.lol/docs/user/known-instances Anubis known instances], but it&#039;s unclear if someone already succeed to configure it for Phabricator.&lt;br /&gt;
&lt;br /&gt;
It&#039;s our current field of investigation by Gui and Dereckson.&lt;br /&gt;
&lt;br /&gt;
At Wikimedia, Andrew Kostka (WMDE) has some experience deploying it, apparently for Wikibase products.&lt;br /&gt;
&lt;br /&gt;
== Implementation (by Gui) ==&lt;br /&gt;
=== Isolation via UNIX Sockets ===&lt;br /&gt;
To avoid to maintain a table of TCP ports, each instance is configured to use UNIX sockets for both traffic and metrics:&lt;br /&gt;
* &#039;&#039;&#039;Main socket:&#039;&#039;&#039; &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/run/anubis/{{ instance }}.sock&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Metrics socket:&#039;&#039;&#039; &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/run/anubis/{{ instance }}-metrics.sock&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic Configuration ===&lt;br /&gt;
The Salt states resolve the target application&#039;s port from the `docker_containers` pillar. In `anubis_instances`, we define the target:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
anubis_instances:&lt;br /&gt;
  devcentral:&lt;br /&gt;
    target:&lt;br /&gt;
      service: phabricator&lt;br /&gt;
      container: devcentral&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Provisioning and Vault ===&lt;br /&gt;
Anubis API and Dashboard keys are provisioned in &#039;&#039;&#039;Vault&#039;&#039;&#039; using a helper script [scripts/fix_anubis_devcentral.sh](cci:7://file:///C:/Users/Gui%20Martinien/Downloads/operations-main/operations-main/scripts/fix_anubis_devcentral.sh:0:0-0:0) and retrieved by Salt during deployment.&lt;br /&gt;
&lt;br /&gt;
== Current work ==&lt;br /&gt;
* Gui deployed an experimental run manually on Dwellers to figure how we can build and configure Anubis&lt;br /&gt;
* Work to deploy Anubis with Salt: [https://devcentral.nasqueron.org/D3908 D3908]&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Each site must have its own Anubis instance ===&lt;br /&gt;
If you serve to protect two different domains, you need two Anubis instances, one per domain.&lt;br /&gt;
&lt;br /&gt;
In December, we noticed strange errors about challenges not found trying to fire the same instance for two different targets from the same domain.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [https://anubis.techaro.lol/ Anubis website]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Anubis&amp;diff=2521</id>
		<title>Operations grimoire/Anubis</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Anubis&amp;diff=2521"/>
		<updated>2026-04-09T17:30:21Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Isolation via UNIX Sockets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Anubis&#039;&#039;&#039; is a proxy to filter out AI scrapers requests. It will allow sites like [[Operations grimoire/DevCentral|DevCentral]] to stop to serve heavy traffic for LLM model training.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Challenges ==&lt;br /&gt;
We want to stop scraping traffic, but let legitimate traffic pass (e.g. CLI requests from Conduit).&lt;br /&gt;
&lt;br /&gt;
Anubis is used by a lot of similar software forges from open-source projects: [https://anubis.techaro.lol/docs/user/known-instances Anubis known instances], but it&#039;s unclear if someone already succeed to configure it for Phabricator.&lt;br /&gt;
&lt;br /&gt;
It&#039;s our current field of investigation by Doba Gui and Dereckson.&lt;br /&gt;
&lt;br /&gt;
At Wikimedia, Andrew Kostka (WMDE) has some experience deploying it, apparently for Wikibase products.&lt;br /&gt;
&lt;br /&gt;
== Implementation (by Doba Gui) ==&lt;br /&gt;
=== Isolation via UNIX Sockets ===&lt;br /&gt;
To avoid to maintain a table of TCP ports, each instance is configured to use UNIX sockets for both traffic and metrics:&lt;br /&gt;
* &#039;&#039;&#039;Main socket:&#039;&#039;&#039; &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/run/anubis/{{ instance }}.sock&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Metrics socket:&#039;&#039;&#039; &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/run/anubis/{{ instance }}-metrics.sock&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic Configuration ===&lt;br /&gt;
The Salt states resolve the target application&#039;s port from the `docker_containers` pillar. In `anubis_instances`, we define the target:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
anubis_instances:&lt;br /&gt;
  devcentral:&lt;br /&gt;
    target:&lt;br /&gt;
      service: phabricator&lt;br /&gt;
      container: devcentral&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Provisioning and Vault ===&lt;br /&gt;
Anubis API and Dashboard keys are provisioned in &#039;&#039;&#039;Vault&#039;&#039;&#039; using a helper script [scripts/fix_anubis_devcentral.sh](cci:7://file:///C:/Users/Gui%20Martinien/Downloads/operations-main/operations-main/scripts/fix_anubis_devcentral.sh:0:0-0:0) and retrieved by Salt during deployment.&lt;br /&gt;
&lt;br /&gt;
== Current work ==&lt;br /&gt;
* Doba deployed an experimental run manually on Dwellers to figure how we can build and configure Anubis&lt;br /&gt;
* Work to deploy Anubis with Salt: [https://devcentral.nasqueron.org/D3908 D3908]&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Each site must have its own Anubis instance ===&lt;br /&gt;
If you serve to protect two different domains, you need two Anubis instances, one per domain.&lt;br /&gt;
&lt;br /&gt;
In December, we noticed strange errors about challenges not found trying to fire the same instance for two different targets from the same domain.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [https://anubis.techaro.lol/ Anubis website]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Configuration_files&amp;diff=2519</id>
		<title>Operations grimoire/Configuration files</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Configuration_files&amp;diff=2519"/>
		<updated>2026-04-05T21:07:45Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: Draft&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists configuration files managed by our SaltStack operations repository (rOPS).&lt;br /&gt;
&lt;br /&gt;
Each file is deployed from {{Ops file|roles/}} subfolders. The &#039;&#039;&#039;Full path&#039;&#039;&#039; column shows the path relative to {{Ops file|roles/}}.&lt;br /&gt;
&lt;br /&gt;
== bastion ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| sshd-otp || SSH || {{Ops file|roles/bastion/sshd-otp/files/sshd.rc}} || [https://docs.freebsd.org/en/articles/rc-scripting/ RC scripting]&lt;br /&gt;
|-&lt;br /&gt;
| sshd-otp || SSH || {{Ops file|roles/bastion/sshd-otp/files/sshd.rc.conf}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| sshd-otp || systemd || {{Ops file|roles/bastion/sshd-otp/files/sshd.service}} || [https://www.freedesktop.org/software/systemd/man/ systemd documentation]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== core ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| certificates || syslog || {{Ops file|roles/core/certificates/files/acmesh/syslog.conf}} || [https://www.rsyslog.com/doc/ rsyslog documentation]&lt;br /&gt;
|-&lt;br /&gt;
| certificates || Certbot || {{Ops file|roles/core/certificates/files/certbot/cli.ini}} || [https://eff-certbot.readthedocs.io/en/latest/ Certbot documentation]&lt;br /&gt;
|-&lt;br /&gt;
| login || BSD login || {{Ops file|roles/core/login/files/login.conf}} || [https://man.freebsd.org/cgi/man.cgi?login.conf login.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| monitoring || Prometheus || {{Ops file|roles/core/monitoring/files/prometheus-node-exporter.env}} || [https://prometheus.io/docs/ Prometheus documentation]&lt;br /&gt;
|-&lt;br /&gt;
| monitoring || Prometheus || {{Ops file|roles/core/monitoring/files/rc/prometheus-node-exporter.conf}} || [https://prometheus.io/docs/ Prometheus documentation]&lt;br /&gt;
|-&lt;br /&gt;
| network || dhclient || {{Ops file|roles/core/network/files/FreeBSD/dhclient6.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| network || dhclient || {{Ops file|roles/core/network/files/FreeBSD/dhclient6.service}} || [https://docs.freebsd.org/en/articles/rc-scripting/ RC scripting]&lt;br /&gt;
|-&lt;br /&gt;
| network || GRE tunnels || {{Ops file|roles/core/network/files/FreeBSD/gre.conf}} || [https://man.freebsd.org/cgi/man.cgi?gre gre man page]&lt;br /&gt;
|-&lt;br /&gt;
| network || GRE tunnels || {{Ops file|roles/core/network/files/FreeBSD/netif_gre.rc}} || [https://man.freebsd.org/cgi/man.cgi?gre gre man page]&lt;br /&gt;
|-&lt;br /&gt;
| network || Network || {{Ops file|roles/core/network/files/FreeBSD/netif_ipv4.rc}} || [https://docs.freebsd.org/en/books/handbook/network/ FreeBSD Handbook - Network]&lt;br /&gt;
|-&lt;br /&gt;
| network || Network || {{Ops file|roles/core/network/files/FreeBSD/netif_ipv6.rc}} || [https://docs.freebsd.org/en/books/handbook/network/ FreeBSD Handbook - Network]&lt;br /&gt;
|-&lt;br /&gt;
| network || Routing || {{Ops file|roles/core/network/files/FreeBSD/route-drake.service}} || [https://docs.freebsd.org/en/articles/rc-scripting/ RC scripting]&lt;br /&gt;
|-&lt;br /&gt;
| network || Routing || {{Ops file|roles/core/network/files/FreeBSD/route_drake.rc}} || [https://man.freebsd.org/cgi/man.cgi?route route man page]&lt;br /&gt;
|-&lt;br /&gt;
| network || Routing || {{Ops file|roles/core/network/files/FreeBSD/router.rc}} || [https://man.freebsd.org/cgi/man.cgi?route route man page]&lt;br /&gt;
|-&lt;br /&gt;
| network || Routing || {{Ops file|roles/core/network/files/FreeBSD/routing_ipv4.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| network || Routing || {{Ops file|roles/core/network/files/FreeBSD/routing_ipv6.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| network || Routing || {{Ops file|roles/core/network/files/Linux/routes.conf}} || [https://man7.org/linux/man-pages/man8/ip-route.8.html ip-route man page]&lt;br /&gt;
|-&lt;br /&gt;
| network || Routing || {{Ops file|roles/core/network/files/Linux/routes.service}} || [https://www.freedesktop.org/software/systemd/man/ systemd documentation]&lt;br /&gt;
|-&lt;br /&gt;
| network || dhclient || {{Ops file|roles/core/network/files/dhclient6.conf}} || [https://man.freebsd.org/cgi/man.cgi?dhclient.conf dhclient.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| network || systemd || {{Ops file|roles/core/network/files/ipv6-tunnels/ipv6-tunnel.service}} || [https://www.freedesktop.org/software/systemd/man/ systemd documentation]&lt;br /&gt;
|-&lt;br /&gt;
| ntp || NTP || {{Ops file|roles/core/ntp/files/rc/ntpd.conf}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| pf || PF firewall || {{Ops file|roles/core/pf/files/pf.conf}} || [https://man.freebsd.org/cgi/man.cgi?pf.conf pf.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| pf || PF firewall || {{Ops file|roles/core/pf/files/rc/pf.conf}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| pf || pflog || {{Ops file|roles/core/pf/files/rc/pflog.conf}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| rc || locate || {{Ops file|roles/core/rc/files/locate.rc}} || [https://man.freebsd.org/cgi/man.cgi?locate.conf locate.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| rc || periodic || {{Ops file|roles/core/rc/files/periodic.conf}} || [https://man.freebsd.org/cgi/man.cgi?periodic.conf periodic.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| rsyslog || rsyslog || {{Ops file|roles/core/rsyslog/files/default.conf}} || [https://www.rsyslog.com/doc/ rsyslog documentation]&lt;br /&gt;
|-&lt;br /&gt;
| salt || Salt || {{Ops file|roles/core/salt/files/rc.conf}} || [https://docs.saltproject.io/ Salt documentation]&lt;br /&gt;
|-&lt;br /&gt;
| salt || Vault || {{Ops file|roles/core/salt/files/vault.conf}} || [https://developer.hashicorp.com/vault/docs Vault documentation]&lt;br /&gt;
|-&lt;br /&gt;
| sshd || SSH || {{Ops file|roles/core/sshd/files/rc.conf}} || [https://man.freebsd.org/cgi/man.cgi?sshd_config sshd_config man page]&lt;br /&gt;
|-&lt;br /&gt;
| sysctl || sysctl || {{Ops file|roles/core/sysctl/files/sysctl.conf}} || [https://man.freebsd.org/cgi/man.cgi?sysctl.conf sysctl.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| userland-home || nano || {{Ops file|roles/core/userland-home/files/dereckson/.nanorc}} || [https://www.nano-editor.org/dist/latest/nanorc.5.html nanorc man page]&lt;br /&gt;
|-&lt;br /&gt;
| userland-home || Zsh || {{Ops file|roles/core/userland-home/files/dereckson/.zshrc}} || [https://zsh.sourceforge.io/Doc/ Zsh documentation]&lt;br /&gt;
|-&lt;br /&gt;
| userland-home || tmux || {{Ops file|roles/core/userland-home/files/dorianwinty/.tmux.conf}} || [https://man.openbsd.org/tmux tmux man page]&lt;br /&gt;
|-&lt;br /&gt;
| userland-home || Zsh || {{Ops file|roles/core/userland-home/files/dorianwinty/.zshrc}} || [https://zsh.sourceforge.io/Doc/ Zsh documentation]&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || pkg || {{Ops file|roles/core/userland-software/files/sources/FreeBSD.conf}} || [https://man.freebsd.org/cgi/man.cgi?pkg.conf pkg.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || pkg || {{Ops file|roles/core/userland-software/files/sources/Nasqueron.conf}} || [https://man.freebsd.org/cgi/man.cgi?pkg.conf pkg.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || tmux || {{Ops file|roles/core/userland-software/files/tmux.conf}} || [https://man.openbsd.org/tmux tmux man page]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== dbserver-mysql ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| grc || grc || {{Ops file|roles/dbserver-mysql/grc/files/grcat.config}} || [https://github.com/garabik/grc grc documentation]&lt;br /&gt;
|-&lt;br /&gt;
| mysql-server || MySQL || {{Ops file|roles/dbserver-mysql/mysql-server/files/conf.d/client.cnf}} || [https://dev.mysql.com/doc/refman/en/ MySQL documentation]&lt;br /&gt;
|-&lt;br /&gt;
| mysql-server || MySQL || {{Ops file|roles/dbserver-mysql/mysql-server/files/conf.d/server.cnf}} || [https://dev.mysql.com/doc/refman/en/ MySQL documentation]&lt;br /&gt;
|-&lt;br /&gt;
| mysql-server || MySQL || {{Ops file|roles/dbserver-mysql/mysql-server/files/mysql.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| salt || Salt || {{Ops file|roles/dbserver-mysql/salt/files/mysql.conf}} || [https://docs.saltproject.io/ Salt documentation]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== dbserver-pgsql ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| server || PostgreSQL || {{Ops file|roles/dbserver-pgsql/server/files/pg_hba.conf}} || [https://www.postgresql.org/docs/current/ PostgreSQL documentation]&lt;br /&gt;
|-&lt;br /&gt;
| server || PostgreSQL || {{Ops file|roles/dbserver-pgsql/server/files/postgresql.conf}} || [https://www.postgresql.org/docs/current/ PostgreSQL documentation]&lt;br /&gt;
|-&lt;br /&gt;
| server || PostgreSQL || {{Ops file|roles/dbserver-pgsql/server/files/postgresql.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== devserver ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| api-exec || API-exec || {{Ops file|roles/devserver/api-exec/files/api-exec.conf}} || &#039;&#039;custom config, still to document&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| api-exec || API-exec || {{Ops file|roles/devserver/api-exec/files/rc/api_exec.conf}} || [https://docs.freebsd.org/en/articles/rc-scripting/ RC scripting]&lt;br /&gt;
|-&lt;br /&gt;
| mail || Sendmail || {{Ops file|roles/devserver/mail/files/sendmail.rc}} || [https://man.freebsd.org/cgi/man.cgi?sendmail sendmail man page]&lt;br /&gt;
|-&lt;br /&gt;
| pkg || pkg || {{Ops file|roles/devserver/pkg/files/nasqueron.conf}} || [https://man.freebsd.org/cgi/man.cgi?pkg.conf pkg.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| poudriere || poudriere || {{Ops file|roles/devserver/poudriere/files/poudriere.conf}} || [https://github.com/freebsd/poudriere/wiki poudriere documentation]&lt;br /&gt;
|-&lt;br /&gt;
| userland-home || Git || {{Ops file|roles/devserver/userland-home/files/dereckson/.gitconfig}} || [https://git-scm.com/docs/git-config git-config documentation]&lt;br /&gt;
|-&lt;br /&gt;
| userland-home || Mercurial || {{Ops file|roles/devserver/userland-home/files/dereckson/.hgrc}} || [https://www.mercurial-scm.org/doc/hgrc.5.html hgrc man page]&lt;br /&gt;
|-&lt;br /&gt;
| userland-home || Shell || {{Ops file|roles/devserver/userland-home/files/dereckson/.shell.yml}} || &#039;&#039;custom config, still to document&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| userland-home || tmux || {{Ops file|roles/devserver/userland-home/files/dereckson/.tmux.conf}} || [https://man.openbsd.org/tmux tmux man page]&lt;br /&gt;
|-&lt;br /&gt;
| userland-home || Zsh || {{Ops file|roles/devserver/userland-home/files/dereckson/.zshrc-misc-aliases}} || [https://zsh.sourceforge.io/Doc/ Zsh documentation]&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || ccache || {{Ops file|roles/devserver/userland-software/files/ccache.conf}} || [https://ccache.dev/manual/latest.html ccache documentation]&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || make || {{Ops file|roles/devserver/userland-software/files/make.conf}} || [https://man.freebsd.org/cgi/man.cgi?make.conf make.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || Notifications || {{Ops file|roles/devserver/userland-software/files/notifications.conf}} || &#039;&#039;custom config, still to document&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || PEFS || {{Ops file|roles/devserver/userland-software/files/pefs.conf}} || [https://wiki.freebsd.org/PEFS PEFS documentation]&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || Transmission || {{Ops file|roles/devserver/userland-software/files/transmission.rc}} || [https://github.com/transmission/transmission/blob/main/docs/Editing-Configuration-Files.md Transmission documentation]&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || URL configuration || {{Ops file|roles/devserver/userland-software/files/url.yml}} || &#039;&#039;custom config, still to document&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| webserver-home || nginx || {{Ops file|roles/devserver/webserver-home/files/001-server.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== dns ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| knot || Knot DNS || {{Ops file|roles/dns/knot/files/knot.conf}} || [https://www.knot-dns.cz/docs/ Knot DNS documentation]&lt;br /&gt;
|-&lt;br /&gt;
| knot || Knot DNS || {{Ops file|roles/dns/knot/files/rc/knot.conf}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== grafana ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| grafana || Grafana || {{Ops file|roles/grafana/grafana/files/grafana.ini}} || [https://grafana.com/docs/grafana/latest/ Grafana documentation]&lt;br /&gt;
|-&lt;br /&gt;
| grafana || Grafana || {{Ops file|roles/grafana/grafana/files/rc/grafana.conf}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== mailserver ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| dkim || OpenDKIM || {{Ops file|roles/mailserver/dkim/files/opendkim.conf}} || [http://www.opendkim.org/opendkim.conf.5.html opendkim.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| dkim || OpenDKIM || {{Ops file|roles/mailserver/dkim/files/rc/opendkim.conf}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| dovecot || Dovecot || {{Ops file|roles/mailserver/dovecot/files/conf.d/10-auth.conf}} || [https://doc.dovecot.org/ Dovecot documentation]&lt;br /&gt;
|-&lt;br /&gt;
| dovecot || Dovecot || {{Ops file|roles/mailserver/dovecot/files/conf.d/10-mail.conf}} || [https://doc.dovecot.org/ Dovecot documentation]&lt;br /&gt;
|-&lt;br /&gt;
| dovecot || Dovecot || {{Ops file|roles/mailserver/dovecot/files/conf.d/10-main-services.conf}} || [https://doc.dovecot.org/ Dovecot documentation]&lt;br /&gt;
|-&lt;br /&gt;
| dovecot || Dovecot || {{Ops file|roles/mailserver/dovecot/files/conf.d/10-metrics.conf}} || [https://doc.dovecot.org/ Dovecot documentation]&lt;br /&gt;
|-&lt;br /&gt;
| dovecot || Dovecot || {{Ops file|roles/mailserver/dovecot/files/conf.d/10-ssl.conf}} || [https://doc.dovecot.org/ Dovecot documentation]&lt;br /&gt;
|-&lt;br /&gt;
| dovecot || Dovecot || {{Ops file|roles/mailserver/dovecot/files/dovecot.conf}} || [https://doc.dovecot.org/ Dovecot documentation]&lt;br /&gt;
|-&lt;br /&gt;
| vimbadmin || ViMbAdmin || {{Ops file|roles/mailserver/vimbadmin/files/application.ini}} || [https://github.com/opensolutions/ViMbAdmin ViMbAdmin documentation]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== netbox ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| netbox || NetBox || {{Ops file|roles/netbox/netbox/files/rc/netbox.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== opensearch ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| dashboards || systemd || {{Ops file|roles/opensearch/dashboards/files/dashboards.service}} || [https://www.freedesktop.org/software/systemd/man/ systemd documentation]&lt;br /&gt;
|-&lt;br /&gt;
| opensearch || OpenSearch || {{Ops file|roles/opensearch/opensearch/files/account.conf}} || [https://opensearch.org/docs/latest/ OpenSearch documentation]&lt;br /&gt;
|-&lt;br /&gt;
| opensearch || OpenSearch || {{Ops file|roles/opensearch/opensearch/files/opensearch.conf}} || [https://opensearch.org/docs/latest/ OpenSearch documentation]&lt;br /&gt;
|-&lt;br /&gt;
| opensearch || systemd || {{Ops file|roles/opensearch/opensearch/files/opensearch.service}} || [https://www.freedesktop.org/software/systemd/man/ systemd documentation]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== paas-docker ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| containers || Docker Compose || {{Ops file|roles/paas-docker/containers/files/relay/dev.yml}} || [https://docs.docker.com/compose/ Docker Compose documentation]&lt;br /&gt;
|-&lt;br /&gt;
| containers || Sentry || {{Ops file|roles/paas-docker/containers/files/sentry/etc/config.yml}} || [https://develop.sentry.dev/self-hosted/ Sentry self-hosted documentation]&lt;br /&gt;
|-&lt;br /&gt;
| containers || Symbolicator || {{Ops file|roles/paas-docker/containers/files/symbolicator/config.yml}} || [https://getsentry.github.io/symbolicator/ Symbolicator documentation]&lt;br /&gt;
|-&lt;br /&gt;
| containers || Vault || {{Ops file|roles/paas-docker/containers/files/vault/vault.hcl}} || [https://developer.hashicorp.com/vault/docs Vault documentation]&lt;br /&gt;
|-&lt;br /&gt;
| devel || systemd || {{Ops file|roles/paas-docker/devel/files/socket.conf}} || [https://www.freedesktop.org/software/systemd/man/ systemd documentation]&lt;br /&gt;
|-&lt;br /&gt;
| kernel || tuned || {{Ops file|roles/paas-docker/kernel/files/tuned.conf}} || [https://tuned-project.org/ tuned documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || logrotate || {{Ops file|roles/paas-docker/nginx/files/logrotate/nginx.conf}} || [https://man.freebsd.org/cgi/man.cgi?logrotate logrotate man page]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/_default.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/acme_dns.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/auth-grove.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/base/fallback.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/base/server.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/bugzilla.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/cachet.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/etherpad.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/hauk.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/jenkins.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/notifications.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/openfire.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/orbeon.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/penpot_web.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/phabricator.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/pixelfed.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/rabbitmq.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/registry.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/sentry.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/tommy.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/paas-docker/nginx/files/vhosts/vault.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| systemd-timers || systemd || {{Ops file|roles/paas-docker/systemd-timers/files/report.service}} || [https://www.freedesktop.org/software/systemd/man/ systemd documentation]&lt;br /&gt;
|-&lt;br /&gt;
| systemd-timers || systemd || {{Ops file|roles/paas-docker/systemd-timers/files/report.timer}} || [https://www.freedesktop.org/software/systemd/man/ systemd documentation]&lt;br /&gt;
|-&lt;br /&gt;
| systemd-unit || systemd || {{Ops file|roles/paas-docker/systemd-unit/files/docker-containers.service}} || [https://www.freedesktop.org/software/systemd/man/ systemd documentation]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== paas-jails ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| jails || Jails || {{Ops file|roles/paas-jails/jails/files/ezjail.rc}} || [https://man.freebsd.org/cgi/man.cgi?jail jail man page]&lt;br /&gt;
|-&lt;br /&gt;
| jails || Jails || {{Ops file|roles/paas-jails/jails/files/jail.rc}} || [https://man.freebsd.org/cgi/man.cgi?jail jail man page]&lt;br /&gt;
|-&lt;br /&gt;
| jails || Network || {{Ops file|roles/paas-jails/jails/files/netif.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| jails || DNS resolver || {{Ops file|roles/paas-jails/jails/files/resolv.conf}} || [https://man.freebsd.org/cgi/man.cgi?resolv.conf resolv.conf man page]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== prometheus ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| prometheus || Prometheus || {{Ops file|roles/prometheus/prometheus/files/prometheus.yml}} || [https://prometheus.io/docs/ Prometheus documentation]&lt;br /&gt;
|-&lt;br /&gt;
| prometheus || Prometheus || {{Ops file|roles/prometheus/prometheus/files/rc/prometheus.conf}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| prometheus || newsyslog || {{Ops file|roles/prometheus/prometheus/files/syslog/newsyslog.conf}} || [https://man.freebsd.org/cgi/man.cgi?newsyslog.conf newsyslog.conf man page]&lt;br /&gt;
|-&lt;br /&gt;
| prometheus || newsyslog || {{Ops file|roles/prometheus/prometheus/files/syslog/prometheus.conf}} || [https://man.freebsd.org/cgi/man.cgi?newsyslog.conf newsyslog.conf man page]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== redis ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| server || Redis || {{Ops file|roles/redis/server/files/redis.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== reports ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| rhyne-wyse || Rhyne-Wyse || {{Ops file|roles/reports/rhyne-wyse/files/secrets.conf}} || [https://docs.nasqueron.org/secretsmith/connect.html#configuration-file secretsmith]&lt;br /&gt;
|-&lt;br /&gt;
| rhyne-wyse || Rhyne-Wyse || {{Ops file|roles/reports/rhyne-wyse/files/syslog/rhyne-wyse.conf}} || [https://man.freebsd.org/cgi/man.cgi?syslog.conf(5) syslog.conf]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== router ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| carp || CARP || {{Ops file|roles/router/carp/files/carp.conf}} || [https://man.freebsd.org/cgi/man.cgi?carp carp man page]&lt;br /&gt;
|-&lt;br /&gt;
| carp || CARP || {{Ops file|roles/router/carp/files/carp.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| carp || CARP || {{Ops file|roles/router/carp/files/secrets.conf}} || [https://docs.nasqueron.org/secretsmith/connect.html#configuration-file secretsmith]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== saas-mediawiki ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/saas-mediawiki/nginx/files/vhosts/nasqueron.org/agora.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/saas-mediawiki/nginx/files/vhosts/nasqueron.org/wikis.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/saas-mediawiki/nginx/files/vhosts/test.ook.space/mediawiki.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| saas || Environment || {{Ops file|roles/saas-mediawiki/saas/files/dot.env}} || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== salt-primary ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| api || Salt || {{Ops file|roles/salt-primary/api/files/api.conf}} || [https://docs.saltproject.io/ Salt documentation]&lt;br /&gt;
|-&lt;br /&gt;
| api || Salt || {{Ops file|roles/salt-primary/api/files/salt_api.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| config || Salt || {{Ops file|roles/salt-primary/config/files/pillar-tower.conf}} || [https://jgraichen.github.io/salt-tower/latest/tower/ salt-tower]&lt;br /&gt;
|-&lt;br /&gt;
| salt-wrapper || Salt || {{Ops file|roles/salt-primary/salt-wrapper/files/salt-wrapper.conf}} || [https://docs.nasqueron.org/salt-wrapper/admin.html#configuration-file salt-wrapper]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== shellserver ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| database || MySQL || {{Ops file|roles/shellserver/database/files/my.cnf}} || [https://dev.mysql.com/doc/refman/en/ MySQL documentation]&lt;br /&gt;
|-&lt;br /&gt;
| odderon || systemd || {{Ops file|roles/shellserver/odderon/files/odderon.service}} || [https://www.freedesktop.org/software/systemd/man/ systemd documentation]&lt;br /&gt;
|-&lt;br /&gt;
| odderon || Odderon || {{Ops file|roles/shellserver/odderon/files/servers.ini}} || [https://github.com/JiggyStardust/Odderon Odderon repository]&lt;br /&gt;
|-&lt;br /&gt;
| odderon || Odderon || {{Ops file|roles/shellserver/odderon/files/setup.ini}} || [https://github.com/JiggyStardust/Odderon Odderon repository]&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || nano || {{Ops file|roles/shellserver/userland-software/files/nanorc}} || [https://www.nano-editor.org/dist/latest/nanorc.5.html nanorc man page]&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || oidentd || {{Ops file|roles/shellserver/userland-software/files/oidentd.conf}} || [https://oidentd.janikrabe.com/doc/2.5/manual oidentd documentation]&lt;br /&gt;
|-&lt;br /&gt;
| userland-software || oidentd || {{Ops file|roles/shellserver/userland-software/files/oidentd.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| vault || Salt || {{Ops file|roles/shellserver/vault/files/salt-vault.conf}} || [https://docs.saltproject.io/ Salt documentation]&lt;br /&gt;
|-&lt;br /&gt;
| vault || Vault || {{Ops file|roles/shellserver/vault/files/salt.hcl}} || [https://developer.hashicorp.com/vault/docs Vault documentation]&lt;br /&gt;
|-&lt;br /&gt;
| vault || Vault || {{Ops file|roles/shellserver/vault/files/vault.hcl}} || [https://developer.hashicorp.com/vault/docs Vault documentation]&lt;br /&gt;
|-&lt;br /&gt;
| vault || systemd || {{Ops file|roles/shellserver/vault/files/vault.service}} || [https://www.freedesktop.org/software/systemd/man/ systemd documentation]&lt;br /&gt;
|-&lt;br /&gt;
| web-hosting || nginx || {{Ops file|roles/shellserver/web-hosting/files/eglide/nginx/vhosts/000-fallback.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| web-hosting || nginx || {{Ops file|roles/shellserver/web-hosting/files/eglide/nginx/vhosts/001-server.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== vault ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| policies || Vault || {{Ops file|roles/vault/policies/files/admin.hcl}} || [https://developer.hashicorp.com/vault/tutorials/get-started/introduction-policies Vault policy]&lt;br /&gt;
|-&lt;br /&gt;
| policies || Vault || {{Ops file|roles/vault/policies/files/airflow.hcl}} || [https://developer.hashicorp.com/vault/tutorials/get-started/introduction-policies Vault policy]&lt;br /&gt;
|-&lt;br /&gt;
| policies || Vault || {{Ops file|roles/vault/policies/files/monitoring.hcl}} || [https://developer.hashicorp.com/vault/tutorials/get-started/introduction-policies Vault policy]&lt;br /&gt;
|-&lt;br /&gt;
| policies || Vault || {{Ops file|roles/vault/policies/files/salt-primary.hcl}} || [https://developer.hashicorp.com/vault/tutorials/get-started/introduction-policies Vault policy]&lt;br /&gt;
|-&lt;br /&gt;
| policies || Vault || {{Ops file|roles/vault/policies/files/sentry.hcl}} || [https://developer.hashicorp.com/vault/tutorials/get-started/introduction-policies Vault policy]&lt;br /&gt;
|-&lt;br /&gt;
| policies || Vault || {{Ops file|roles/vault/policies/files/vault_bootstrap.hcl}} || [https://developer.hashicorp.com/vault/tutorials/get-started/introduction-policies Vault policy]&lt;br /&gt;
|-&lt;br /&gt;
| vault || Vault || {{Ops file|roles/vault/vault/files/vault.hcl}} || [https://developer.hashicorp.com/vault/docs Vault documentation]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== viperserv ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| eggdrop || Eggdrop || {{Ops file|roles/viperserv/eggdrop/files/eggdrop-bot.conf}} || [https://docs.eggheads.org/ Eggdrop documentation]&lt;br /&gt;
|-&lt;br /&gt;
| eggdrop || Eggdrop || {{Ops file|roles/viperserv/eggdrop/files/eggdrop-core.conf}} || [https://docs.eggheads.org/ Eggdrop documentation]&lt;br /&gt;
|-&lt;br /&gt;
| eggdrop || Eggdrop || {{Ops file|roles/viperserv/eggdrop/files/eggdrops-live.conf}} || [https://docs.eggheads.org/ Eggdrop documentation]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== webserver-alkane ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| alkane || Alkane || {{Ops file|roles/webserver-alkane/alkane/files/alkane.conf}} || [[Operations grimoire/Alkane|Alkane]]&lt;br /&gt;
|-&lt;br /&gt;
| alkane || Alkane || {{Ops file|roles/webserver-alkane/alkane/files/alkane.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| monitoring || PHP-FPM exporter || {{Ops file|roles/webserver-alkane/monitoring/files/rc/phpfpm_exporter.conf}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/newsyslog/nginx.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/dereckson.be/assets.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/dereckson.be/hg.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/dereckson.be/mediawiki.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/dereckson.be/scherzo.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/dereckson.be/www.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/dereckson.be/www51.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/dereckson.be/zed51.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/espace-win.org/cosmo.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/espace-win.org/grip.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/espace-win.org/www.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/hypership.space/www.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/admin.mail.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/api.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/api51.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/assets.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/autoconfig.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/daeghrefn.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/docker.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/docs.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/drive.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/ftp.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/grafana.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/infra.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/join.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/labs.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/launch.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/mail.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/obsidian51.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/packages.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/rain.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/tools51.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/trustspace.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/www.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/nasqueron.org/www51.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/test.ook.space/migration.mediawiki.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/wolfplex.org/api.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/wolfplex.org/assets.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-alkane/nginx/files/vhosts/wolfplex.org/www.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| php || PHP-FPM || {{Ops file|roles/webserver-alkane/php/files/php-fpm-pool.conf}} || [https://www.php.net/manual/en/install.fpm.configuration.php PHP-FPM documentation]&lt;br /&gt;
|-&lt;br /&gt;
| php || PHP-FPM || {{Ops file|roles/webserver-alkane/php/files/php-fpm.conf}} || [https://www.php.net/manual/en/install.fpm.configuration.php PHP-FPM documentation]&lt;br /&gt;
|-&lt;br /&gt;
| php || PHP-FPM || {{Ops file|roles/webserver-alkane/php/files/php.ini}} || [https://www.php.net/manual/en/configuration.file.php PHP configuration file]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== webserver-content ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| _generic || Environment || {{Ops file|roles/webserver-content/_generic/files/dot.env}} || [https://github.com/vlucas/phpdotenv dotenv]&lt;br /&gt;
|-&lt;br /&gt;
| org/nasqueron || Git || {{Ops file|roles/webserver-content/org/nasqueron/files/git-safe.conf}} || [https://git-scm.com/docs/git-config git-config documentation]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== webserver-core ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-core/nginx/files/nginx.conf}} || [https://nginx.org/en/docs/ nginx documentation]&lt;br /&gt;
|-&lt;br /&gt;
| nginx || nginx || {{Ops file|roles/webserver-core/nginx/files/nginx.rc}} || [[Operations grimoire/Services#FreeBSD_rc|FreeBSD rc]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== webserver-legacy ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Unit !! Software !! Full path !! Documentation&lt;br /&gt;
|-&lt;br /&gt;
| php-sites || PHP-FPM || {{Ops file|roles/webserver-legacy/php-sites/files/php-fpm-pool.conf}} || [https://www.php.net/manual/en/install.fpm.configuration.php PHP-FPM documentation]&lt;br /&gt;
|-&lt;br /&gt;
| php-sites || PHP-FPM || {{Ops file|roles/webserver-legacy/php-sites/files/php-fpm.conf}} || [https://www.php.net/manual/en/install.fpm.configuration.php PHP-FPM documentation]&lt;br /&gt;
|-&lt;br /&gt;
| php-sites || PHP-FPM || {{Ops file|roles/webserver-legacy/php-sites/files/php.ini}} || [https://www.php.net/manual/en/configuration.file.php PHP configuration file]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Services&amp;diff=2518</id>
		<title>Operations grimoire/Services</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Services&amp;diff=2518"/>
		<updated>2026-04-05T20:50:48Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* FreeBSD rc */ Basic instructions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Software running as daemons should be set as services to manage them at OS level a standard way.&lt;br /&gt;
&lt;br /&gt;
== Systemd, rc and runit ==&lt;br /&gt;
&lt;br /&gt;
Nasqueron infrastructure uses 3 services software:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Service management&lt;br /&gt;
|-&lt;br /&gt;
! OS !! Use case !! Software !! Commands&lt;br /&gt;
|-&lt;br /&gt;
| FreeBSD || Standard || rc || service &amp;lt;service&amp;gt; &amp;lt;command&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Linux || Standard || systemd || systemctl &amp;lt;command&amp;gt; &amp;lt;service&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Linux || Docker containers || runit || sv &amp;lt;service&amp;gt; &amp;lt;command&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note how systemd inverts the general order by putting the command before the service.&lt;br /&gt;
&lt;br /&gt;
== Systemd ==&lt;br /&gt;
=== Services ===&lt;br /&gt;
Search for .service file in operations repository for an idea.&lt;br /&gt;
It&#039;s well documented on ArchLinux wiki and freedesktop.org site.&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html&lt;br /&gt;
* https://wiki.archlinux.org/title/Systemd&lt;br /&gt;
&lt;br /&gt;
=== Timers ===&lt;br /&gt;
* Generally better to use a systemd service and a systemd timer than a crontab entry on Linux&lt;br /&gt;
* Don&#039;t forget to start the timer, see [https://devcentral.nasqueron.org/D3674#57039 this comment on D3674] for a demonstration&lt;br /&gt;
&lt;br /&gt;
=== Howto for operations repository ===&lt;br /&gt;
You can follow [https://www.dereckson.be/blog/2017/01/25/deploy-a-darkbot-or-a-simple-generic-service-with-saltstack-part-1/ this tutorial] to deploy a service on Nasqueron infrastructure, it covers the step from software deployment, configuration, user creation and a systemd service.&lt;br /&gt;
&lt;br /&gt;
== FreeBSD rc ==&lt;br /&gt;
=== Structure of a rc configuration file ===&lt;br /&gt;
Each service is configured in /etc/rc.conf.d/&amp;lt;service&amp;gt; file or by all the files in /etc/rc.conf.d/&amp;lt;service&amp;gt;/ directory.&lt;br /&gt;
&lt;br /&gt;
Those files follow [https://man.freebsd.org/cgi/man.cgi?rc.conf rc.conf syntax] and use:&lt;br /&gt;
* &amp;lt;service&amp;gt;_enable=&amp;quot;YES&amp;quot; to indicate auto start of the service&lt;br /&gt;
* various &amp;lt;service&amp;gt;_&amp;lt;key&amp;gt;=&amp;lt;value&amp;gt; per service documentation&lt;br /&gt;
&lt;br /&gt;
To know all the available options for a service the best is to read the documentation at the top of every service, located in  &lt;br /&gt;
/usr/local/etc/rc.d for applications and /etc/rc.d for the base system.&lt;br /&gt;
&lt;br /&gt;
=== Template for operations repository ===&lt;br /&gt;
If you need to add a rc service, we&#039;ve a template for the file: follow [https://devcentral.nasqueron.org/D3571 D3571 instructions]&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire|Services]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire&amp;diff=2517</id>
		<title>Operations grimoire</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire&amp;diff=2517"/>
		<updated>2026-04-05T20:41:45Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Appendices */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Nasqueron Operations Grimoire.jpg|thumb|320px|right|The Nasqueron operations grimoire tries to document the more arcane aspects of our complex infrastructure.]]&lt;br /&gt;
&lt;br /&gt;
Welcome to the Nasqueron operations grimoire (NOG).&lt;br /&gt;
&lt;br /&gt;
This grimoire is a reference about our infrastructure and services hosted with procedures we follow to build, maintain and deploy.&lt;br /&gt;
&lt;br /&gt;
Our infrastructure is open, mainly documented in {{repo|operations}} repository, and we actively encourage contributions from the community.&lt;br /&gt;
&lt;br /&gt;
== Infrastructure ==&lt;br /&gt;
* [[/Environments]]&lt;br /&gt;
* [[/Kubernetes]]&lt;br /&gt;
* [[/Docker engine]]&lt;br /&gt;
* [[/Salt]]&lt;br /&gt;
&lt;br /&gt;
=== OS-specific ===&lt;br /&gt;
;By OS&lt;br /&gt;
* [[/FreeBSD]]&lt;br /&gt;
* [[/RHEL]]&lt;br /&gt;
&lt;br /&gt;
;All OSes&lt;br /&gt;
* [[/NTP]]&lt;br /&gt;
* [[/Packages repository]]&lt;br /&gt;
* [[/Services]]: systemd, runit and rc&lt;br /&gt;
&lt;br /&gt;
=== Storage ===&lt;br /&gt;
* [[/ZFS]]&lt;br /&gt;
&lt;br /&gt;
=== Observability ===&lt;br /&gt;
* [[/Grafana]]&lt;br /&gt;
* [[/Logs]]&lt;br /&gt;
* [[/Prometheus]]&lt;br /&gt;
&lt;br /&gt;
=== Network ===&lt;br /&gt;
* [[/Network]]&lt;br /&gt;
* [[/DNS]]&lt;br /&gt;
* [[/Firewall]]&lt;br /&gt;
* [[/IPv6]]&lt;br /&gt;
* [https://netbox.nasqueron.org/ NetBox]&lt;br /&gt;
&lt;br /&gt;
== Services ==&lt;br /&gt;
=== Core services ===&lt;br /&gt;
; Messages queues&lt;br /&gt;
* [[/Kafka]]&lt;br /&gt;
* [[/RabbitMQ]]&lt;br /&gt;
&lt;br /&gt;
; Databases&lt;br /&gt;
* [[/MySQL]]&lt;br /&gt;
* [[/PostgreSQL]]&lt;br /&gt;
&lt;br /&gt;
; Ops&lt;br /&gt;
* [[/NetBox]]&lt;br /&gt;
&lt;br /&gt;
=== Identity management ===&lt;br /&gt;
* [[/Login]] (Auth Grove)&lt;br /&gt;
&lt;br /&gt;
=== Collaborative tools ===&lt;br /&gt;
* [[/DevCentral]] (Phabricator)&lt;br /&gt;
* [[/Etherpad]]&lt;br /&gt;
* [[/Mumble]]&lt;br /&gt;
* [[/Mastodon]] (social.nasqueron.org)&lt;br /&gt;
* [[/Openfire]] (XMPP)&lt;br /&gt;
&lt;br /&gt;
=== IRC bots ===&lt;br /&gt;
* [[/Dæghrefn]] (eggdrop)&lt;br /&gt;
* [[/Odderon]] (darkbot)&lt;br /&gt;
&lt;br /&gt;
=== Mail ===&lt;br /&gt;
* [[/Mail]]&lt;br /&gt;
* [[/Mail/DKIM]]&lt;br /&gt;
* [[/Mail/Sympa]]&lt;br /&gt;
&lt;br /&gt;
=== Web ===&lt;br /&gt;
; Common documentation for all webserver roles&lt;br /&gt;
* [[/Web/Headers]]&lt;br /&gt;
&lt;br /&gt;
; Where to host?&lt;br /&gt;
* [[/Docker engine]] for Docker containers front-end&lt;br /&gt;
* [[/Alkane]] for PHP and static sites&lt;br /&gt;
&lt;br /&gt;
; SaaS for common applications&lt;br /&gt;
* [[MediaWiki SaaS]]&lt;br /&gt;
* [[/WordPress]]&lt;br /&gt;
&lt;br /&gt;
; Other sites&lt;br /&gt;
* [[/Sites on Eglide]]&lt;br /&gt;
* [[/Sites on Ysul]] (currently migrating to Alkane)&lt;br /&gt;
&lt;br /&gt;
; Services for web applications&lt;br /&gt;
* [[/Anubis]] if you need to protect from LLM scraping traffic&lt;br /&gt;
* [[/Orbeon]] if you&#039;re in need of a form&lt;br /&gt;
&lt;br /&gt;
=== CI/CD ===&lt;br /&gt;
* [[/Broker]]&lt;br /&gt;
* [[/Docker registry]]&lt;br /&gt;
* [[/Jenkins]]&lt;br /&gt;
* [[/Notifications center]]&lt;br /&gt;
* [[/Sentry]]&lt;br /&gt;
* [[/Vault]]&lt;br /&gt;
&lt;br /&gt;
=== Shellserver ===&lt;br /&gt;
* [[/Eglide/Vault]]&lt;br /&gt;
&lt;br /&gt;
== Services configuration ==&lt;br /&gt;
&#039;&#039;This section contains general information not related to a specific service.&#039;&#039;&lt;br /&gt;
* [[/TLS certificates]] (Let&#039;s encrypt / letsencrypt)&lt;br /&gt;
&lt;br /&gt;
== Checklists ==&lt;br /&gt;
=== SSH ===&lt;br /&gt;
* [[/Recommended SSH configuration]]&lt;br /&gt;
&lt;br /&gt;
=== Infrastructure ===&lt;br /&gt;
* [[/How to add a server to the Nasqueron servers pool]]&lt;br /&gt;
* [[/How to attach a new virtual disk]]&lt;br /&gt;
* [[/Reboot checklist]]&lt;br /&gt;
&lt;br /&gt;
=== Network ===&lt;br /&gt;
* [[/Checklist router post-restart]]&lt;br /&gt;
&lt;br /&gt;
=== Docker ===&lt;br /&gt;
* [[/Restart a Docker engine]]&lt;br /&gt;
* [[/Dwellers to DevCentral]]&lt;br /&gt;
* [[/Git operations in production containers]]&lt;br /&gt;
* [[/Add a service to Docker PaaS]]&lt;br /&gt;
* [[/Docker Hub]]&lt;br /&gt;
&lt;br /&gt;
=== Salt ===&lt;br /&gt;
* [[/Operations repository]]&lt;br /&gt;
* [[/Deploy with Salt]]&lt;br /&gt;
* [[/Create and revoke user accounts on Salt servers]]&lt;br /&gt;
* [[/Provision user homefiles]]&lt;br /&gt;
&lt;br /&gt;
=== Terraform / OpenTofu ===&lt;br /&gt;
* [[/Deploy with Terraform]]&lt;br /&gt;
&lt;br /&gt;
== SIG ==&lt;br /&gt;
* [[/Onboarding]]&lt;br /&gt;
&lt;br /&gt;
== Appendices ==&lt;br /&gt;
* [[/Changelog]]&lt;br /&gt;
* [[/Contacts]]&lt;br /&gt;
* [[/Configuration files]]&lt;br /&gt;
* [[/Contribute]]&lt;br /&gt;
* [[/Decom]]&lt;br /&gt;
* [[/Evaluated products]]&lt;br /&gt;
* [[/External services]]&lt;br /&gt;
* [[/Incidents]]&lt;br /&gt;
* [[/Legacy archive]]&lt;br /&gt;
* [[/OID]]&lt;br /&gt;
* [[/Old content report]]&lt;br /&gt;
* [[/Policies]]&lt;br /&gt;
* [[/Who]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire|*]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Code_conventions&amp;diff=2516</id>
		<title>Code conventions</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Code_conventions&amp;diff=2516"/>
		<updated>2026-04-03T22:35:38Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Salt */ Double quotes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== All languages ==&lt;br /&gt;
&lt;br /&gt;
* Don&#039;t use more complicated constructs like ternary operators&lt;br /&gt;
* [http://jeroendedauw.github.io/slides/craftmanship/functions/#/1 Keep functions short and simple].&lt;br /&gt;
* Define explicitly methods visibility, as several languages have different default values (e.g. private for C# class members, public for PHP methods)&lt;br /&gt;
* Comments to document a method are written at the singular 3rd person (we seem to have moved to infinitive recently, we need to take a decision here)&lt;br /&gt;
&lt;br /&gt;
== C ==&lt;br /&gt;
If you use [http://clang.llvm.org/docs/ClangFormat.html ClangFormat], a [https://github.com/dereckson/rabbitmq-tcl/blob/master/.clang-format .clang-format file] is available.&lt;br /&gt;
&lt;br /&gt;
== JavaScript ==&lt;br /&gt;
The following conventions are used:&lt;br /&gt;
* K&amp;amp;R, 1TBS variant, including for functions&lt;br /&gt;
* 4 spaces as indent&lt;br /&gt;
* Use modern JavaScript idioms like &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt;&lt;br /&gt;
* Consider to use async code for events-driven development, especially for servers&lt;br /&gt;
&lt;br /&gt;
== PHP ==&lt;br /&gt;
The following conventions are used:&lt;br /&gt;
* K&amp;amp;R, 1TBS variant, including for functions&lt;br /&gt;
* 4 spaces as indent&lt;br /&gt;
* The keywords &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; must be in lower case.&lt;br /&gt;
* Arrays use short syntax&lt;br /&gt;
* Array elements ends with a comma&lt;br /&gt;
* Functions, methods and class names use camel case &lt;br /&gt;
&lt;br /&gt;
If you use PhpStorm or another JetBrains IDE, you can import [https://github.com/nasqueron/codestyle/blob/master/JetBrains/php-codestyle.xml JetBrains/php-codestyle.xml] from the codestyle repository as a code style (Settings or Default Settings &amp;gt; Editor &amp;gt; Code Style &amp;gt; PHP &amp;gt; click on the wheel icon &amp;gt; Import Scheme &amp;gt; Intellij IDEA codestyle XML).&lt;br /&gt;
&lt;br /&gt;
If you want to lint a project with phpcs, you can require the Composer package &amp;lt;code&amp;gt;nasqueron/codestyle&amp;lt;/code&amp;gt; and use the following &amp;lt;kbd&amp;gt;phpcs.xml&amp;lt;kbd&amp;gt; standard file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;ruleset&amp;gt;&lt;br /&gt;
    &amp;lt;rule ref=&amp;quot;vendor/nasqueron/codestyle/CodeSniffer&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;file&amp;gt;.&amp;lt;/file&amp;gt;&lt;br /&gt;
    &amp;lt;exclude-pattern&amp;gt;\.git/&amp;lt;/exclude-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;exclude-pattern&amp;gt;vendor/&amp;lt;/exclude-pattern&amp;gt;&lt;br /&gt;
&amp;lt;/ruleset&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python ==&lt;br /&gt;
=== Code style ===&lt;br /&gt;
&#039;&#039;&#039;2023.&#039;&#039;&#039; We follow [https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html black style], so use black utility (&amp;lt;code&amp;gt;pip install black&amp;lt;/code&amp;gt;). As such, you need to configure Flake8 to ignore rule E203.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2015.&#039;&#039;&#039; We follow [https://www.python.org/dev/peps/pep-0008/ PEP-8].&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
A template exists for a new Python command: [https://devcentral.nasqueron.org/source/snippets/browse/main/python/command.py python/command.py]&lt;br /&gt;
&lt;br /&gt;
In packages, empty __init__.py files can follow [https://devcentral.nasqueron.org/source/merge-dictionaries/browse/main/src/mergedictionaries/utils/__init__.py;eaf5bc2c21118454837e8148147606c19d4afff7 this example].&lt;br /&gt;
&lt;br /&gt;
=== Configuration files ===&lt;br /&gt;
Allow empty configuration files. For example, the YAML parser will return None if the file exists but is empty, we can catch that and return default instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
         with open(get_configuration_path()) as fd:&lt;br /&gt;
            return yaml.safe_load(fd) or {}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rust ==&lt;br /&gt;
&#039;&#039;&#039;2023.&#039;&#039;&#039; Automated codestyle (black in Python, clang-format in Rust) seems preferable. As such, a style compatible with &amp;lt;code&amp;gt;rustfmt&amp;lt;/code&amp;gt; is needed to be able to format using &amp;lt;code&amp;gt;cargo fmt&amp;lt;/code&amp;gt;. You can add to your project  [https://devcentral.nasqueron.org/source/codestyle/browse/main/rust/rustfmt.toml rust/rustfmt.toml in codestyle] to configure it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2015.&#039;&#039;&#039; We followed &amp;quot;Rust default style&amp;quot;, described at [https://web.archive.org/web/20170320083740/http://aturon.github.io/ https://aturon.github.io/]. It&#039;s mainly a K&amp;amp;R, 1TBS variant.&lt;br /&gt;
&lt;br /&gt;
Use trailing comma for elements in every struct/impl/etc.&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
Standard library isn&#039;t the most ergonomic for threads programming, those crate allows more efficient and legible code:&lt;br /&gt;
* [https://docs.rs/crossbeam-channel/latest/crossbeam_channel/ crossbeam_channel] for mpmc (multiple producers, multiple consumers)&lt;br /&gt;
* [https://docs.rs/parking_lot/latest/parking_lot/type.Mutex.html parking_lot] for Mutex&lt;br /&gt;
&lt;br /&gt;
== Salt ==&lt;br /&gt;
=== Style ===&lt;br /&gt;
;Whitespaces&lt;br /&gt;
* Indent with two spaces&lt;br /&gt;
* YAML lists use indented bullets&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
id:&lt;br /&gt;
  method:&lt;br /&gt;
    - somekey: value&lt;br /&gt;
    - otherkey: value&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Quotes&lt;br /&gt;
* Use double quotes in Python, Salt and Jinja expressions&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
&lt;br /&gt;
;Files provisioned&lt;br /&gt;
* When you ask to download a file remotely, you need a source hash, pick SHA256 as algo&lt;br /&gt;
* Each file provisioned from the Salt repository must contains an header explaining the fact, with the full path in the rOPS repo&lt;br /&gt;
&lt;br /&gt;
;BSD and Linux distros compatible states&lt;br /&gt;
* populate the map.jinja file with OS logic (e.g. `dirs` for /etc vs /usr/local/etc)&lt;br /&gt;
* when you&#039;ve a specific set of tasks to do for one OS/distro, it&#039;s acceptable to enclose it in a state by an if block&lt;br /&gt;
&lt;br /&gt;
=== Vocabulary ===&lt;br /&gt;
&lt;br /&gt;
;Domain names&lt;br /&gt;
:To refer to the fully qualified domain name sub.domain.tld, use &#039;&#039;&#039;fqdn&#039;&#039;&#039;. To split the domains in part, use &#039;&#039;&#039;domain&#039;&#039;&#039; and &#039;&#039;&#039;subdomain&#039;&#039;&#039;. This is important to understand a state without having  to refer to the associated pillar to disambig domain.&lt;br /&gt;
&lt;br /&gt;
== Shell scripts ==&lt;br /&gt;
;UNIX agnosticism:&lt;br /&gt;
* Don&#039;t assume absolute path, use &amp;lt;code&amp;gt;#!/usr/bin/env bash&amp;lt;/code&amp;gt; and not &amp;lt;code&amp;gt;#!/bin/bash&amp;lt;/code&amp;gt; (it could be elsewhere on BSD or Solaris)&lt;br /&gt;
* Use `sh` as must as possible, try to avoid &amp;lt;code&amp;gt;bash&amp;lt;/code&amp;gt;, document exceptions rationale in your commits&lt;br /&gt;
&lt;br /&gt;
;Whitespaces:&lt;br /&gt;
* One whitespace line between shebang and actual content&lt;br /&gt;
* 4 spaces as indent&lt;br /&gt;
&lt;br /&gt;
;File names:&lt;br /&gt;
* We use hyphens (-) as separators, not underscores or camelcase&lt;br /&gt;
* Filename should start by a verb if it performs an action&lt;br /&gt;
* Don&#039;t use .sh extensions when deployed as command&lt;br /&gt;
** sometimes you&#039;ll see them on Phabricator pastes&#039; titles, but it has been added there, so Phab knows shell syntax highlighting should be used&lt;br /&gt;
** &#039;&#039;&#039;Tip.&#039;&#039;&#039; You can use .sh in src/ to help linters, but then provide a Makefile to install it under correct name without extension. Same for operations repository where everything uses .sh, but when deploying with file.managed the extension is omitted&lt;br /&gt;
&lt;br /&gt;
;Templates&lt;br /&gt;
* New command: [https://devcentral.nasqueron.org/source/snippets/browse/main/shell/script.sh shell/script.sh]&lt;br /&gt;
&lt;br /&gt;
== TCL ==&lt;br /&gt;
&lt;br /&gt;
* Indent with 4 spaces, as of 2026-03-20&lt;br /&gt;
* Keep blocks visually separated&lt;br /&gt;
* Use Tcl primitives instead of manual parsing for strings: split, lindex, lrange, join&lt;br /&gt;
* Avoid regex unless necessary&lt;br /&gt;
* List expansion {*} instead of eval&lt;br /&gt;
&lt;br /&gt;
; ViperServ development&lt;br /&gt;
* If you build a full new system, all procedures must be defined in a namespace&lt;br /&gt;
* Use fully-qualified names (::namespace::proc) for procedure definitions and cross-namespace calls&lt;br /&gt;
* Separate low-level request logic from API-specific methods&lt;br /&gt;
&lt;br /&gt;
== Makefile ==&lt;br /&gt;
UNIX agnosticism:&lt;br /&gt;
* Test your makefile against BSD make, and document in README.md to use GNU Makefile (gmake) when it&#039;s not convenient to keep compatibility&lt;br /&gt;
&lt;br /&gt;
Presentation:&lt;br /&gt;
* Create a block with the general targets, then sections with your targets organized by categories/goals/parts&lt;br /&gt;
&lt;br /&gt;
Tip:&lt;br /&gt;
* It&#039;s possible to provision BSDmakefile and GNUmakefile when UNIX agnosticism doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
== Structured data formats (YAML, JSON, XML) ==&lt;br /&gt;
The number of spaces depend if the format is usually heavily hierarchized or not:&lt;br /&gt;
&lt;br /&gt;
* 2 spaces for JSON and YAML&lt;br /&gt;
* 4 spaces for XML, TOML and other configuration files&lt;br /&gt;
&lt;br /&gt;
== Utilities ==&lt;br /&gt;
&lt;br /&gt;
The https://github.com/nasqueron/codestyle repository contains resource to help to respect code convention, like a phpcs ruleset, a configuration ready for PhpStorm, IntelliJ and other JetBrains editors, or a clang-format configuration file.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Fix indent issues ===&lt;br /&gt;
The &amp;lt;code&amp;gt;expand&amp;lt;/code&amp;gt; utility converts tabs into spaces, while &amp;lt;code&amp;gt;unexpand&amp;lt;/code&amp;gt; convert spaces into tabs.&lt;br /&gt;
&lt;br /&gt;
Switch a file from tab indent to 4 spaces indent:&lt;br /&gt;
&lt;br /&gt;
    $ expand -t 4 foo.sh &amp;gt; a&lt;br /&gt;
    $ cat a &amp;gt; foo.sh&lt;br /&gt;
    $ rm a&lt;br /&gt;
&lt;br /&gt;
(Avoid &amp;lt;code&amp;gt;mv&amp;lt;/code&amp;gt; for shell scripts as your foo.sh has probably a 755 chmod, and a will probably have a 644 chmod, assuming 022 as umask)&lt;br /&gt;
&lt;br /&gt;
Switch a file indent with 2 spaces to 4 spaces:&lt;br /&gt;
&lt;br /&gt;
    $ unexpand -t 2 JetBrains/php-codestyle.xml &amp;gt; a&lt;br /&gt;
    $ expand -t 4 a &amp;gt; JetBrains/php-codestyle.xml&lt;br /&gt;
&lt;br /&gt;
This last technique can be used in batch [https://gist.github.com/dereckson/80a746b408c0cf0b688a09db31d5c881 with this reindent script]:&lt;br /&gt;
&lt;br /&gt;
    $ git ls-files | xargs -n1 reindent 2 4 &lt;br /&gt;
&lt;br /&gt;
[[Category:Reference]]&lt;br /&gt;
[[Category:Contributor guide]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=WindRiver&amp;diff=2515</id>
		<title>WindRiver</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=WindRiver&amp;diff=2515"/>
		<updated>2026-04-03T17:19:51Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;WindRiver is an FreeBSD 14 bare metal server for Nasqueron general-purpose development.&lt;br /&gt;
&lt;br /&gt;
It supersedes [[Ysul]].&lt;br /&gt;
&lt;br /&gt;
Documentation: [[Devserver reference]]&lt;br /&gt;
&lt;br /&gt;
== Basic information ==&lt;br /&gt;
* &#039;&#039;&#039;IP:&#039;&#039;&#039;&lt;br /&gt;
** 195.154.30.15 &amp;lt;strike&amp;gt;51.159.17.168 since 2023-06-14. Previously 51.159.18.59.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** 2a02:578:4f0d:0:30d0:7b22:6cde:a52e (native, still to migrate)&lt;br /&gt;
** 2001:bc8:6005:5:aa1e:84ff:fef3:5d9c (future through HE)&lt;br /&gt;
* &#039;&#039;&#039;Hostname:&#039;&#039;&#039; windriver.nasqueron.org&lt;br /&gt;
* &#039;&#039;&#039;Homepage:&#039;&#039;&#039; https://windriver.nasqueron.org/&lt;br /&gt;
* &#039;&#039;&#039;Configuration:&#039;&#039;&#039; &amp;lt;strike&amp;gt;64 Gb RAM, Xeon E3 1240 V6, 2x 500 GB SSD (&amp;quot;Pro-6-S&amp;quot;)&amp;lt;/strike&amp;gt; 96 Gb. RAM, Xeon E5-1650 v3, 3x 500 GB SSD (&amp;quot;Pro-4-L&amp;quot;)&lt;br /&gt;
* &#039;&#039;&#039;ISP:&#039;&#039;&#039; [http://www.online.net Online] (FR)&lt;br /&gt;
* &#039;&#039;&#039;Network:&#039;&#039;&#039; Illiad (FR)&lt;br /&gt;
* &#039;&#039;&#039;Policy:&#039;&#039;&#039; Access for any Nasqueron project and for infrastructure operations task.&lt;br /&gt;
* &#039;&#039;&#039;Started:&#039;&#039;&#039; 2019-11-21&lt;br /&gt;
&lt;br /&gt;
== Ports ==&lt;br /&gt;
&lt;br /&gt;
Ports for services managed automatically through Salt are available on {{Ops file|PORTS}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Reserved ports - IRC server range&lt;br /&gt;
|-&lt;br /&gt;
! Port !! User account !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 6901 || dereckson || irssi proxy&lt;br /&gt;
|-&lt;br /&gt;
| 6902 || dereckson || irssi proxy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
&lt;br /&gt;
=== To check after reboot ===&lt;br /&gt;
&lt;br /&gt;
* Network&lt;br /&gt;
** IPv4 - ICANN&lt;br /&gt;
** IPv6 - main + viperserv alias&lt;br /&gt;
** IPv6 - can we reach something with IPv6&lt;br /&gt;
** IPv4 - Drake: tunnel + route + ping any server&lt;br /&gt;
* Services&lt;br /&gt;
** Alkane HTTP server&lt;br /&gt;
** API exec HTTP server&lt;br /&gt;
** Bitlbee&lt;br /&gt;
** Eggdrops: Dæghrefn + Wearg&lt;br /&gt;
** Grafana&lt;br /&gt;
** MariaDB&lt;br /&gt;
** NetBox&lt;br /&gt;
** nginx&lt;br /&gt;
** Node exporter for Prometheus&lt;br /&gt;
** oidentd&lt;br /&gt;
** php-fpm&lt;br /&gt;
** PostgreSQL&lt;br /&gt;
** Prometheus&lt;br /&gt;
** Redis&lt;br /&gt;
** Salt minion&lt;br /&gt;
** SSH server&lt;br /&gt;
* Vault connectivity&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=How_to_communicate&amp;diff=2495</id>
		<title>How to communicate</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=How_to_communicate&amp;diff=2495"/>
		<updated>2026-03-24T17:13:32Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page shows tools and best practices to communicate efficiently about code changes or operations activities.&lt;br /&gt;
&lt;br /&gt;
== Ways of communication ==&lt;br /&gt;
&lt;br /&gt;
=== Discussion spaces ===&lt;br /&gt;
Our primary discussion spaces are IRC, DevCentral and here on Agora:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Primary discussion spaces&lt;br /&gt;
|-&lt;br /&gt;
! Space !! How to join !! Scope&lt;br /&gt;
|-&lt;br /&gt;
| [[IRC]] || [https://libera.chat/ Libera.chat] #nasqueron-ops || Discussions about servers, infrastructure, operations, access.&amp;lt;br&amp;gt;Also, as it&#039;s currently our main discussion space, you&#039;re welcome to hangout there if you want to chat with fellow nasquenautes.&lt;br /&gt;
|-&lt;br /&gt;
| DevCentral || Browse https://devcentral.nasqueron.org || Tasks, project management, status update, sprints, ideas&lt;br /&gt;
|-&lt;br /&gt;
| Agora || You&#039;re here! [https://forms.nasqueron.org/nasqueron-requests/agora-account/new Request an account] || Documentation, projects, idea, personal notes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
We also use Jitsi as video-conference platform and some members currently use Discord to organize their contributions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Known discussion spaces&lt;br /&gt;
|-&lt;br /&gt;
! Space !! How to join !! Scope&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| Discord || https://discord.gg/DZQK8Dd8Xd || ServPulse&lt;br /&gt;
|-&lt;br /&gt;
| Jitsi || https://meet.jit.si/nasqueron || Any topic.&amp;lt;br&amp;gt;Tip: If you&#039;re first on the meeting, you can login through GitHub to open it.&lt;br /&gt;
|}&lt;br /&gt;
=== By project ===&lt;br /&gt;
* Nasqueron Operations SIG uses IRC: Libera.chat #nasqueron-ops&lt;br /&gt;
* Eli and Amine work on Discord for [[ServPulse]]&lt;br /&gt;
&lt;br /&gt;
=== Tips for audio and video meeting ===&lt;br /&gt;
A headset can help a lot to get clear communication, without echo or reverb. When you don&#039;t have it, try to mute yourself when you don&#039;t speak (Jitsi) or enable push-to-talk feature (Discord).&lt;br /&gt;
&lt;br /&gt;
Dereckson has a spare USB headset from Sennheiser if you need one.&lt;br /&gt;
&lt;br /&gt;
== Share logs, screenshots ==&lt;br /&gt;
;Core recommandations&lt;br /&gt;
* DO: use appropriate tools to share information through a short link&lt;br /&gt;
* DON&#039;T: use screenshots to share text, text must be shared as text&lt;br /&gt;
* DON&#039;T: copy/paste full logs in chat&lt;br /&gt;
* DON&#039;T: share logs with privacy data / PII, in that case give a reference to go to that log&lt;br /&gt;
&lt;br /&gt;
;Tools to use&lt;br /&gt;
* To share directly the ouput of a command&lt;br /&gt;
** [https://termbin.com/ Termbin]: &amp;lt;code&amp;gt;command | nc termbin.com 9999&amp;lt;/code&amp;gt;&lt;br /&gt;
** Arcanist to publish to DevCentral: &amp;lt;code&amp;gt;command | arc paste --&amp;lt;/code&amp;gt;&lt;br /&gt;
* To share clipboard content&lt;br /&gt;
** https://dpaste.com/&lt;br /&gt;
** DevCentral: [https://devcentral.nasqueron.org/paste/edit/form/default/ create paste], that gives a reference to put in other objects (tasks, differential), use &amp;lt;code&amp;gt;{P100}&amp;lt;/code&amp;gt; for direct inclusion or &amp;lt;code&amp;gt;P100&amp;lt;/code&amp;gt; for link&lt;br /&gt;
* To share source code&lt;br /&gt;
** Pastebin are totally appropriated too&lt;br /&gt;
** You can also use GitHub Gist: https://gist.github.com - they can be secret or publicly available&lt;br /&gt;
** You can send a pull request to the repository for proof of concept&lt;br /&gt;
** If you want to discuss a pull request against an upstream repository, DevCentral allows &amp;quot;free&amp;quot; diff not linked to any repo too: [https://devcentral.nasqueron.org/differential/diff/create/ diff/create]&lt;br /&gt;
&lt;br /&gt;
;Too many tools! I&#039;m lost&lt;br /&gt;
It can require some practice to be able to pick among the most appropriate tool, so you can start with:&lt;br /&gt;
* Command output -&amp;gt; &amp;lt;code&amp;gt;command | nc termbin.com 9999&amp;lt;/code&amp;gt;&lt;br /&gt;
* Anything else&lt;br /&gt;
** Ephemeral -&amp;gt; https://dpaste.com/&lt;br /&gt;
** To save and discuss in tasks -&amp;gt; https://devcentral.nasqueron.org/paste/edit/form/default/&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributor guide]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2494</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2494"/>
		<updated>2026-03-22T23:51:29Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Propagate secrets (DRP) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert&amp;quot;&amp;gt;Important. Each time you&#039;ll reprovision the secrets, they will change.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to always apply this full procedure.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=MediaWiki:Common.css&amp;diff=2493</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=MediaWiki:Common.css&amp;diff=2493"/>
		<updated>2026-03-22T23:50:38Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Source code */&lt;br /&gt;
&lt;br /&gt;
code, tt, kbd, pre, samp {&lt;br /&gt;
	font-size: 0.9em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Call for actions button  */&lt;br /&gt;
&lt;br /&gt;
.btn {&lt;br /&gt;
	-webkit-border-radius: 6;&lt;br /&gt;
	-moz-border-radius: 6;&lt;br /&gt;
	border-radius: 6px;&lt;br /&gt;
	color: #ffffff;&lt;br /&gt;
	font-size: 1.4em;&lt;br /&gt;
	background: #4d7b94;&lt;br /&gt;
	padding: 10px 20px 10px 20px;&lt;br /&gt;
	text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.btn a, .btn a:hover, .btn a:visited {&lt;br /&gt;
	color: white !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.btn:hover {&lt;br /&gt;
	background: #6caacc;&lt;br /&gt;
	text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Inline code  */&lt;br /&gt;
&lt;br /&gt;
.inline-code, .inline-code div,  .inline-code pre {&lt;br /&gt;
	display: inline-table;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
    Banners&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
.alert {&lt;br /&gt;
  background: #d32f2f;&lt;br /&gt;
  color: #fff;&lt;br /&gt;
  padding: 0.75rem 1rem;&lt;br /&gt;
  border-radius: 4px;&lt;br /&gt;
  font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
    Colors from 2017 palette&lt;br /&gt;
    &lt;br /&gt;
    See https://devcentral.nasqueron.org/M11 or [[Design/2017 colors]]&lt;br /&gt;
 */&lt;br /&gt;
 &lt;br /&gt;
.color-magnetic-one {&lt;br /&gt;
	/* Cyberspace gray */&lt;br /&gt;
	color: #44484D;&lt;br /&gt;
}&lt;br /&gt;
.color-magnetic-two {&lt;br /&gt;
	/* Anchors Aweigh blue */&lt;br /&gt;
	color: #2B3441;&lt;br /&gt;
}&lt;br /&gt;
.color-magnetic-three {&lt;br /&gt;
	/* Niagara blue — Pantone 17-4123 */&lt;br /&gt;
	color: #5587A2; &lt;br /&gt;
}&lt;br /&gt;
.color-magnetic-four {&lt;br /&gt;
	/* Primrose yellow — Pantone 13-0755 */&lt;br /&gt;
	color: #F6D258;&lt;br /&gt;
}&lt;br /&gt;
.color-magnetic-five {&lt;br /&gt;
	/* Green from http://www.elledecor.com/design-decorate/color/g3175/color-trends/ */&lt;br /&gt;
	color: #67947D;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
    Responsive blocks.&lt;br /&gt;
 */&lt;br /&gt;
 &lt;br /&gt;
.block {&lt;br /&gt;
	margin: 0 0;&lt;br /&gt;
	padding: 5vh 5vw;&lt;br /&gt;
	&lt;br /&gt;
	border: #808080 solid 5px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block-col {&lt;br /&gt;
	position: relative;&lt;br /&gt;
	display:inline;&lt;br /&gt;
	float: left;&lt;br /&gt;
	margin-right: 1em;&lt;br /&gt;
	padding: 1vw;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block-col-quarter {&lt;br /&gt;
	width: 20%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block-col-half {&lt;br /&gt;
	width: 40%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.user-block {&lt;br /&gt;
	min-height: 50vh;&lt;br /&gt;
	background-color: #44484D;&lt;br /&gt;
	color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.user-block dt {&lt;br /&gt;
    color: #67947D;&lt;br /&gt;
    font-family: &#039;Segoe UI&#039;, &#039;Segoe UI Emoji&#039;, &#039;Segoe UI Symbol&#039;, &#039;Lato&#039;, &#039;Liberation Sans&#039;, &#039;Noto Sans&#039;, &#039;Helvetica Neue&#039;, &#039;Helvetica&#039;, sans-serif;&lt;br /&gt;
    font-size: 1.375em;&lt;br /&gt;
    margin-bottom: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.user-block a {&lt;br /&gt;
    color: #F6D258 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
	Variable Grid System.&lt;br /&gt;
	Learn more ~ http://www.spry-soft.com/grids/&lt;br /&gt;
	Based on 960 Grid System - http://960.gs/&lt;br /&gt;
&lt;br /&gt;
	Licensed under GPL and MIT.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Containers&lt;br /&gt;
----------------------------------------------------------------------------------------------------*/&lt;br /&gt;
.container_12 {&lt;br /&gt;
	margin-left: auto;&lt;br /&gt;
	margin-right: auto;&lt;br /&gt;
	width: 960px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid &amp;gt;&amp;gt; Global&lt;br /&gt;
----------------------------------------------------------------------------------------------------*/&lt;br /&gt;
&lt;br /&gt;
.grid_1,&lt;br /&gt;
.grid_2,&lt;br /&gt;
.grid_3,&lt;br /&gt;
.grid_4,&lt;br /&gt;
.grid_5,&lt;br /&gt;
.grid_6,&lt;br /&gt;
.grid_7,&lt;br /&gt;
.grid_8,&lt;br /&gt;
.grid_9,&lt;br /&gt;
.grid_10,&lt;br /&gt;
.grid_11,&lt;br /&gt;
.grid_12 {&lt;br /&gt;
	display:inline;&lt;br /&gt;
	float: left;&lt;br /&gt;
	position: relative;&lt;br /&gt;
	margin-left: 10px;&lt;br /&gt;
	margin-right: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid &amp;gt;&amp;gt; Children (Alpha ~ First, Omega ~ Last)&lt;br /&gt;
----------------------------------------------------------------------------------------------------*/&lt;br /&gt;
&lt;br /&gt;
.alpha {&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.omega {&lt;br /&gt;
	margin-right: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid &amp;gt;&amp;gt; 12 Columns&lt;br /&gt;
----------------------------------------------------------------------------------------------------*/&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_1 {&lt;br /&gt;
	width:60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_2 {&lt;br /&gt;
	width:140px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_3 {&lt;br /&gt;
	width:220px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_4 {&lt;br /&gt;
	width:300px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_5 {&lt;br /&gt;
	width:380px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_6 {&lt;br /&gt;
	width:460px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_7 {&lt;br /&gt;
	width:540px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_8 {&lt;br /&gt;
	width:620px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_9 {&lt;br /&gt;
	width:700px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_10 {&lt;br /&gt;
	width:780px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_11 {&lt;br /&gt;
	width:860px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .grid_12 {&lt;br /&gt;
	width:940px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Prefix Extra Space &amp;gt;&amp;gt; 12 Columns&lt;br /&gt;
----------------------------------------------------------------------------------------------------*/&lt;br /&gt;
&lt;br /&gt;
.container_12 .prefix_1 {&lt;br /&gt;
	padding-left:80px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .prefix_2 {&lt;br /&gt;
	padding-left:160px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .prefix_3 {&lt;br /&gt;
	padding-left:240px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .prefix_4 {&lt;br /&gt;
	padding-left:320px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .prefix_5 {&lt;br /&gt;
	padding-left:400px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .prefix_6 {&lt;br /&gt;
	padding-left:480px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .prefix_7 {&lt;br /&gt;
	padding-left:560px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .prefix_8 {&lt;br /&gt;
	padding-left:640px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .prefix_9 {&lt;br /&gt;
	padding-left:720px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .prefix_10 {&lt;br /&gt;
	padding-left:800px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .prefix_11 {&lt;br /&gt;
	padding-left:880px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Suffix Extra Space &amp;gt;&amp;gt; 12 Columns&lt;br /&gt;
----------------------------------------------------------------------------------------------------*/&lt;br /&gt;
&lt;br /&gt;
.container_12 .suffix_1 {&lt;br /&gt;
	padding-right:80px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .suffix_2 {&lt;br /&gt;
	padding-right:160px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .suffix_3 {&lt;br /&gt;
	padding-right:240px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .suffix_4 {&lt;br /&gt;
	padding-right:320px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .suffix_5 {&lt;br /&gt;
	padding-right:400px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .suffix_6 {&lt;br /&gt;
	padding-right:480px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .suffix_7 {&lt;br /&gt;
	padding-right:560px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .suffix_8 {&lt;br /&gt;
	padding-right:640px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .suffix_9 {&lt;br /&gt;
	padding-right:720px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .suffix_10 {&lt;br /&gt;
	padding-right:800px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .suffix_11 {&lt;br /&gt;
	padding-right:880px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Push Space &amp;gt;&amp;gt; 12 Columns&lt;br /&gt;
----------------------------------------------------------------------------------------------------*/&lt;br /&gt;
&lt;br /&gt;
.container_12 .push_1 {&lt;br /&gt;
	left:80px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .push_2 {&lt;br /&gt;
	left:160px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .push_3 {&lt;br /&gt;
	left:240px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .push_4 {&lt;br /&gt;
	left:320px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .push_5 {&lt;br /&gt;
	left:400px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .push_6 {&lt;br /&gt;
	left:480px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .push_7 {&lt;br /&gt;
	left:560px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .push_8 {&lt;br /&gt;
	left:640px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .push_9 {&lt;br /&gt;
	left:720px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .push_10 {&lt;br /&gt;
	left:800px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .push_11 {&lt;br /&gt;
	left:880px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Pull Space &amp;gt;&amp;gt; 12 Columns&lt;br /&gt;
----------------------------------------------------------------------------------------------------*/&lt;br /&gt;
&lt;br /&gt;
.container_12 .pull_1 {&lt;br /&gt;
	left:-80px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .pull_2 {&lt;br /&gt;
	left:-160px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .pull_3 {&lt;br /&gt;
	left:-240px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .pull_4 {&lt;br /&gt;
	left:-320px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .pull_5 {&lt;br /&gt;
	left:-400px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .pull_6 {&lt;br /&gt;
	left:-480px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .pull_7 {&lt;br /&gt;
	left:-560px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .pull_8 {&lt;br /&gt;
	left:-640px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .pull_9 {&lt;br /&gt;
	left:-720px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .pull_10 {&lt;br /&gt;
	left:-800px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.container_12 .pull_11 {&lt;br /&gt;
	left:-880px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Clear Floated Elements&lt;br /&gt;
----------------------------------------------------------------------------------------------------*/&lt;br /&gt;
&lt;br /&gt;
/* http://sonspring.com/journal/clearing-floats */&lt;br /&gt;
&lt;br /&gt;
.clear {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	display: block;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	visibility: hidden;&lt;br /&gt;
	width: 0;&lt;br /&gt;
	height: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* http://perishablepress.com/press/2008/02/05/lessons-learned-concerning-the-clearfix-css-hack */&lt;br /&gt;
&lt;br /&gt;
.clearfix:after {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	content: &#039; &#039;;&lt;br /&gt;
	display: block;&lt;br /&gt;
	font-size: 0;&lt;br /&gt;
	line-height: 0;&lt;br /&gt;
	visibility: hidden;&lt;br /&gt;
	width: 0;&lt;br /&gt;
	height: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.clearfix {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
* html .clearfix {&lt;br /&gt;
	height: 1%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.clearfix {&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2492</id>
		<title>Operations grimoire/Deploy with Terraform</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Deploy_with_Terraform&amp;diff=2492"/>
		<updated>2026-03-22T23:18:13Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Propagate secrets (DRP) */ # Missing for router&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Where to work? ==&lt;br /&gt;
We deploy from [[Complector]] using &amp;lt;code&amp;gt;/opt/salt/nasqueron-operations&amp;lt;/code&amp;gt; as our local copy of rOPS, authoritative for both Salt and Terraform&lt;br /&gt;
&lt;br /&gt;
You need to belong to the &amp;lt;code&amp;gt;ops&amp;lt;/code&amp;gt; group to be able to have access and have write-rights on the repository&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to work from there to save a shared Terraform state.&lt;br /&gt;
&lt;br /&gt;
== Specific deployment notes ==&lt;br /&gt;
=== Vault / OpenBao ===&lt;br /&gt;
==== General notes ====&lt;br /&gt;
;OpenTofu support&lt;br /&gt;
As of 2026-02-07, the Vault provider isn&#039;t compiled for FreeBSD. You need to use Terraform instead.&lt;br /&gt;
&lt;br /&gt;
;Vault&lt;br /&gt;
You need a Vault token to allow the provider to connect.&lt;br /&gt;
&lt;br /&gt;
You also need to set VAULT_ADDR to https://172.27.27.7:8200 as Vault doesn&#039;t listen on 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ export VAULT_ADDR=https://172.27.27.7:8200&lt;br /&gt;
$ sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token&lt;br /&gt;
    &lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be interesting to maintain an alternative policy to admin for the Terraform provider, restricted to the current actions. Note benefits would be limited as those include policies management.&lt;br /&gt;
&lt;br /&gt;
==== Propagate secrets (DRP) ====&lt;br /&gt;
;No automatic secret rotation&lt;br /&gt;
Secrets rotation is disabled with a lifecycle management &amp;lt;code&amp;gt;ignore_changes = [ secret_id, ]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rotate a secret, it needs first to be destroyed from terraform state:&lt;br /&gt;
&amp;lt;code&amp;gt;terraform destroy -target=module.viperserv_approle.vault_approle_auth_backend_role_secret_id.this&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Full procedure &lt;br /&gt;
Once the AppRole have been created in Vault, they need to be provisioned to the relevant configuration files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations/terraform/openbao&lt;br /&gt;
$ terraform init # if you&#039;ve a new entry requiring a module, it needs to be installed&lt;br /&gt;
$ terraform plan&lt;br /&gt;
$ terraform apply&lt;br /&gt;
&lt;br /&gt;
$ cd /opt/salt/nasqueron-operations&lt;br /&gt;
$ salt windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config&lt;br /&gt;
$ salt windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config&lt;br /&gt;
# Missing for router&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Table of Terraform states ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Terraform and OpenBao states&lt;br /&gt;
|-&lt;br /&gt;
! Configuration !! State back-end !! Path !! Software to use&lt;br /&gt;
|-&lt;br /&gt;
| openbao || On disk || /opt/salt/nasqueron-operations/terraform/openbao/terraform.tfstate || Terraform&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On disk paths are stored in Complector.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Error: Module not installed ===&lt;br /&gt;
&lt;br /&gt;
You need to run &amp;lt;code&amp;gt;tofu init&amp;lt;/code&amp;gt; to prepare for any new provider.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu plan&lt;br /&gt;
&lt;br /&gt;
│ Error: Module not installed&lt;br /&gt;
│ &lt;br /&gt;
│   on rhyne_wyse.tf line 23:&lt;br /&gt;
│   23: module &amp;quot;rhyne_wyse_approle&amp;quot; {&lt;br /&gt;
│ &lt;br /&gt;
│ This module is not yet installed. Run &amp;quot;tofu init&amp;quot; to install all modules required by this configuration.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: Incompatible provider version ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ tofu init&lt;br /&gt;
&lt;br /&gt;
Initializing the backend...&lt;br /&gt;
Initializing modules...&lt;br /&gt;
- rhyne_wyse_approle in modules/app_credentials&lt;br /&gt;
&lt;br /&gt;
Initializing provider plugins...&lt;br /&gt;
- Finding hashicorp/vault versions matching &amp;quot;5.3.0&amp;quot;...&lt;br /&gt;
╷&lt;br /&gt;
│ Error: Incompatible provider version&lt;br /&gt;
│ &lt;br /&gt;
│ Provider registry.opentofu.org/hashicorp/vault v5.3.0 does not have a package available for your current platform, freebsd_amd64.&lt;br /&gt;
│ &lt;br /&gt;
│ Provider releases are separate from OpenTofu CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On OpenTofu, some modules are only compiled for Linux, not for FreeBSD.&lt;br /&gt;
Switch to Terraform pending a solution to help the OpenTofu builds.&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Terraform]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Vault&amp;diff=2490</id>
		<title>Operations grimoire/Vault</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Vault&amp;diff=2490"/>
		<updated>2026-03-22T18:59:45Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Get an admin-level token */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This page currently documents Vault installed on complector as part of {{Ops file|roles/vault/}}. It doesn&#039;t document Docker or shellserver installation. See [[Operations grimoire/Eglide/Vault]] and [[Dev zone/Vault]].&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Hashicorp Vault allows to manage credentials and is currently used:&lt;br /&gt;
&lt;br /&gt;
* to provision credentials through Salt &lt;br /&gt;
* to allow applications to fetch credentials&lt;br /&gt;
* to emit certificates for the private network applications&lt;br /&gt;
* to store credentials used by the Nasqueron Operations SIG beings&lt;br /&gt;
&lt;br /&gt;
Vault policies are fully managed through Salt in the operations repository.&lt;br /&gt;
&lt;br /&gt;
Vault has been selected in 2016 for secrets management.&lt;br /&gt;
&lt;br /&gt;
== Vault reference ==&lt;br /&gt;
=== kv engine ===&lt;br /&gt;
The kv engine contains the following paths:&lt;br /&gt;
&lt;br /&gt;
  * ops/secrets: credentials like passwords, API tokens, private keys deployed to servers - a reference for machines&lt;br /&gt;
  * ops/internal: credentials to third-party services internally shared amongst ops - a reference for humans&lt;br /&gt;
  * ops/privacy: privacy information&lt;br /&gt;
&lt;br /&gt;
==== Secrets ====&lt;br /&gt;
Secrets are directly and manually managed in Vault. If we need to run a disaster recovery procedure, we&#039;ll roll any secret by defining them again and deploy from rOPS those new secrets.&lt;br /&gt;
&lt;br /&gt;
==== Privacy data ====&lt;br /&gt;
Personal identity information (PII) shared inside the Nasqueron Operations squad are more convenient to manage as a repository.&lt;br /&gt;
&lt;br /&gt;
Such access to the repository is restricted to commit data, and ensure this data is deployed to the servers needing it. Any other use isn&#039;t allowed.&lt;br /&gt;
&lt;br /&gt;
Information to the repository is then published in Vault, and referred in rOPS as Vault credentials.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The ops/privacy path is only intended for PII of current or previous members of the Ops SIG, like IP addresses allowed to connect to restricted resources like the ops VPN. This is not acceptable to put 3rd party information in this repository.&lt;br /&gt;
&lt;br /&gt;
=== pki engine ===&lt;br /&gt;
Services listening to private IPs use the Vault PKI to generate certificates: &lt;br /&gt;
&lt;br /&gt;
* pki_root: root CA, certificate available at https://api.nasqueron.org/infra/security/pki/root/ca&lt;br /&gt;
* pki_vault: intermediate CA used for Vault itself&lt;br /&gt;
&lt;br /&gt;
Certificates should be issued short-term and frequently renewed by automated services.&lt;br /&gt;
&lt;br /&gt;
=== transit engine ===&lt;br /&gt;
Encryption as a service is available for applications under /transit path.&lt;br /&gt;
&lt;br /&gt;
See https://learn.hashicorp.com/tutorials/vault/eaas-transit.&lt;br /&gt;
&lt;br /&gt;
Applications should use a policy restricting to a subpath for that app, not to the whole engine.&lt;br /&gt;
&lt;br /&gt;
=== Users accounts ===&lt;br /&gt;
&lt;br /&gt;
Members of the Operations SIG need an access to Vault to create and maintain credentials.&lt;br /&gt;
&lt;br /&gt;
Currently, we use tokens. To generate a token:&lt;br /&gt;
&lt;br /&gt;
     vault token create -policy=admin&lt;br /&gt;
&lt;br /&gt;
To connect to Vault with a token from a devserver (e.g. WindRiver), you need:&lt;br /&gt;
&lt;br /&gt;
# Store the token in &amp;lt;code&amp;gt;$HOME/.vault-token&amp;lt;/code&amp;gt;&lt;br /&gt;
# Define environment variable VAULT_ADDR: &amp;lt;code&amp;gt;export VAULT_ADDR=https://172.27.27.7:8200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tokens need to be frequently renew (before expiration) with &amp;lt;code&amp;gt;vault renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Salt configuration ==&lt;br /&gt;
=== Get a secret through Salt ===&lt;br /&gt;
The information in the ops/secrets and ops/privacy kv engines are integrated in the Salt pillar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
ext_pillar:&lt;br /&gt;
  # Credentials to deploy to servers&lt;br /&gt;
  - vault:&lt;br /&gt;
       conf: path=ops/secrets&lt;br /&gt;
       nesting_key: credentials&lt;br /&gt;
&lt;br /&gt;
  # Personal identity information from Nasqueron Operations SIG members&lt;br /&gt;
  - vault:&lt;br /&gt;
       conf: path=ops/privacy&lt;br /&gt;
       nesting_key: privacy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then access to this information in Salt states using the following references:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Access to Salt data&lt;br /&gt;
|-&lt;br /&gt;
! Category !! Example of path in Vault !! Example of pillar key in Salt&lt;br /&gt;
|-&lt;br /&gt;
| Secrets || ops/secrets/foo || pillar[&#039;credentials&#039;][&#039;foo&#039;]&lt;br /&gt;
|-&lt;br /&gt;
| Privacy data || ops/privacy/ops-cidr || pillar[&#039;privacy&#039;][&#039;ops-cidr&#039;]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ops/internal paths aren&#039;t accessible through Vault.&lt;br /&gt;
&lt;br /&gt;
=== Policies ===&lt;br /&gt;
&lt;br /&gt;
Policies are managed in {{Ops file|pillar/credentials/vault.sls}}.&lt;br /&gt;
&lt;br /&gt;
For Salt, we deploy secrets to servers, policy management for a node consist to provide the list of secrets a role should have access to, generally in &#039;&#039;&#039;vault_secrets_by_role&#039;&#039;&#039; dictionary.&lt;br /&gt;
&lt;br /&gt;
For other applications:&lt;br /&gt;
* create a policy .hcl in &amp;lt;code&amp;gt;roles/vault/policies/files/&amp;lt;/code&amp;gt;&lt;br /&gt;
* declare the policy in the pillar under &amp;lt;code&amp;gt;vault_policies&amp;lt;/code&amp;gt; list, it should match the .hcl file (without the extension or the path)&lt;br /&gt;
* run the repository tests to check if both information matches ; to only run that part, use &amp;lt;code&amp;gt;cd _tests &amp;amp;&amp;amp; python3 -m unittest discover pillar/credentials/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To add only an application policy, Salt can be deployed like this:&lt;br /&gt;
&lt;br /&gt;
    salt complector state.sls_id vault_policy_airflow roles/vault/policies&lt;br /&gt;
&lt;br /&gt;
Salt policies can be tested by specifying the node name:&lt;br /&gt;
&lt;br /&gt;
    salt complector state.sls_id salt-node-windriver roles/vault/policies test=True&lt;br /&gt;
&lt;br /&gt;
=== DRP ===&lt;br /&gt;
Any step we need to do to configure the engines should be added to the {{ops file|roles/vault/bootstrap}} unit.&lt;br /&gt;
&lt;br /&gt;
If we need to recover Vault, two solutions are available:&lt;br /&gt;
* restore the storage, to keep data (credentials, certificates including the root CA one)&lt;br /&gt;
* recreate it from scratch through the roles/vault/bootstrap unit&lt;br /&gt;
&lt;br /&gt;
== Howto ==&lt;br /&gt;
=== Allow a new application to authenticate to Vault ===&lt;br /&gt;
Applications need a policy and an authentication method, for example here for an application called yourservice with AppRole with secret_id and role_id:&lt;br /&gt;
# Create a new policy in operations repository: {{D|3270}}&lt;br /&gt;
# Deploy it from Complector with &amp;lt;code&amp;gt;salt complector state.sls_id vault_policy_yourservice roles/vault/policies&amp;lt;/code&amp;gt;&lt;br /&gt;
# Create an approle matching that policy: &amp;lt;code&amp;gt;vault write auth/approle/role/yourservice token_policies=&amp;quot;yourservice&amp;quot; token_ttl=1h token_max_ttl=4h&amp;lt;/code&amp;gt;&lt;br /&gt;
# Get role_id with &amp;lt;code&amp;gt;vault read auth/approle/role/yourservice/role-id&amp;lt;/code&amp;gt;&lt;br /&gt;
# Get secret_id with &amp;lt;code&amp;gt;vault write -force auth/approle/role/yourservice/secret-id&amp;lt;/code&amp;gt;&lt;br /&gt;
# If you wish Salt to provision those credentials during your service deployment, probably a good idea to write them too: &amp;lt;code&amp;gt;vault kv put secrets/nasqueron/yourservice/vault username=role-id password=secret-id&amp;lt;/code&amp;gt; [to skip if you don&#039;t use Salt to provision role-id and secret-id]&lt;br /&gt;
&lt;br /&gt;
=== Get an admin-level token ===&lt;br /&gt;
Ops can use the self-service hvac script to get a token valid for 30 days:&lt;br /&gt;
&lt;br /&gt;
    ssh complector&lt;br /&gt;
    cd /opt/salt/nasqueron-operations&lt;br /&gt;
    sudo ./utils/vault/issue-admin-token.py&lt;br /&gt;
&lt;br /&gt;
If Vault certificate has expired, add the `--insecure` argument.&lt;br /&gt;
&lt;br /&gt;
You can also create a $HOME/bin/vault-login helper script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight language=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
touch $HOME/.vault-token&lt;br /&gt;
chmod 600 $HOME/.vault-token&lt;br /&gt;
ssh complector sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py | tr -d &#039;\n&#039; &amp;gt; $HOME/.vault-token&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Connecting to Vault ===&lt;br /&gt;
==== Access to web UI ====&lt;br /&gt;
Vault isn&#039;t listening any public IP, but accept connections from internal network, so you can open a SSH tunnel against &amp;lt;code&amp;gt;complector:8200&amp;lt;/code&amp;gt; and then browse https://localhost:8200:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ssh -L 8200:complector:8200 router-001.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== curl: (60) SSL certificate problem ====&lt;br /&gt;
Curl is compiled against a certificate bundle (&amp;lt;code&amp;gt;curl-config --ca&amp;lt;/code&amp;gt; for the path). That bundle doesn&#039;t contain the pki_root certificate. We deploy this certificate in /etc/ssl/certs, but curl won&#039;t check there if not instructed to. &lt;br /&gt;
&lt;br /&gt;
If you build an immutable environment like a container, add the certificate to the bundle.&lt;br /&gt;
&lt;br /&gt;
On other machines, create a curl configuration file in ~/.curlrc (it doesn&#039;t seem currently possible to create a system one) with &amp;lt;code&amp;gt;capath=/etc/ssl/certs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve still the issue after that, check two things:&lt;br /&gt;
* with &amp;lt;code&amp;gt;curl -v&amp;lt;/code&amp;gt;, the path should correctly there: &amp;lt;code&amp;gt;*  CApath: /etc/ssl/certs&amp;lt;/code&amp;gt; in addition to a CAfile.&lt;br /&gt;
* with &amp;lt;code&amp;gt;file /etc/ssl/certs/* | grep -i nasqueron&amp;lt;/code&amp;gt; you should have a result ; if not, put the certificate in /usr/local/share/certs and relaunch the tool to link it in /etc/ssl/certs, for example &amp;lt;code&amp;gt;certctl rehash&amp;lt;/code&amp;gt; on FreeBSD (needs root access).&lt;br /&gt;
&lt;br /&gt;
=== Certificates ===&lt;br /&gt;
==== How to unseal when certificate have expired? ====&lt;br /&gt;
Use the web UI through SSH tunnel.&lt;br /&gt;
&lt;br /&gt;
==== Renew Vault HTTP certificates ====&lt;br /&gt;
&lt;br /&gt;
Vault uses TLS certificates managed by its own CA. That can create a chicken/egg issue if certificates have expired to connect to it, as the Vault client strictly requires valid TLS certificated to issue commands to renew certificates.&lt;br /&gt;
&lt;br /&gt;
Connect to the web UI works as your browser is able to bypass certificate requirement. Opening a SSH tunnel with &amp;lt;code&amp;gt;-L 8200:complector:8200&amp;lt;/code&amp;gt; should work for that.&lt;br /&gt;
&lt;br /&gt;
Certificates configuration is available at [https://devcentral.nasqueron.org/D2639 D2639].&lt;br /&gt;
&lt;br /&gt;
The web UI doesn&#039;t offer a comprehensive sets of widgets to generate certificates. You can instead use the &#039;&#039;Vault Browser CLI&#039;&#039; to run Vault CLI commands from the web UI. The signing operation can be done through endpoint configuration UI.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: indianred; border: solid 3px black; color:white; font-size: large; padding: 2em;&amp;quot;&amp;gt;Automation for this part is being tested.&lt;br /&gt;
&lt;br /&gt;
You can preview automation proposal in /home/dereckson/sandbox/vault/renew-certificates on Complector.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Based on current D2639 state (2023-01), you can do the following:&lt;br /&gt;
* Has intermediate authority certificate expired? [old instructions, currently not valid anymore]&lt;br /&gt;
** Web console: &amp;lt;code&amp;gt;write -format=json pki_vault/intermediate/generate/internal common_name=&amp;quot;nasqueron.drake Intermediate Authority&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
** At https://localhost:8200/ui/vault/secrets/pki_vault/pki/roles/nasqueron-drake you can use the sign intermediate button to sign it, don&#039;t forget to fill the following information:&lt;br /&gt;
*** CSR, pick from console the .data.csr output from JSON response&lt;br /&gt;
*** Format: pem_bundle&lt;br /&gt;
*** TTL: 100 days&lt;br /&gt;
*** Common name: &amp;quot;nasqueron.drake Intermediate Authority&amp;quot;&lt;br /&gt;
*** Organization: Nasqueron&lt;br /&gt;
*** Organization unit: Nasqueron Operations SIG&lt;br /&gt;
*** Country: BE&lt;br /&gt;
** Follow the warning instruction: copy the certificate bundle, and in pki_vault, use Set signed intermediate to set the certificate as intermediate one. That will create a new issuer, fetch the name in &amp;quot;issuers&amp;quot;.&lt;br /&gt;
** Save also the certificate bundle to /usr/local/share/certs/nasqueron-vault-intermediate.crt&lt;br /&gt;
** Edit the nasqueron-drake role to use your new issuer name&lt;br /&gt;
* Has complector.nasqueron.drake certificate has expired?&lt;br /&gt;
** Web console: &amp;lt;code&amp;gt;write -format=json pki_vault/issue/nasqueron-drake common_name=complector.nasqueron.drake ttl=2160h ip_sans=127.0.0.1,172.27.27.7&amp;lt;/code&amp;gt;, save the output in /usr/local/etc/certificates/vault files:&lt;br /&gt;
*** .data.certificate to certificate.pem&lt;br /&gt;
*** .data.issuing_ca to ca.pem&lt;br /&gt;
*** .data.private_key to private.key (careful how you replace the \n, if you use Python REPL, do it on Complector itself and get rid of the history with &amp;lt;code&amp;gt;import readline ; readline.clear_history()&amp;lt;/code&amp;gt;)&lt;br /&gt;
** Prepare the fullchain bundle with &amp;lt;code&amp;gt;cat certificate.pem ca.pem &amp;gt; fullchain.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
** Send a SIGHUP signal to Vault to reload configuration with &amp;lt;code&amp;gt;kill -1 &amp;lt;Vault PID&amp;gt;&amp;lt;/code&amp;gt;, HTTP server should pick new certificate and you can know directly use the vault command. Vault configuration currently uses fullchain.pem and private.key.&lt;br /&gt;
&lt;br /&gt;
CSR uses &amp;lt;code&amp;gt;line1\nline2\nline3&amp;lt;/code&amp;gt; format in JSON. You can use a Python REPL with print(&amp;quot;...&amp;quot;) to print the CSR in several lines. CSR isn&#039;t confidential information, key is protected in Vault and never exposed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;jq.&#039;&#039;&#039; Another tool that can help is &amp;lt;code&amp;gt;jq&amp;lt;/code&amp;gt;. For example, &amp;lt;code&amp;gt;cat certificate.json | jq -r .data.certificate &amp;gt; /usr/local/etc/certificates/vault/certificate.pem&amp;lt;/code&amp;gt; will save it in multiline format.&lt;br /&gt;
&lt;br /&gt;
If you get an issue about private key missing at Set signed intermediate step, don&#039;t forget you&#039;re setting an intermediate certificate for pki_vault, and not for pki_root, set that here: https://localhost:8200/ui/vault/settings/secrets/configure/pki_vault/cert&lt;br /&gt;
&lt;br /&gt;
Paths where to store certificates matter:&lt;br /&gt;
* pki_root certificates are stored in /usr/local/share/certs&lt;br /&gt;
* pki_vault certificates are stored in /usr/local/etc/certificates/vault&lt;br /&gt;
&lt;br /&gt;
Ensure `private.key` belongs to user `vault` and receives a correct chmod like 400.&lt;br /&gt;
&lt;br /&gt;
==== Services known to break when a certificate is expired ====&lt;br /&gt;
&lt;br /&gt;
* Salt, but that&#039;s ad-hoc and explicit&lt;br /&gt;
* Sentry containers: &amp;lt;code&amp;gt;sudo docker ps -a | grep sentry | grep -v &amp;quot;Up &amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Salt ===&lt;br /&gt;
==== Policy for a node doesn&#039;t contain new secret entry ====&lt;br /&gt;
If the policies are attached to a new role:&lt;br /&gt;
&lt;br /&gt;
# Ensure new secret have been added for the right role in {{Ops file|pillar/credentials/vault.sls}}&lt;br /&gt;
#* If missing, validate afterwards with &amp;lt;code&amp;gt;salt complector pillar.get vault_secrets_by_role:yourrole&amp;lt;/code&amp;gt;&lt;br /&gt;
#* You need to refresh the pillar if still missing: &amp;lt;code&amp;gt;salt complector saltutil.refresh_pillar&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure role has been added to {{Ops file|pillar/nodes/nodes.sls}} and NetBox&lt;br /&gt;
#* If missing, refresh pillar afterwards&lt;br /&gt;
#* Validate with &amp;lt;code&amp;gt;salt complector node.get roles &amp;lt;server name&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
# Final check: &amp;lt;code&amp;gt;salt complector state.sls_id salt-node-&amp;lt;server name&amp;gt; roles/vault/policies test=True&amp;lt;/code&amp;gt;&lt;br /&gt;
# If diff is complicated to read, check the full policies document by role: &amp;lt;code&amp;gt;salt complector credentials.build_policies_by_node&amp;lt;/code&amp;gt;&lt;br /&gt;
#* Secret path present? Check the policy isn&#039;t already up-to-date: &amp;lt;code&amp;gt;vault policy read salt-node-&amp;lt;server name&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== credentials.vault_policy_present returns Bad Request ====&lt;br /&gt;
&lt;br /&gt;
Vault returns a 400 error if the policy format is incorrect.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Case 1.&#039;&#039;&#039; The state ID starts by &amp;lt;code&amp;gt;vault_policy_&amp;lt;/code&amp;gt;. You manually added a file to roles/vault/policies/file: this error means Vault API founds a syntax error in it. You can use https://github.com/mschuchard/linter-vault-policy if you use Pulsar (ex Atom) to lint those files.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Case 2.&#039;&#039;&#039; The state ID starts by anything else. The policy has been generated through _modules/credentials.py.&lt;br /&gt;
&lt;br /&gt;
Check if the pillar values added are correct:&lt;br /&gt;
* if not, add a test in &amp;lt;code&amp;gt;_tests/pillar/credentials/test_vault.py&amp;lt;/code&amp;gt; to detect the case&lt;br /&gt;
* if yes, there is an issue with the Python module code to fix&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example of Salt output.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
----------&lt;br /&gt;
          ID: vault_policy_admin&lt;br /&gt;
    Function: credentials.vault_policy_present&lt;br /&gt;
        Name: admin&lt;br /&gt;
      Result: False&lt;br /&gt;
     Comment: Failed to change policy: Bad Request&lt;br /&gt;
     Started: 13:45:14.162421&lt;br /&gt;
    Duration: 76.168 ms&lt;br /&gt;
     Changes:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Vault]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Vault&amp;diff=2489</id>
		<title>Operations grimoire/Vault</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Vault&amp;diff=2489"/>
		<updated>2026-03-22T18:57:55Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Get an admin-level token */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This page currently documents Vault installed on complector as part of {{Ops file|roles/vault/}}. It doesn&#039;t document Docker or shellserver installation. See [[Operations grimoire/Eglide/Vault]] and [[Dev zone/Vault]].&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Hashicorp Vault allows to manage credentials and is currently used:&lt;br /&gt;
&lt;br /&gt;
* to provision credentials through Salt &lt;br /&gt;
* to allow applications to fetch credentials&lt;br /&gt;
* to emit certificates for the private network applications&lt;br /&gt;
* to store credentials used by the Nasqueron Operations SIG beings&lt;br /&gt;
&lt;br /&gt;
Vault policies are fully managed through Salt in the operations repository.&lt;br /&gt;
&lt;br /&gt;
Vault has been selected in 2016 for secrets management.&lt;br /&gt;
&lt;br /&gt;
== Vault reference ==&lt;br /&gt;
=== kv engine ===&lt;br /&gt;
The kv engine contains the following paths:&lt;br /&gt;
&lt;br /&gt;
  * ops/secrets: credentials like passwords, API tokens, private keys deployed to servers - a reference for machines&lt;br /&gt;
  * ops/internal: credentials to third-party services internally shared amongst ops - a reference for humans&lt;br /&gt;
  * ops/privacy: privacy information&lt;br /&gt;
&lt;br /&gt;
==== Secrets ====&lt;br /&gt;
Secrets are directly and manually managed in Vault. If we need to run a disaster recovery procedure, we&#039;ll roll any secret by defining them again and deploy from rOPS those new secrets.&lt;br /&gt;
&lt;br /&gt;
==== Privacy data ====&lt;br /&gt;
Personal identity information (PII) shared inside the Nasqueron Operations squad are more convenient to manage as a repository.&lt;br /&gt;
&lt;br /&gt;
Such access to the repository is restricted to commit data, and ensure this data is deployed to the servers needing it. Any other use isn&#039;t allowed.&lt;br /&gt;
&lt;br /&gt;
Information to the repository is then published in Vault, and referred in rOPS as Vault credentials.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The ops/privacy path is only intended for PII of current or previous members of the Ops SIG, like IP addresses allowed to connect to restricted resources like the ops VPN. This is not acceptable to put 3rd party information in this repository.&lt;br /&gt;
&lt;br /&gt;
=== pki engine ===&lt;br /&gt;
Services listening to private IPs use the Vault PKI to generate certificates: &lt;br /&gt;
&lt;br /&gt;
* pki_root: root CA, certificate available at https://api.nasqueron.org/infra/security/pki/root/ca&lt;br /&gt;
* pki_vault: intermediate CA used for Vault itself&lt;br /&gt;
&lt;br /&gt;
Certificates should be issued short-term and frequently renewed by automated services.&lt;br /&gt;
&lt;br /&gt;
=== transit engine ===&lt;br /&gt;
Encryption as a service is available for applications under /transit path.&lt;br /&gt;
&lt;br /&gt;
See https://learn.hashicorp.com/tutorials/vault/eaas-transit.&lt;br /&gt;
&lt;br /&gt;
Applications should use a policy restricting to a subpath for that app, not to the whole engine.&lt;br /&gt;
&lt;br /&gt;
=== Users accounts ===&lt;br /&gt;
&lt;br /&gt;
Members of the Operations SIG need an access to Vault to create and maintain credentials.&lt;br /&gt;
&lt;br /&gt;
Currently, we use tokens. To generate a token:&lt;br /&gt;
&lt;br /&gt;
     vault token create -policy=admin&lt;br /&gt;
&lt;br /&gt;
To connect to Vault with a token from a devserver (e.g. WindRiver), you need:&lt;br /&gt;
&lt;br /&gt;
# Store the token in &amp;lt;code&amp;gt;$HOME/.vault-token&amp;lt;/code&amp;gt;&lt;br /&gt;
# Define environment variable VAULT_ADDR: &amp;lt;code&amp;gt;export VAULT_ADDR=https://172.27.27.7:8200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tokens need to be frequently renew (before expiration) with &amp;lt;code&amp;gt;vault renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Salt configuration ==&lt;br /&gt;
=== Get a secret through Salt ===&lt;br /&gt;
The information in the ops/secrets and ops/privacy kv engines are integrated in the Salt pillar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
ext_pillar:&lt;br /&gt;
  # Credentials to deploy to servers&lt;br /&gt;
  - vault:&lt;br /&gt;
       conf: path=ops/secrets&lt;br /&gt;
       nesting_key: credentials&lt;br /&gt;
&lt;br /&gt;
  # Personal identity information from Nasqueron Operations SIG members&lt;br /&gt;
  - vault:&lt;br /&gt;
       conf: path=ops/privacy&lt;br /&gt;
       nesting_key: privacy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then access to this information in Salt states using the following references:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Access to Salt data&lt;br /&gt;
|-&lt;br /&gt;
! Category !! Example of path in Vault !! Example of pillar key in Salt&lt;br /&gt;
|-&lt;br /&gt;
| Secrets || ops/secrets/foo || pillar[&#039;credentials&#039;][&#039;foo&#039;]&lt;br /&gt;
|-&lt;br /&gt;
| Privacy data || ops/privacy/ops-cidr || pillar[&#039;privacy&#039;][&#039;ops-cidr&#039;]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ops/internal paths aren&#039;t accessible through Vault.&lt;br /&gt;
&lt;br /&gt;
=== Policies ===&lt;br /&gt;
&lt;br /&gt;
Policies are managed in {{Ops file|pillar/credentials/vault.sls}}.&lt;br /&gt;
&lt;br /&gt;
For Salt, we deploy secrets to servers, policy management for a node consist to provide the list of secrets a role should have access to, generally in &#039;&#039;&#039;vault_secrets_by_role&#039;&#039;&#039; dictionary.&lt;br /&gt;
&lt;br /&gt;
For other applications:&lt;br /&gt;
* create a policy .hcl in &amp;lt;code&amp;gt;roles/vault/policies/files/&amp;lt;/code&amp;gt;&lt;br /&gt;
* declare the policy in the pillar under &amp;lt;code&amp;gt;vault_policies&amp;lt;/code&amp;gt; list, it should match the .hcl file (without the extension or the path)&lt;br /&gt;
* run the repository tests to check if both information matches ; to only run that part, use &amp;lt;code&amp;gt;cd _tests &amp;amp;&amp;amp; python3 -m unittest discover pillar/credentials/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To add only an application policy, Salt can be deployed like this:&lt;br /&gt;
&lt;br /&gt;
    salt complector state.sls_id vault_policy_airflow roles/vault/policies&lt;br /&gt;
&lt;br /&gt;
Salt policies can be tested by specifying the node name:&lt;br /&gt;
&lt;br /&gt;
    salt complector state.sls_id salt-node-windriver roles/vault/policies test=True&lt;br /&gt;
&lt;br /&gt;
=== DRP ===&lt;br /&gt;
Any step we need to do to configure the engines should be added to the {{ops file|roles/vault/bootstrap}} unit.&lt;br /&gt;
&lt;br /&gt;
If we need to recover Vault, two solutions are available:&lt;br /&gt;
* restore the storage, to keep data (credentials, certificates including the root CA one)&lt;br /&gt;
* recreate it from scratch through the roles/vault/bootstrap unit&lt;br /&gt;
&lt;br /&gt;
== Howto ==&lt;br /&gt;
=== Allow a new application to authenticate to Vault ===&lt;br /&gt;
Applications need a policy and an authentication method, for example here for an application called yourservice with AppRole with secret_id and role_id:&lt;br /&gt;
# Create a new policy in operations repository: {{D|3270}}&lt;br /&gt;
# Deploy it from Complector with &amp;lt;code&amp;gt;salt complector state.sls_id vault_policy_yourservice roles/vault/policies&amp;lt;/code&amp;gt;&lt;br /&gt;
# Create an approle matching that policy: &amp;lt;code&amp;gt;vault write auth/approle/role/yourservice token_policies=&amp;quot;yourservice&amp;quot; token_ttl=1h token_max_ttl=4h&amp;lt;/code&amp;gt;&lt;br /&gt;
# Get role_id with &amp;lt;code&amp;gt;vault read auth/approle/role/yourservice/role-id&amp;lt;/code&amp;gt;&lt;br /&gt;
# Get secret_id with &amp;lt;code&amp;gt;vault write -force auth/approle/role/yourservice/secret-id&amp;lt;/code&amp;gt;&lt;br /&gt;
# If you wish Salt to provision those credentials during your service deployment, probably a good idea to write them too: &amp;lt;code&amp;gt;vault kv put secrets/nasqueron/yourservice/vault username=role-id password=secret-id&amp;lt;/code&amp;gt; [to skip if you don&#039;t use Salt to provision role-id and secret-id]&lt;br /&gt;
&lt;br /&gt;
=== Get an admin-level token ===&lt;br /&gt;
Ops can use the self-service hvac script to get a token valid for 30 days:&lt;br /&gt;
&lt;br /&gt;
    ssh complector&lt;br /&gt;
    cd /opt/salt/nasqueron-operations&lt;br /&gt;
    sudo ./utils/vault/issue-admin-token.py&lt;br /&gt;
&lt;br /&gt;
If Vault certificate has expired, add the `--insecure` argument.&lt;br /&gt;
&lt;br /&gt;
You can also automate this as a oneliner to store the token in the default token file:&lt;br /&gt;
&lt;br /&gt;
    ssh complector sudo /opt/salt/nasqueron-operations/utils/vault/issue-admin-token.py &amp;gt; ~/.vault-token ; chmod 600 ~/.vault-token&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Connecting to Vault ===&lt;br /&gt;
==== Access to web UI ====&lt;br /&gt;
Vault isn&#039;t listening any public IP, but accept connections from internal network, so you can open a SSH tunnel against &amp;lt;code&amp;gt;complector:8200&amp;lt;/code&amp;gt; and then browse https://localhost:8200:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ssh -L 8200:complector:8200 router-001.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== curl: (60) SSL certificate problem ====&lt;br /&gt;
Curl is compiled against a certificate bundle (&amp;lt;code&amp;gt;curl-config --ca&amp;lt;/code&amp;gt; for the path). That bundle doesn&#039;t contain the pki_root certificate. We deploy this certificate in /etc/ssl/certs, but curl won&#039;t check there if not instructed to. &lt;br /&gt;
&lt;br /&gt;
If you build an immutable environment like a container, add the certificate to the bundle.&lt;br /&gt;
&lt;br /&gt;
On other machines, create a curl configuration file in ~/.curlrc (it doesn&#039;t seem currently possible to create a system one) with &amp;lt;code&amp;gt;capath=/etc/ssl/certs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve still the issue after that, check two things:&lt;br /&gt;
* with &amp;lt;code&amp;gt;curl -v&amp;lt;/code&amp;gt;, the path should correctly there: &amp;lt;code&amp;gt;*  CApath: /etc/ssl/certs&amp;lt;/code&amp;gt; in addition to a CAfile.&lt;br /&gt;
* with &amp;lt;code&amp;gt;file /etc/ssl/certs/* | grep -i nasqueron&amp;lt;/code&amp;gt; you should have a result ; if not, put the certificate in /usr/local/share/certs and relaunch the tool to link it in /etc/ssl/certs, for example &amp;lt;code&amp;gt;certctl rehash&amp;lt;/code&amp;gt; on FreeBSD (needs root access).&lt;br /&gt;
&lt;br /&gt;
=== Certificates ===&lt;br /&gt;
==== How to unseal when certificate have expired? ====&lt;br /&gt;
Use the web UI through SSH tunnel.&lt;br /&gt;
&lt;br /&gt;
==== Renew Vault HTTP certificates ====&lt;br /&gt;
&lt;br /&gt;
Vault uses TLS certificates managed by its own CA. That can create a chicken/egg issue if certificates have expired to connect to it, as the Vault client strictly requires valid TLS certificated to issue commands to renew certificates.&lt;br /&gt;
&lt;br /&gt;
Connect to the web UI works as your browser is able to bypass certificate requirement. Opening a SSH tunnel with &amp;lt;code&amp;gt;-L 8200:complector:8200&amp;lt;/code&amp;gt; should work for that.&lt;br /&gt;
&lt;br /&gt;
Certificates configuration is available at [https://devcentral.nasqueron.org/D2639 D2639].&lt;br /&gt;
&lt;br /&gt;
The web UI doesn&#039;t offer a comprehensive sets of widgets to generate certificates. You can instead use the &#039;&#039;Vault Browser CLI&#039;&#039; to run Vault CLI commands from the web UI. The signing operation can be done through endpoint configuration UI.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: indianred; border: solid 3px black; color:white; font-size: large; padding: 2em;&amp;quot;&amp;gt;Automation for this part is being tested.&lt;br /&gt;
&lt;br /&gt;
You can preview automation proposal in /home/dereckson/sandbox/vault/renew-certificates on Complector.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Based on current D2639 state (2023-01), you can do the following:&lt;br /&gt;
* Has intermediate authority certificate expired? [old instructions, currently not valid anymore]&lt;br /&gt;
** Web console: &amp;lt;code&amp;gt;write -format=json pki_vault/intermediate/generate/internal common_name=&amp;quot;nasqueron.drake Intermediate Authority&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
** At https://localhost:8200/ui/vault/secrets/pki_vault/pki/roles/nasqueron-drake you can use the sign intermediate button to sign it, don&#039;t forget to fill the following information:&lt;br /&gt;
*** CSR, pick from console the .data.csr output from JSON response&lt;br /&gt;
*** Format: pem_bundle&lt;br /&gt;
*** TTL: 100 days&lt;br /&gt;
*** Common name: &amp;quot;nasqueron.drake Intermediate Authority&amp;quot;&lt;br /&gt;
*** Organization: Nasqueron&lt;br /&gt;
*** Organization unit: Nasqueron Operations SIG&lt;br /&gt;
*** Country: BE&lt;br /&gt;
** Follow the warning instruction: copy the certificate bundle, and in pki_vault, use Set signed intermediate to set the certificate as intermediate one. That will create a new issuer, fetch the name in &amp;quot;issuers&amp;quot;.&lt;br /&gt;
** Save also the certificate bundle to /usr/local/share/certs/nasqueron-vault-intermediate.crt&lt;br /&gt;
** Edit the nasqueron-drake role to use your new issuer name&lt;br /&gt;
* Has complector.nasqueron.drake certificate has expired?&lt;br /&gt;
** Web console: &amp;lt;code&amp;gt;write -format=json pki_vault/issue/nasqueron-drake common_name=complector.nasqueron.drake ttl=2160h ip_sans=127.0.0.1,172.27.27.7&amp;lt;/code&amp;gt;, save the output in /usr/local/etc/certificates/vault files:&lt;br /&gt;
*** .data.certificate to certificate.pem&lt;br /&gt;
*** .data.issuing_ca to ca.pem&lt;br /&gt;
*** .data.private_key to private.key (careful how you replace the \n, if you use Python REPL, do it on Complector itself and get rid of the history with &amp;lt;code&amp;gt;import readline ; readline.clear_history()&amp;lt;/code&amp;gt;)&lt;br /&gt;
** Prepare the fullchain bundle with &amp;lt;code&amp;gt;cat certificate.pem ca.pem &amp;gt; fullchain.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
** Send a SIGHUP signal to Vault to reload configuration with &amp;lt;code&amp;gt;kill -1 &amp;lt;Vault PID&amp;gt;&amp;lt;/code&amp;gt;, HTTP server should pick new certificate and you can know directly use the vault command. Vault configuration currently uses fullchain.pem and private.key.&lt;br /&gt;
&lt;br /&gt;
CSR uses &amp;lt;code&amp;gt;line1\nline2\nline3&amp;lt;/code&amp;gt; format in JSON. You can use a Python REPL with print(&amp;quot;...&amp;quot;) to print the CSR in several lines. CSR isn&#039;t confidential information, key is protected in Vault and never exposed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;jq.&#039;&#039;&#039; Another tool that can help is &amp;lt;code&amp;gt;jq&amp;lt;/code&amp;gt;. For example, &amp;lt;code&amp;gt;cat certificate.json | jq -r .data.certificate &amp;gt; /usr/local/etc/certificates/vault/certificate.pem&amp;lt;/code&amp;gt; will save it in multiline format.&lt;br /&gt;
&lt;br /&gt;
If you get an issue about private key missing at Set signed intermediate step, don&#039;t forget you&#039;re setting an intermediate certificate for pki_vault, and not for pki_root, set that here: https://localhost:8200/ui/vault/settings/secrets/configure/pki_vault/cert&lt;br /&gt;
&lt;br /&gt;
Paths where to store certificates matter:&lt;br /&gt;
* pki_root certificates are stored in /usr/local/share/certs&lt;br /&gt;
* pki_vault certificates are stored in /usr/local/etc/certificates/vault&lt;br /&gt;
&lt;br /&gt;
Ensure `private.key` belongs to user `vault` and receives a correct chmod like 400.&lt;br /&gt;
&lt;br /&gt;
==== Services known to break when a certificate is expired ====&lt;br /&gt;
&lt;br /&gt;
* Salt, but that&#039;s ad-hoc and explicit&lt;br /&gt;
* Sentry containers: &amp;lt;code&amp;gt;sudo docker ps -a | grep sentry | grep -v &amp;quot;Up &amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Salt ===&lt;br /&gt;
==== Policy for a node doesn&#039;t contain new secret entry ====&lt;br /&gt;
If the policies are attached to a new role:&lt;br /&gt;
&lt;br /&gt;
# Ensure new secret have been added for the right role in {{Ops file|pillar/credentials/vault.sls}}&lt;br /&gt;
#* If missing, validate afterwards with &amp;lt;code&amp;gt;salt complector pillar.get vault_secrets_by_role:yourrole&amp;lt;/code&amp;gt;&lt;br /&gt;
#* You need to refresh the pillar if still missing: &amp;lt;code&amp;gt;salt complector saltutil.refresh_pillar&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure role has been added to {{Ops file|pillar/nodes/nodes.sls}} and NetBox&lt;br /&gt;
#* If missing, refresh pillar afterwards&lt;br /&gt;
#* Validate with &amp;lt;code&amp;gt;salt complector node.get roles &amp;lt;server name&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
# Final check: &amp;lt;code&amp;gt;salt complector state.sls_id salt-node-&amp;lt;server name&amp;gt; roles/vault/policies test=True&amp;lt;/code&amp;gt;&lt;br /&gt;
# If diff is complicated to read, check the full policies document by role: &amp;lt;code&amp;gt;salt complector credentials.build_policies_by_node&amp;lt;/code&amp;gt;&lt;br /&gt;
#* Secret path present? Check the policy isn&#039;t already up-to-date: &amp;lt;code&amp;gt;vault policy read salt-node-&amp;lt;server name&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== credentials.vault_policy_present returns Bad Request ====&lt;br /&gt;
&lt;br /&gt;
Vault returns a 400 error if the policy format is incorrect.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Case 1.&#039;&#039;&#039; The state ID starts by &amp;lt;code&amp;gt;vault_policy_&amp;lt;/code&amp;gt;. You manually added a file to roles/vault/policies/file: this error means Vault API founds a syntax error in it. You can use https://github.com/mschuchard/linter-vault-policy if you use Pulsar (ex Atom) to lint those files.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Case 2.&#039;&#039;&#039; The state ID starts by anything else. The policy has been generated through _modules/credentials.py.&lt;br /&gt;
&lt;br /&gt;
Check if the pillar values added are correct:&lt;br /&gt;
* if not, add a test in &amp;lt;code&amp;gt;_tests/pillar/credentials/test_vault.py&amp;lt;/code&amp;gt; to detect the case&lt;br /&gt;
* if yes, there is an issue with the Python module code to fix&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example of Salt output.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
----------&lt;br /&gt;
          ID: vault_policy_admin&lt;br /&gt;
    Function: credentials.vault_policy_present&lt;br /&gt;
        Name: admin&lt;br /&gt;
      Result: False&lt;br /&gt;
     Comment: Failed to change policy: Bad Request&lt;br /&gt;
     Started: 13:45:14.162421&lt;br /&gt;
    Duration: 76.168 ms&lt;br /&gt;
     Changes:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Vault]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Wearg&amp;diff=2488</id>
		<title>Wearg</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Wearg&amp;diff=2488"/>
		<updated>2026-03-21T09:48:02Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* MariaDB server connectivity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wearg is an eggdrop and a notifications client.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
Wearg handles two important workflows for the Nasqueron Operations SIG:&lt;br /&gt;
&lt;br /&gt;
* Publish notifications on IRC channels: Services --HTTPS--&amp;gt; [[Operations grimoire/Notifications center|Notifications center]] --AMQP--&amp;gt; [[Operations grimoire/RabbitMQ|broker]] --AMQP--&amp;gt; Wearg --IRC--&amp;gt; Channel publication&lt;br /&gt;
* Allow to log to servers log: Channel publication --HTTPS--&amp;gt; Nasqueron API --IO--&amp;gt; servers log&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== No messages are received ===&lt;br /&gt;
Check through another client (the CLI client for example) all works fine at notifications center and broker level.&lt;br /&gt;
&lt;br /&gt;
If so:&lt;br /&gt;
&lt;br /&gt;
# Check we&#039;re connected through &amp;lt;code&amp;gt;.tcl mq connected&amp;lt;/code&amp;gt;&lt;br /&gt;
# If so, disconnect it with &amp;lt;code&amp;gt;.tcl mq disconnect&amp;lt;/code&amp;gt;&lt;br /&gt;
# Check timer through .tcl utimers, you should have one (and only one) timer with ::broker::on_tick as callback&lt;br /&gt;
## Too many timers? kill extra timers with &amp;lt;code&amp;gt;.tcl killutimer timer&amp;lt;id&amp;gt;&amp;lt;/code&amp;gt;, good luck for the guess the second game&lt;br /&gt;
## No timer? &amp;lt;code&amp;gt;.tcl broker::on_tick&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ask next message in the queue .tcl mq get wearg-notifications&lt;br /&gt;
# If stuck at the previous operation, close the connection through the broker interface: http://white-rabbit.nasqueron.org:15672/#/connections (username is daeghrefn, source IP is 212.83.187.132). This method is pretty effective&lt;br /&gt;
&lt;br /&gt;
=== Can&#039;t publish to servers log ===&lt;br /&gt;
==== MariaDB server connectivity ====&lt;br /&gt;
&lt;br /&gt;
If the MariaDB connection is broken, &amp;lt;code&amp;gt;.+log [server] message works&amp;lt;/code&amp;gt;, but not directly &amp;lt;code&amp;gt;[server] message&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Short-term solution: &amp;lt;code&amp;gt;.tcl sqlrehash&amp;lt;/code&amp;gt; in the Wearg partyline&lt;br /&gt;
* Long-term solution: automate reconnect with {{T|2282}}&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Wearg&amp;diff=2487</id>
		<title>Wearg</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Wearg&amp;diff=2487"/>
		<updated>2026-03-21T09:47:30Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wearg is an eggdrop and a notifications client.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
Wearg handles two important workflows for the Nasqueron Operations SIG:&lt;br /&gt;
&lt;br /&gt;
* Publish notifications on IRC channels: Services --HTTPS--&amp;gt; [[Operations grimoire/Notifications center|Notifications center]] --AMQP--&amp;gt; [[Operations grimoire/RabbitMQ|broker]] --AMQP--&amp;gt; Wearg --IRC--&amp;gt; Channel publication&lt;br /&gt;
* Allow to log to servers log: Channel publication --HTTPS--&amp;gt; Nasqueron API --IO--&amp;gt; servers log&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== No messages are received ===&lt;br /&gt;
Check through another client (the CLI client for example) all works fine at notifications center and broker level.&lt;br /&gt;
&lt;br /&gt;
If so:&lt;br /&gt;
&lt;br /&gt;
# Check we&#039;re connected through &amp;lt;code&amp;gt;.tcl mq connected&amp;lt;/code&amp;gt;&lt;br /&gt;
# If so, disconnect it with &amp;lt;code&amp;gt;.tcl mq disconnect&amp;lt;/code&amp;gt;&lt;br /&gt;
# Check timer through .tcl utimers, you should have one (and only one) timer with ::broker::on_tick as callback&lt;br /&gt;
## Too many timers? kill extra timers with &amp;lt;code&amp;gt;.tcl killutimer timer&amp;lt;id&amp;gt;&amp;lt;/code&amp;gt;, good luck for the guess the second game&lt;br /&gt;
## No timer? &amp;lt;code&amp;gt;.tcl broker::on_tick&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ask next message in the queue .tcl mq get wearg-notifications&lt;br /&gt;
# If stuck at the previous operation, close the connection through the broker interface: http://white-rabbit.nasqueron.org:15672/#/connections (username is daeghrefn, source IP is 212.83.187.132). This method is pretty effective&lt;br /&gt;
&lt;br /&gt;
=== Can&#039;t publish to servers log ===&lt;br /&gt;
==== MariaDB server connectivity ====&lt;br /&gt;
&lt;br /&gt;
If the MariaDB connection is broken, &amp;lt;code&amp;gt;.+log [server] message works&amp;lt;/code&amp;gt;, but not directly &amp;lt;code&amp;gt;[server] message&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Short-term solution: &amp;lt;code&amp;gt;.tcl sqlrehash&amp;lt;/code&amp;gt; in the Wearg partyline&lt;br /&gt;
Long-term solution: {{T|2282}}&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Code_conventions&amp;diff=2486</id>
		<title>Code conventions</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Code_conventions&amp;diff=2486"/>
		<updated>2026-03-20T01:47:16Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Makefile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== All languages ==&lt;br /&gt;
&lt;br /&gt;
* Don&#039;t use more complicated constructs like ternary operators&lt;br /&gt;
* [http://jeroendedauw.github.io/slides/craftmanship/functions/#/1 Keep functions short and simple].&lt;br /&gt;
* Define explicitly methods visibility, as several languages have different default values (e.g. private for C# class members, public for PHP methods)&lt;br /&gt;
* Comments to document a method are written at the singular 3rd person (we seem to have moved to infinitive recently, we need to take a decision here)&lt;br /&gt;
&lt;br /&gt;
== C ==&lt;br /&gt;
If you use [http://clang.llvm.org/docs/ClangFormat.html ClangFormat], a [https://github.com/dereckson/rabbitmq-tcl/blob/master/.clang-format .clang-format file] is available.&lt;br /&gt;
&lt;br /&gt;
== JavaScript ==&lt;br /&gt;
The following conventions are used:&lt;br /&gt;
* K&amp;amp;R, 1TBS variant, including for functions&lt;br /&gt;
* 4 spaces as indent&lt;br /&gt;
* Use modern JavaScript idioms like &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt;&lt;br /&gt;
* Consider to use async code for events-driven development, especially for servers&lt;br /&gt;
&lt;br /&gt;
== PHP ==&lt;br /&gt;
The following conventions are used:&lt;br /&gt;
* K&amp;amp;R, 1TBS variant, including for functions&lt;br /&gt;
* 4 spaces as indent&lt;br /&gt;
* The keywords &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; must be in lower case.&lt;br /&gt;
* Arrays use short syntax&lt;br /&gt;
* Array elements ends with a comma&lt;br /&gt;
* Functions, methods and class names use camel case &lt;br /&gt;
&lt;br /&gt;
If you use PhpStorm or another JetBrains IDE, you can import [https://github.com/nasqueron/codestyle/blob/master/JetBrains/php-codestyle.xml JetBrains/php-codestyle.xml] from the codestyle repository as a code style (Settings or Default Settings &amp;gt; Editor &amp;gt; Code Style &amp;gt; PHP &amp;gt; click on the wheel icon &amp;gt; Import Scheme &amp;gt; Intellij IDEA codestyle XML).&lt;br /&gt;
&lt;br /&gt;
If you want to lint a project with phpcs, you can require the Composer package &amp;lt;code&amp;gt;nasqueron/codestyle&amp;lt;/code&amp;gt; and use the following &amp;lt;kbd&amp;gt;phpcs.xml&amp;lt;kbd&amp;gt; standard file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;ruleset&amp;gt;&lt;br /&gt;
    &amp;lt;rule ref=&amp;quot;vendor/nasqueron/codestyle/CodeSniffer&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;file&amp;gt;.&amp;lt;/file&amp;gt;&lt;br /&gt;
    &amp;lt;exclude-pattern&amp;gt;\.git/&amp;lt;/exclude-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;exclude-pattern&amp;gt;vendor/&amp;lt;/exclude-pattern&amp;gt;&lt;br /&gt;
&amp;lt;/ruleset&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python ==&lt;br /&gt;
=== Code style ===&lt;br /&gt;
&#039;&#039;&#039;2023.&#039;&#039;&#039; We follow [https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html black style], so use black utility (&amp;lt;code&amp;gt;pip install black&amp;lt;/code&amp;gt;). As such, you need to configure Flake8 to ignore rule E203.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2015.&#039;&#039;&#039; We follow [https://www.python.org/dev/peps/pep-0008/ PEP-8].&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
A template exists for a new Python command: [https://devcentral.nasqueron.org/source/snippets/browse/main/python/command.py python/command.py]&lt;br /&gt;
&lt;br /&gt;
In packages, empty __init__.py files can follow [https://devcentral.nasqueron.org/source/merge-dictionaries/browse/main/src/mergedictionaries/utils/__init__.py;eaf5bc2c21118454837e8148147606c19d4afff7 this example].&lt;br /&gt;
&lt;br /&gt;
=== Configuration files ===&lt;br /&gt;
Allow empty configuration files. For example, the YAML parser will return None if the file exists but is empty, we can catch that and return default instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
         with open(get_configuration_path()) as fd:&lt;br /&gt;
            return yaml.safe_load(fd) or {}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rust ==&lt;br /&gt;
&#039;&#039;&#039;2023.&#039;&#039;&#039; Automated codestyle (black in Python, clang-format in Rust) seems preferable. As such, a style compatible with &amp;lt;code&amp;gt;rustfmt&amp;lt;/code&amp;gt; is needed to be able to format using &amp;lt;code&amp;gt;cargo fmt&amp;lt;/code&amp;gt;. You can add to your project  [https://devcentral.nasqueron.org/source/codestyle/browse/main/rust/rustfmt.toml rust/rustfmt.toml in codestyle] to configure it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2015.&#039;&#039;&#039; We followed &amp;quot;Rust default style&amp;quot;, described at [https://web.archive.org/web/20170320083740/http://aturon.github.io/ https://aturon.github.io/]. It&#039;s mainly a K&amp;amp;R, 1TBS variant.&lt;br /&gt;
&lt;br /&gt;
Use trailing comma for elements in every struct/impl/etc.&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
Standard library isn&#039;t the most ergonomic for threads programming, those crate allows more efficient and legible code:&lt;br /&gt;
* [https://docs.rs/crossbeam-channel/latest/crossbeam_channel/ crossbeam_channel] for mpmc (multiple producers, multiple consumers)&lt;br /&gt;
* [https://docs.rs/parking_lot/latest/parking_lot/type.Mutex.html parking_lot] for Mutex&lt;br /&gt;
&lt;br /&gt;
== Salt ==&lt;br /&gt;
=== Style ===&lt;br /&gt;
Whitespaces:&lt;br /&gt;
* Indent with two spaces&lt;br /&gt;
* YAML lists use indented bullets&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
id:&lt;br /&gt;
  method:&lt;br /&gt;
    - somekey: value&lt;br /&gt;
    - otherkey: value&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
&lt;br /&gt;
;Files provisioned&lt;br /&gt;
* When you ask to download a file remotely, you need a source hash, pick SHA256 as algo&lt;br /&gt;
* Each file provisioned from the Salt repository must contains an header explaining the fact, with the full path in the rOPS repo&lt;br /&gt;
&lt;br /&gt;
;BSD and Linux distros compatible states&lt;br /&gt;
* populate the map.jinja file with OS logic (e.g. `dirs` for /etc vs /usr/local/etc)&lt;br /&gt;
* when you&#039;ve a specific set of tasks to do for one OS/distro, it&#039;s acceptable to enclose it in a state by an if block&lt;br /&gt;
&lt;br /&gt;
=== Vocabulary ===&lt;br /&gt;
&lt;br /&gt;
;Domain names&lt;br /&gt;
:To refer to the fully qualified domain name sub.domain.tld, use &#039;&#039;&#039;fqdn&#039;&#039;&#039;. To split the domains in part, use &#039;&#039;&#039;domain&#039;&#039;&#039; and &#039;&#039;&#039;subdomain&#039;&#039;&#039;. This is important to understand a state without having  to refer to the associated pillar to disambig domain.&lt;br /&gt;
&lt;br /&gt;
== Shell scripts ==&lt;br /&gt;
;UNIX agnosticism:&lt;br /&gt;
* Don&#039;t assume absolute path, use &amp;lt;code&amp;gt;#!/usr/bin/env bash&amp;lt;/code&amp;gt; and not &amp;lt;code&amp;gt;#!/bin/bash&amp;lt;/code&amp;gt; (it could be elsewhere on BSD or Solaris)&lt;br /&gt;
* Use `sh` as must as possible, try to avoid &amp;lt;code&amp;gt;bash&amp;lt;/code&amp;gt;, document exceptions rationale in your commits&lt;br /&gt;
&lt;br /&gt;
;Whitespaces:&lt;br /&gt;
* One whitespace line between shebang and actual content&lt;br /&gt;
* 4 spaces as indent&lt;br /&gt;
&lt;br /&gt;
;File names:&lt;br /&gt;
* We use hyphens (-) as separators, not underscores or camelcase&lt;br /&gt;
* Filename should start by a verb if it performs an action&lt;br /&gt;
* Don&#039;t use .sh extensions when deployed as command&lt;br /&gt;
** sometimes you&#039;ll see them on Phabricator pastes&#039; titles, but it has been added there, so Phab knows shell syntax highlighting should be used&lt;br /&gt;
** &#039;&#039;&#039;Tip.&#039;&#039;&#039; You can use .sh in src/ to help linters, but then provide a Makefile to install it under correct name without extension. Same for operations repository where everything uses .sh, but when deploying with file.managed the extension is omitted&lt;br /&gt;
&lt;br /&gt;
;Templates&lt;br /&gt;
* New command: [https://devcentral.nasqueron.org/source/snippets/browse/main/shell/script.sh shell/script.sh]&lt;br /&gt;
&lt;br /&gt;
== TCL ==&lt;br /&gt;
&lt;br /&gt;
* Indent with 4 spaces, as of 2026-03-20&lt;br /&gt;
* Keep blocks visually separated&lt;br /&gt;
* Use Tcl primitives instead of manual parsing for strings: split, lindex, lrange, join&lt;br /&gt;
* Avoid regex unless necessary&lt;br /&gt;
* List expansion {*} instead of eval&lt;br /&gt;
&lt;br /&gt;
; ViperServ development&lt;br /&gt;
* If you build a full new system, all procedures must be defined in a namespace&lt;br /&gt;
* Use fully-qualified names (::namespace::proc) for procedure definitions and cross-namespace calls&lt;br /&gt;
* Separate low-level request logic from API-specific methods&lt;br /&gt;
&lt;br /&gt;
== Makefile ==&lt;br /&gt;
UNIX agnosticism:&lt;br /&gt;
* Test your makefile against BSD make, and document in README.md to use GNU Makefile (gmake) when it&#039;s not convenient to keep compatibility&lt;br /&gt;
&lt;br /&gt;
Presentation:&lt;br /&gt;
* Create a block with the general targets, then sections with your targets organized by categories/goals/parts&lt;br /&gt;
&lt;br /&gt;
Tip:&lt;br /&gt;
* It&#039;s possible to provision BSDmakefile and GNUmakefile when UNIX agnosticism doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
== Structured data formats (YAML, JSON, XML) ==&lt;br /&gt;
The number of spaces depend if the format is usually heavily hierarchized or not:&lt;br /&gt;
&lt;br /&gt;
* 2 spaces for JSON and YAML&lt;br /&gt;
* 4 spaces for XML, TOML and other configuration files&lt;br /&gt;
&lt;br /&gt;
== Utilities ==&lt;br /&gt;
&lt;br /&gt;
The https://github.com/nasqueron/codestyle repository contains resource to help to respect code convention, like a phpcs ruleset, a configuration ready for PhpStorm, IntelliJ and other JetBrains editors, or a clang-format configuration file.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Fix indent issues ===&lt;br /&gt;
The &amp;lt;code&amp;gt;expand&amp;lt;/code&amp;gt; utility converts tabs into spaces, while &amp;lt;code&amp;gt;unexpand&amp;lt;/code&amp;gt; convert spaces into tabs.&lt;br /&gt;
&lt;br /&gt;
Switch a file from tab indent to 4 spaces indent:&lt;br /&gt;
&lt;br /&gt;
    $ expand -t 4 foo.sh &amp;gt; a&lt;br /&gt;
    $ cat a &amp;gt; foo.sh&lt;br /&gt;
    $ rm a&lt;br /&gt;
&lt;br /&gt;
(Avoid &amp;lt;code&amp;gt;mv&amp;lt;/code&amp;gt; for shell scripts as your foo.sh has probably a 755 chmod, and a will probably have a 644 chmod, assuming 022 as umask)&lt;br /&gt;
&lt;br /&gt;
Switch a file indent with 2 spaces to 4 spaces:&lt;br /&gt;
&lt;br /&gt;
    $ unexpand -t 2 JetBrains/php-codestyle.xml &amp;gt; a&lt;br /&gt;
    $ expand -t 4 a &amp;gt; JetBrains/php-codestyle.xml&lt;br /&gt;
&lt;br /&gt;
This last technique can be used in batch [https://gist.github.com/dereckson/80a746b408c0cf0b688a09db31d5c881 with this reindent script]:&lt;br /&gt;
&lt;br /&gt;
    $ git ls-files | xargs -n1 reindent 2 4 &lt;br /&gt;
&lt;br /&gt;
[[Category:Reference]]&lt;br /&gt;
[[Category:Contributor guide]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Clean_up&amp;diff=2485</id>
		<title>Clean up</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Clean_up&amp;diff=2485"/>
		<updated>2026-03-20T01:38:43Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Tab to spaces */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Style ==&lt;br /&gt;
=== EOL at EOF ===&lt;br /&gt;
There is a need for a blank line at end of file.&lt;br /&gt;
&lt;br /&gt;
You can add them with &amp;lt;code&amp;gt;echo&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ git ls-files | while read f; do tail -n1 $f | read -r _ || echo &amp;gt;&amp;gt; $f; done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== UNIX lines ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ dos2unix&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Encoding ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ iconv -f iso-8859-15 -t utf-8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tab to spaces ===&lt;br /&gt;
Git has a filter to be able to normalize with expand. See [https://eev.ee/blog/2016/06/04/converting-a-git-repo-from-tabs-to-spaces/ here].&lt;br /&gt;
&lt;br /&gt;
As expand doesn&#039;t have a inline capability, you need to create a temporary file:&lt;br /&gt;
&lt;br /&gt;
    tmp_file=$(mktemp -t spaces)&lt;br /&gt;
    expand -t 4 &amp;quot;$source_file&amp;quot; &amp;gt; &amp;quot;$tmp_file&amp;quot;&lt;br /&gt;
    mv &amp;quot;$tmp_file&amp;quot; &amp;quot;$source_file&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Trailing spaces ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ git ls-files | xargs -n 1 gsed -i &#039;s/[[:space:]]*$//&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== UTF-8 BOM ===&lt;br /&gt;
Some old editors started a file by the sequence of bytes [0xEF, 0xBB, 0xBF] to allow the UTF-8 file encoding to be detected. This practice is discouraged nowadays and those should removed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ sed -e &#039;1s/^\xef\xbb\xbf//&#039; &amp;lt; bomfile &amp;gt; newfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]]&lt;br /&gt;
[[Category:Contributor guide]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=WindRiver&amp;diff=2484</id>
		<title>WindRiver</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=WindRiver&amp;diff=2484"/>
		<updated>2026-03-19T22:23:05Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;WindRiver is an FreeBSD 14 bare metal server for Nasqueron general-purpose development.&lt;br /&gt;
&lt;br /&gt;
It supersedes [[Ysul]].&lt;br /&gt;
&lt;br /&gt;
Documentation: [[Devserver reference]]&lt;br /&gt;
&lt;br /&gt;
== Basic information ==&lt;br /&gt;
* &#039;&#039;&#039;IP:&#039;&#039;&#039;&lt;br /&gt;
** 195.154.30.15 &amp;lt;strike&amp;gt;51.159.17.168 since 2023-06-14. Previously 51.159.18.59.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** 2a02:578:4f0d:0:30d0:7b22:6cde:a52e (native, still to migrate)&lt;br /&gt;
** 2001:bc8:6005:5:aa1e:84ff:fef3:5d9c (future through HE)&lt;br /&gt;
* &#039;&#039;&#039;Hostname:&#039;&#039;&#039; windriver.nasqueron.org&lt;br /&gt;
* &#039;&#039;&#039;Homepage:&#039;&#039;&#039; https://windriver.nasqueron.org/&lt;br /&gt;
* &#039;&#039;&#039;Configuration:&#039;&#039;&#039; &amp;lt;strike&amp;gt;64 Gb RAM, Xeon E3 1240 V6, 2x 500 GB SSD (&amp;quot;Pro-6-S&amp;quot;)&amp;lt;/strike&amp;gt; 96 Gb. RAM, Xeon E5-1650 v3, 3x 500 GB SSD (&amp;quot;Pro-4-L&amp;quot;)&lt;br /&gt;
* &#039;&#039;&#039;ISP:&#039;&#039;&#039; [http://www.online.net Online] (FR)&lt;br /&gt;
* &#039;&#039;&#039;Network:&#039;&#039;&#039; Illiad (FR)&lt;br /&gt;
* &#039;&#039;&#039;Policy:&#039;&#039;&#039; Access for any Nasqueron project and for infrastructure operations task.&lt;br /&gt;
* &#039;&#039;&#039;Started:&#039;&#039;&#039; 2019-11-21&lt;br /&gt;
&lt;br /&gt;
== Ports ==&lt;br /&gt;
&lt;br /&gt;
Ports for services managed automatically through Salt are available on {{Ops file|PORTS}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Reserved ports - IRC server range&lt;br /&gt;
|-&lt;br /&gt;
! Port !! User account !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 6901 || dereckson || irssi proxy&lt;br /&gt;
|-&lt;br /&gt;
| 6902 || dereckson || irssi proxy&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=User:Dereckson/Devserver&amp;diff=2483</id>
		<title>User:Dereckson/Devserver</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=User:Dereckson/Devserver&amp;diff=2483"/>
		<updated>2026-03-19T22:02:12Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== MediaWiki ==&lt;br /&gt;
=== Logs ===&lt;br /&gt;
tail -n 100 -f /var/log/www/dereckson.be/mediawiki-php.log&lt;br /&gt;
&lt;br /&gt;
=== Reinstall ===&lt;br /&gt;
* /var/51-wwwroot/mediawiki-dereckson/core: wikimedia/core repository&lt;br /&gt;
* /var/51-wwwroot/mediawiki-dereckson/core/extensions: symlink to &amp;lt;code&amp;gt;../extensions&amp;lt;/code&amp;gt;&lt;br /&gt;
** Clone all needed extensions in /var/51-wwwroot/mediawiki-dereckson/extensions&lt;br /&gt;
* /var/51-wwwroot/mediawiki-dereckson/core/skins: symlink to &amp;lt;code&amp;gt;../skins&amp;lt;/code&amp;gt;&lt;br /&gt;
** Same with git clone ssh://review/mediawiki/skins/&lt;br /&gt;
* /var/dataroot/mediawiki.dereckson.be/data contains:&lt;br /&gt;
** my_wiki.sqlite for the content&lt;br /&gt;
** wikicache.sqlite for the cache&lt;br /&gt;
&lt;br /&gt;
=== Update ===&lt;br /&gt;
* &#039;&#039;&#039;Core:&#039;&#039;&#039; mw-update-core (currently writing it)&lt;br /&gt;
&lt;br /&gt;
=== Create a new extension ===&lt;br /&gt;
;I. Wikimedia side&lt;br /&gt;
* [[mw:Manual:Developing_extensions]] &lt;br /&gt;
* [[mw:Gerrit/New repositories/Requests]]&lt;br /&gt;
* [https://phabricator.wikimedia.org/maniphest/task/edit/form/1/?projects=Project-Admins Create task for new Phabricator project]&lt;br /&gt;
&lt;br /&gt;
;II. WindRiver&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
$ setenv MW_EXTENSION foo&lt;br /&gt;
$ cd ~/dev/wikimedia/mediawiki/extensions&lt;br /&gt;
$ git clone ssh://review/mediawiki/extensions/$MW_EXTENSION || git init $MW_EXTENSION &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Extension is actually stored at /var/51-wwwroot/mediawiki-dereckson/extensions, so can immediately be configured to test locally.&lt;br /&gt;
&lt;br /&gt;
;III. SaaS deployment&lt;br /&gt;
* {{Ops file|pillar/saas/mediawiki.sls}}&lt;br /&gt;
* [https://devcentral.nasqueron.org/source/saas-mediawiki/browse/main/config/Settings.php config/Settings.php]&lt;br /&gt;
&lt;br /&gt;
=== Troubleshoot ===&lt;br /&gt;
==== SQLite database is read-only ====&lt;br /&gt;
Runtime error near line 2: attempt to write a readonly database (8)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
chown -R web-be-dereckson-mw:dereckson /var/dataroot/mediawiki.dereckson.be/data&lt;br /&gt;
chmod 771 /var/dataroot/mediawiki.dereckson.be/data&lt;br /&gt;
chmod 660 /var/dataroot/mediawiki.dereckson.be/data/my_wiki.sqlite&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Permissions to run tests and maintenance scripts ===&lt;br /&gt;
To run tests against wiki and maintenance scripts as user can be tricky:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
touch /tmp/mw-GlobalIdGenerator5001-UID-nodeid /tmp/mw-GlobalIdGenerator5001-UUID-128&lt;br /&gt;
chown web-be-dereckson-mw:dereckson /tmp/mw-GlobalIdGenerator5001-*&lt;br /&gt;
chmod 664 /tmp/mw-GlobalIdGenerator5001-*&lt;br /&gt;
&lt;br /&gt;
chmod 771 /var/dataroot/mediawiki.dereckson.be/data/locks&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zed ==&lt;br /&gt;
=== Logs ===&lt;br /&gt;
tail -n 100 -f /var/log/www/dereckson.be/zed51-php.log&lt;br /&gt;
&lt;br /&gt;
=== Staging  ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note. Keruald is currently symlinked from the monorepo to vendor/keruald.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To recreate Zed staging area:&lt;br /&gt;
&lt;br /&gt;
    $ cd /var/dataroot/zed/content&lt;br /&gt;
    $ git init .&lt;br /&gt;
    $ git config --global --add safe.directory /var/dataroot/zed/content&lt;br /&gt;
    $ git remote add origin git@github.com:hypership/content.git&lt;br /&gt;
    $ git fetch --all&lt;br /&gt;
    $ git reset --hard origin/main&lt;br /&gt;
    $ git clone git@github.com:hypership/content_users.git users&lt;br /&gt;
    &lt;br /&gt;
    $ sudo -u web-be-dereckson-zed51 mkdir /var/dataroot/zed/cache/sessions&lt;br /&gt;
    $ sudo mkdir -p /var/dataroot/zed/content/users/_photos/tn&lt;br /&gt;
    $ sudo chown -R web-be-dereckson-zed51:dereckson /var/dataroot/zed/content/users/_photos&lt;br /&gt;
    $ sudo chmod 771 /var/dataroot/zed/content/users/_photos /var/dataroot/zed/content/users/_photos/tn&lt;br /&gt;
    &lt;br /&gt;
    $ mkdir -p /home/dereckson/dev/zed/hypership&lt;br /&gt;
    $ cd /home/dereckson/dev/zed/hypership&lt;br /&gt;
    $ ln -s /var/dataroot/zed/content&lt;br /&gt;
    &lt;br /&gt;
Note: Zed currently not defined in wwwroot-51 in rOPS, should be done for /var/51-wwwroot/zed&lt;br /&gt;
&lt;br /&gt;
== IRC ==&lt;br /&gt;
&lt;br /&gt;
=== Troubleshoot ===&lt;br /&gt;
==== Error loading module proxy/irc ====&lt;br /&gt;
When trying to load proxy module, I got:&lt;br /&gt;
&lt;br /&gt;
    22:00:09 -!- Irssi: Error loading module proxy/irc: /home/dereckson/.irssi/modules/libirc_proxy.so: Undefined symbol &amp;quot;g_input_add&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Proxy is now compiled by default, personal module needs to be deleted.&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Clean_up&amp;diff=2404</id>
		<title>Clean up</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Clean_up&amp;diff=2404"/>
		<updated>2026-03-09T14:00:51Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Style ==&lt;br /&gt;
=== EOL at EOF ===&lt;br /&gt;
There is a need for a blank line at end of file.&lt;br /&gt;
&lt;br /&gt;
You can add them with &amp;lt;code&amp;gt;echo&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ git ls-files | while read f; do tail -n1 $f | read -r _ || echo &amp;gt;&amp;gt; $f; done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== UNIX lines ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ dos2unix&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Encoding ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ iconv -f iso-8859-15 -t utf-8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tab to spaces ===&lt;br /&gt;
Git has a filter to be able to normalize with expand. See [https://eev.ee/blog/2016/06/04/converting-a-git-repo-from-tabs-to-spaces/ here].&lt;br /&gt;
&lt;br /&gt;
=== Trailing spaces ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ git ls-files | xargs -n 1 gsed -i &#039;s/[[:space:]]*$//&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== UTF-8 BOM ===&lt;br /&gt;
Some old editors started a file by the sequence of bytes [0xEF, 0xBB, 0xBF] to allow the UTF-8 file encoding to be detected. This practice is discouraged nowadays and those should removed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ sed -e &#039;1s/^\xef\xbb\xbf//&#039; &amp;lt; bomfile &amp;gt; newfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]]&lt;br /&gt;
[[Category:Contributor guide]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Clean_up&amp;diff=2388</id>
		<title>Clean up</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Clean_up&amp;diff=2388"/>
		<updated>2026-03-09T13:19:44Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: +trailing spaces&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Style ==&lt;br /&gt;
=== EOL at EOF ===&lt;br /&gt;
There is a need for a blank line at end of file.&lt;br /&gt;
&lt;br /&gt;
You can add them with &amp;lt;code&amp;gt;echo&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ git ls-files | while read f; do tail -n1 $f | read -r _ || echo &amp;gt;&amp;gt; $f; done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== UNIX lines ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ dos2unix&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Encoding ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ iconv -f iso-8859-15 -t utf-8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tab to spaces ===&lt;br /&gt;
Git has a filter to be able to normalize with expand. See [https://eev.ee/blog/2016/06/04/converting-a-git-repo-from-tabs-to-spaces/ here].&lt;br /&gt;
&lt;br /&gt;
== Trailing spaces ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ git ls-files | xargs -n 1 gsed -i &#039;s/[[:space:]]*$//&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== UTF-8 BOM ===&lt;br /&gt;
Some old editors started a file by the sequence of bytes [0xEF, 0xBB, 0xBF] to allow the UTF-8 file encoding to be detected. This practice is discouraged nowadays and those should removed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ sed -e &#039;1s/^\xef\xbb\xbf//&#039; &amp;lt; bomfile &amp;gt; newfile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]]&lt;br /&gt;
[[Category:Contributor guide]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Vault&amp;diff=2375</id>
		<title>Operations grimoire/Vault</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Vault&amp;diff=2375"/>
		<updated>2026-03-02T18:00:24Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Policies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This page currently documents Vault installed on complector as part of {{Ops file|roles/vault/}}. It doesn&#039;t document Docker or shellserver installation. See [[Operations grimoire/Eglide/Vault]] and [[Dev zone/Vault]].&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Hashicorp Vault allows to manage credentials and is currently used:&lt;br /&gt;
&lt;br /&gt;
* to provision credentials through Salt &lt;br /&gt;
* to allow applications to fetch credentials&lt;br /&gt;
* to emit certificates for the private network applications&lt;br /&gt;
* to store credentials used by the Nasqueron Operations SIG beings&lt;br /&gt;
&lt;br /&gt;
Vault policies are fully managed through Salt in the operations repository.&lt;br /&gt;
&lt;br /&gt;
Vault has been selected in 2016 for secrets management.&lt;br /&gt;
&lt;br /&gt;
== Vault reference ==&lt;br /&gt;
=== kv engine ===&lt;br /&gt;
The kv engine contains the following paths:&lt;br /&gt;
&lt;br /&gt;
  * ops/secrets: credentials like passwords, API tokens, private keys deployed to servers - a reference for machines&lt;br /&gt;
  * ops/internal: credentials to third-party services internally shared amongst ops - a reference for humans&lt;br /&gt;
  * ops/privacy: privacy information&lt;br /&gt;
&lt;br /&gt;
==== Secrets ====&lt;br /&gt;
Secrets are directly and manually managed in Vault. If we need to run a disaster recovery procedure, we&#039;ll roll any secret by defining them again and deploy from rOPS those new secrets.&lt;br /&gt;
&lt;br /&gt;
==== Privacy data ====&lt;br /&gt;
Personal identity information (PII) shared inside the Nasqueron Operations squad are more convenient to manage as a repository.&lt;br /&gt;
&lt;br /&gt;
Such access to the repository is restricted to commit data, and ensure this data is deployed to the servers needing it. Any other use isn&#039;t allowed.&lt;br /&gt;
&lt;br /&gt;
Information to the repository is then published in Vault, and referred in rOPS as Vault credentials.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The ops/privacy path is only intended for PII of current or previous members of the Ops SIG, like IP addresses allowed to connect to restricted resources like the ops VPN. This is not acceptable to put 3rd party information in this repository.&lt;br /&gt;
&lt;br /&gt;
=== pki engine ===&lt;br /&gt;
Services listening to private IPs use the Vault PKI to generate certificates: &lt;br /&gt;
&lt;br /&gt;
* pki_root: root CA, certificate available at https://api.nasqueron.org/infra/security/pki/root/ca&lt;br /&gt;
* pki_vault: intermediate CA used for Vault itself&lt;br /&gt;
&lt;br /&gt;
Certificates should be issued short-term and frequently renewed by automated services.&lt;br /&gt;
&lt;br /&gt;
=== transit engine ===&lt;br /&gt;
Encryption as a service is available for applications under /transit path.&lt;br /&gt;
&lt;br /&gt;
See https://learn.hashicorp.com/tutorials/vault/eaas-transit.&lt;br /&gt;
&lt;br /&gt;
Applications should use a policy restricting to a subpath for that app, not to the whole engine.&lt;br /&gt;
&lt;br /&gt;
=== Users accounts ===&lt;br /&gt;
&lt;br /&gt;
Members of the Operations SIG need an access to Vault to create and maintain credentials.&lt;br /&gt;
&lt;br /&gt;
Currently, we use tokens. To generate a token:&lt;br /&gt;
&lt;br /&gt;
     vault token create -policy=admin&lt;br /&gt;
&lt;br /&gt;
To connect to Vault with a token from a devserver (e.g. WindRiver), you need:&lt;br /&gt;
&lt;br /&gt;
# Store the token in &amp;lt;code&amp;gt;$HOME/.vault-token&amp;lt;/code&amp;gt;&lt;br /&gt;
# Define environment variable VAULT_ADDR: &amp;lt;code&amp;gt;export VAULT_ADDR=https://172.27.27.7:8200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tokens need to be frequently renew (before expiration) with &amp;lt;code&amp;gt;vault renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Salt configuration ==&lt;br /&gt;
=== Get a secret through Salt ===&lt;br /&gt;
The information in the ops/secrets and ops/privacy kv engines are integrated in the Salt pillar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
ext_pillar:&lt;br /&gt;
  # Credentials to deploy to servers&lt;br /&gt;
  - vault:&lt;br /&gt;
       conf: path=ops/secrets&lt;br /&gt;
       nesting_key: credentials&lt;br /&gt;
&lt;br /&gt;
  # Personal identity information from Nasqueron Operations SIG members&lt;br /&gt;
  - vault:&lt;br /&gt;
       conf: path=ops/privacy&lt;br /&gt;
       nesting_key: privacy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then access to this information in Salt states using the following references:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Access to Salt data&lt;br /&gt;
|-&lt;br /&gt;
! Category !! Example of path in Vault !! Example of pillar key in Salt&lt;br /&gt;
|-&lt;br /&gt;
| Secrets || ops/secrets/foo || pillar[&#039;credentials&#039;][&#039;foo&#039;]&lt;br /&gt;
|-&lt;br /&gt;
| Privacy data || ops/privacy/ops-cidr || pillar[&#039;privacy&#039;][&#039;ops-cidr&#039;]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ops/internal paths aren&#039;t accessible through Vault.&lt;br /&gt;
&lt;br /&gt;
=== Policies ===&lt;br /&gt;
&lt;br /&gt;
Policies are managed in {{Ops file|pillar/credentials/vault.sls}}.&lt;br /&gt;
&lt;br /&gt;
For Salt, we deploy secrets to servers, policy management for a node consist to provide the list of secrets a role should have access to, generally in &#039;&#039;&#039;vault_secrets_by_role&#039;&#039;&#039; dictionary.&lt;br /&gt;
&lt;br /&gt;
For other applications:&lt;br /&gt;
* create a policy .hcl in &amp;lt;code&amp;gt;roles/vault/policies/files/&amp;lt;/code&amp;gt;&lt;br /&gt;
* declare the policy in the pillar under &amp;lt;code&amp;gt;vault_policies&amp;lt;/code&amp;gt; list, it should match the .hcl file (without the extension or the path)&lt;br /&gt;
* run the repository tests to check if both information matches ; to only run that part, use &amp;lt;code&amp;gt;cd _tests &amp;amp;&amp;amp; python3 -m unittest discover pillar/credentials/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To add only an application policy, Salt can be deployed like this:&lt;br /&gt;
&lt;br /&gt;
    salt complector state.sls_id vault_policy_airflow roles/vault/policies&lt;br /&gt;
&lt;br /&gt;
Salt policies can be tested by specifying the node name:&lt;br /&gt;
&lt;br /&gt;
    salt complector state.sls_id salt-node-windriver roles/vault/policies test=True&lt;br /&gt;
&lt;br /&gt;
=== DRP ===&lt;br /&gt;
Any step we need to do to configure the engines should be added to the {{ops file|roles/vault/bootstrap}} unit.&lt;br /&gt;
&lt;br /&gt;
If we need to recover Vault, two solutions are available:&lt;br /&gt;
* restore the storage, to keep data (credentials, certificates including the root CA one)&lt;br /&gt;
* recreate it from scratch through the roles/vault/bootstrap unit&lt;br /&gt;
&lt;br /&gt;
== Howto ==&lt;br /&gt;
=== Allow a new application to authenticate to Vault ===&lt;br /&gt;
Applications need a policy and an authentication method, for example here for an application called yourservice with AppRole with secret_id and role_id:&lt;br /&gt;
# Create a new policy in operations repository: {{D|3270}}&lt;br /&gt;
# Deploy it from Complector with &amp;lt;code&amp;gt;salt complector state.sls_id vault_policy_yourservice roles/vault/policies&amp;lt;/code&amp;gt;&lt;br /&gt;
# Create an approle matching that policy: &amp;lt;code&amp;gt;vault write auth/approle/role/yourservice token_policies=&amp;quot;yourservice&amp;quot; token_ttl=1h token_max_ttl=4h&amp;lt;/code&amp;gt;&lt;br /&gt;
# Get role_id with &amp;lt;code&amp;gt;vault read auth/approle/role/yourservice/role-id&amp;lt;/code&amp;gt;&lt;br /&gt;
# Get secret_id with &amp;lt;code&amp;gt;vault write -force auth/approle/role/yourservice/secret-id&amp;lt;/code&amp;gt;&lt;br /&gt;
# If you wish Salt to provision those credentials during your service deployment, probably a good idea to write them too: &amp;lt;code&amp;gt;vault kv put secrets/nasqueron/yourservice/vault username=role-id password=secret-id&amp;lt;/code&amp;gt; [to skip if you don&#039;t use Salt to provision role-id and secret-id]&lt;br /&gt;
&lt;br /&gt;
=== Get an admin-level token ===&lt;br /&gt;
Ops can use the self-service hvac script to get a token valid for 30 days:&lt;br /&gt;
&lt;br /&gt;
    ssh complector&lt;br /&gt;
    cd /opt/salt/nasqueron-operations&lt;br /&gt;
    sudo ./utils/vault/issue-admin-token.py                  &lt;br /&gt;
&lt;br /&gt;
If Vault certificate has expired, add the `--insecure` argument.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Connecting to Vault ===&lt;br /&gt;
==== Access to web UI ====&lt;br /&gt;
Vault isn&#039;t listening any public IP, but accept connections from internal network, so you can open a SSH tunnel against &amp;lt;code&amp;gt;complector:8200&amp;lt;/code&amp;gt; and then browse https://localhost:8200:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ssh -L 8200:complector:8200 router-001.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== curl: (60) SSL certificate problem ====&lt;br /&gt;
Curl is compiled against a certificate bundle (&amp;lt;code&amp;gt;curl-config --ca&amp;lt;/code&amp;gt; for the path). That bundle doesn&#039;t contain the pki_root certificate. We deploy this certificate in /etc/ssl/certs, but curl won&#039;t check there if not instructed to. &lt;br /&gt;
&lt;br /&gt;
If you build an immutable environment like a container, add the certificate to the bundle.&lt;br /&gt;
&lt;br /&gt;
On other machines, create a curl configuration file in ~/.curlrc (it doesn&#039;t seem currently possible to create a system one) with &amp;lt;code&amp;gt;capath=/etc/ssl/certs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve still the issue after that, check two things:&lt;br /&gt;
* with &amp;lt;code&amp;gt;curl -v&amp;lt;/code&amp;gt;, the path should correctly there: &amp;lt;code&amp;gt;*  CApath: /etc/ssl/certs&amp;lt;/code&amp;gt; in addition to a CAfile.&lt;br /&gt;
* with &amp;lt;code&amp;gt;file /etc/ssl/certs/* | grep -i nasqueron&amp;lt;/code&amp;gt; you should have a result ; if not, put the certificate in /usr/local/share/certs and relaunch the tool to link it in /etc/ssl/certs, for example &amp;lt;code&amp;gt;certctl rehash&amp;lt;/code&amp;gt; on FreeBSD (needs root access).&lt;br /&gt;
&lt;br /&gt;
=== Certificates ===&lt;br /&gt;
==== How to unseal when certificate have expired? ====&lt;br /&gt;
Use the web UI through SSH tunnel.&lt;br /&gt;
&lt;br /&gt;
==== Renew Vault HTTP certificates ====&lt;br /&gt;
&lt;br /&gt;
Vault uses TLS certificates managed by its own CA. That can create a chicken/egg issue if certificates have expired to connect to it, as the Vault client strictly requires valid TLS certificated to issue commands to renew certificates.&lt;br /&gt;
&lt;br /&gt;
Connect to the web UI works as your browser is able to bypass certificate requirement. Opening a SSH tunnel with &amp;lt;code&amp;gt;-L 8200:complector:8200&amp;lt;/code&amp;gt; should work for that.&lt;br /&gt;
&lt;br /&gt;
Certificates configuration is available at [https://devcentral.nasqueron.org/D2639 D2639].&lt;br /&gt;
&lt;br /&gt;
The web UI doesn&#039;t offer a comprehensive sets of widgets to generate certificates. You can instead use the &#039;&#039;Vault Browser CLI&#039;&#039; to run Vault CLI commands from the web UI. The signing operation can be done through endpoint configuration UI.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: indianred; border: solid 3px black; color:white; font-size: large; padding: 2em;&amp;quot;&amp;gt;Automation for this part is being tested.&lt;br /&gt;
&lt;br /&gt;
You can preview automation proposal in /home/dereckson/sandbox/vault/renew-certificates on Complector.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Based on current D2639 state (2023-01), you can do the following:&lt;br /&gt;
* Has intermediate authority certificate expired? [old instructions, currently not valid anymore]&lt;br /&gt;
** Web console: &amp;lt;code&amp;gt;write -format=json pki_vault/intermediate/generate/internal common_name=&amp;quot;nasqueron.drake Intermediate Authority&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
** At https://localhost:8200/ui/vault/secrets/pki_vault/pki/roles/nasqueron-drake you can use the sign intermediate button to sign it, don&#039;t forget to fill the following information:&lt;br /&gt;
*** CSR, pick from console the .data.csr output from JSON response&lt;br /&gt;
*** Format: pem_bundle&lt;br /&gt;
*** TTL: 100 days&lt;br /&gt;
*** Common name: &amp;quot;nasqueron.drake Intermediate Authority&amp;quot;&lt;br /&gt;
*** Organization: Nasqueron&lt;br /&gt;
*** Organization unit: Nasqueron Operations SIG&lt;br /&gt;
*** Country: BE&lt;br /&gt;
** Follow the warning instruction: copy the certificate bundle, and in pki_vault, use Set signed intermediate to set the certificate as intermediate one. That will create a new issuer, fetch the name in &amp;quot;issuers&amp;quot;.&lt;br /&gt;
** Save also the certificate bundle to /usr/local/share/certs/nasqueron-vault-intermediate.crt&lt;br /&gt;
** Edit the nasqueron-drake role to use your new issuer name&lt;br /&gt;
* Has complector.nasqueron.drake certificate has expired?&lt;br /&gt;
** Web console: &amp;lt;code&amp;gt;write -format=json pki_vault/issue/nasqueron-drake common_name=complector.nasqueron.drake ttl=2160h ip_sans=127.0.0.1,172.27.27.7&amp;lt;/code&amp;gt;, save the output in /usr/local/etc/certificates/vault files:&lt;br /&gt;
*** .data.certificate to certificate.pem&lt;br /&gt;
*** .data.issuing_ca to ca.pem&lt;br /&gt;
*** .data.private_key to private.key (careful how you replace the \n, if you use Python REPL, do it on Complector itself and get rid of the history with &amp;lt;code&amp;gt;import readline ; readline.clear_history()&amp;lt;/code&amp;gt;)&lt;br /&gt;
** Prepare the fullchain bundle with &amp;lt;code&amp;gt;cat certificate.pem ca.pem &amp;gt; fullchain.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
** Send a SIGHUP signal to Vault to reload configuration with &amp;lt;code&amp;gt;kill -1 &amp;lt;Vault PID&amp;gt;&amp;lt;/code&amp;gt;, HTTP server should pick new certificate and you can know directly use the vault command. Vault configuration currently uses fullchain.pem and private.key.&lt;br /&gt;
&lt;br /&gt;
CSR uses &amp;lt;code&amp;gt;line1\nline2\nline3&amp;lt;/code&amp;gt; format in JSON. You can use a Python REPL with print(&amp;quot;...&amp;quot;) to print the CSR in several lines. CSR isn&#039;t confidential information, key is protected in Vault and never exposed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;jq.&#039;&#039;&#039; Another tool that can help is &amp;lt;code&amp;gt;jq&amp;lt;/code&amp;gt;. For example, &amp;lt;code&amp;gt;cat certificate.json | jq -r .data.certificate &amp;gt; /usr/local/etc/certificates/vault/certificate.pem&amp;lt;/code&amp;gt; will save it in multiline format.&lt;br /&gt;
&lt;br /&gt;
If you get an issue about private key missing at Set signed intermediate step, don&#039;t forget you&#039;re setting an intermediate certificate for pki_vault, and not for pki_root, set that here: https://localhost:8200/ui/vault/settings/secrets/configure/pki_vault/cert&lt;br /&gt;
&lt;br /&gt;
Paths where to store certificates matter:&lt;br /&gt;
* pki_root certificates are stored in /usr/local/share/certs&lt;br /&gt;
* pki_vault certificates are stored in /usr/local/etc/certificates/vault&lt;br /&gt;
&lt;br /&gt;
Ensure `private.key` belongs to user `vault` and receives a correct chmod like 400.&lt;br /&gt;
&lt;br /&gt;
==== Services known to break when a certificate is expired ====&lt;br /&gt;
&lt;br /&gt;
* Salt, but that&#039;s ad-hoc and explicit&lt;br /&gt;
* Sentry containers: &amp;lt;code&amp;gt;sudo docker ps -a | grep sentry | grep -v &amp;quot;Up &amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Salt ===&lt;br /&gt;
==== Policy for a node doesn&#039;t contain new secret entry ====&lt;br /&gt;
If the policies are attached to a new role:&lt;br /&gt;
&lt;br /&gt;
# Ensure new secret have been added for the right role in {{Ops file|pillar/credentials/vault.sls}}&lt;br /&gt;
#* If missing, validate afterwards with &amp;lt;code&amp;gt;salt complector pillar.get vault_secrets_by_role:yourrole&amp;lt;/code&amp;gt;&lt;br /&gt;
#* You need to refresh the pillar if still missing: &amp;lt;code&amp;gt;salt complector saltutil.refresh_pillar&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure role has been added to {{Ops file|pillar/nodes/nodes.sls}} and NetBox&lt;br /&gt;
#* If missing, refresh pillar afterwards&lt;br /&gt;
#* Validate with &amp;lt;code&amp;gt;salt complector node.get roles &amp;lt;server name&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
# Final check: &amp;lt;code&amp;gt;salt complector state.sls_id salt-node-&amp;lt;server name&amp;gt; roles/vault/policies test=True&amp;lt;/code&amp;gt;&lt;br /&gt;
# If diff is complicated to read, check the full policies document by role: &amp;lt;code&amp;gt;salt complector credentials.build_policies_by_node&amp;lt;/code&amp;gt;&lt;br /&gt;
#* Secret path present? Check the policy isn&#039;t already up-to-date: &amp;lt;code&amp;gt;vault policy read salt-node-&amp;lt;server name&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== credentials.vault_policy_present returns Bad Request ====&lt;br /&gt;
&lt;br /&gt;
Vault returns a 400 error if the policy format is incorrect.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Case 1.&#039;&#039;&#039; The state ID starts by &amp;lt;code&amp;gt;vault_policy_&amp;lt;/code&amp;gt;. You manually added a file to roles/vault/policies/file: this error means Vault API founds a syntax error in it. You can use https://github.com/mschuchard/linter-vault-policy if you use Pulsar (ex Atom) to lint those files.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Case 2.&#039;&#039;&#039; The state ID starts by anything else. The policy has been generated through _modules/credentials.py.&lt;br /&gt;
&lt;br /&gt;
Check if the pillar values added are correct:&lt;br /&gt;
* if not, add a test in &amp;lt;code&amp;gt;_tests/pillar/credentials/test_vault.py&amp;lt;/code&amp;gt; to detect the case&lt;br /&gt;
* if yes, there is an issue with the Python module code to fix&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example of Salt output.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
----------&lt;br /&gt;
          ID: vault_policy_admin&lt;br /&gt;
    Function: credentials.vault_policy_present&lt;br /&gt;
        Name: admin&lt;br /&gt;
      Result: False&lt;br /&gt;
     Comment: Failed to change policy: Bad Request&lt;br /&gt;
     Started: 13:45:14.162421&lt;br /&gt;
    Duration: 76.168 ms&lt;br /&gt;
     Changes:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Operations grimoire]]&lt;br /&gt;
[[Category:Vault]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Internship_guide/Best_practices_for_mentors&amp;diff=2372</id>
		<title>Internship guide/Best practices for mentors</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Internship_guide/Best_practices_for_mentors&amp;diff=2372"/>
		<updated>2026-02-21T15:32:24Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Rules we&amp;#039;d like to follow in the future */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Context and experience ==&lt;br /&gt;
&lt;br /&gt;
Nasqueron is a small-size open-source project and free culture community. When we offer an internship, the outcome is really different based on the motivation and the level of the intern.&lt;br /&gt;
&lt;br /&gt;
Our experience is based on 7 internships offered and it&#039;s only the second year we offer such a program, so the experience is based on a small dataset.&lt;br /&gt;
&lt;br /&gt;
The ideal intern is:&lt;br /&gt;
* self-directed&lt;br /&gt;
* motivated&lt;br /&gt;
* able to engage with the mentor&lt;br /&gt;
&lt;br /&gt;
Remote / non-remote balance doesn&#039;t seem to matter — we had a lukewarm experience with an intern on-site and a stellar experience with a remote intern with big timezone difference. Our workflows allow remote connection.&lt;br /&gt;
&lt;br /&gt;
Communication tools matter: we had good experiences with IRC and WhatsApp communication, mixed results on DevCentral integrated chat; we would like to experience what&#039;s going on with solutions like Mattermost/Zulip/Stoat/Slack/Discord.&lt;br /&gt;
&lt;br /&gt;
The mentor seems to matter too:&lt;br /&gt;
* Dorian and Dereckson looks hard to win — you need to be a good to very good contributor to gain their approval, either technically or with eagerness to learn.&lt;br /&gt;
* Eli is clearly more open to help a newcomer to find their first steps and takes care not to overwhelm them.&lt;br /&gt;
&lt;br /&gt;
== Rules we&#039;d like to follow in the future ==&lt;br /&gt;
* &#039;&#039;&#039;Backup.&#039;&#039;&#039; We really need to have a backup mentor for each internship.&lt;br /&gt;
* &#039;&#039;&#039;Remote or hybrid.&#039;&#039;&#039; A minimal number of days on-site isn&#039;t acceptable.&lt;br /&gt;
* &#039;&#039;&#039;Experience.&#039;&#039;&#039; Projects engagement show we can provide a really more meaningful internship for experienced students.&lt;br /&gt;
* &#039;&#039;&#039;Favour ops/security/network track.&#039;&#039;&#039; Internships in non-dev is rather hard to find, and Nasqueron tasks seem really infrastructure-oriented, so we can provide real projects, experience, knowledge and culture. That works and that works well (80% success), so that&#039;s we clearly bring something on the table here and an opportunity for interns to grow. For developers, it seems more complicated: our practices and infrastructure are clearly tailored for developers at ease with complicated tooling and workflows, and our project doesn&#039;t seem fit for newcomers, whatever we try — something also noticed on Wikimedia programs, where a lot of things were tried to improve engagement and success.&lt;br /&gt;
* &#039;&#039;&#039;Initial engagement.&#039;&#039;&#039; Ideally, tooling training (arc/git workflow) should be offered beforehand. We should offer a small task to complete in that goal.&lt;br /&gt;
* &#039;&#039;&#039;Communication.&#039;&#039;&#039; Continuous communication must occur: we need interns able to initiate the communication from their side too when needed, and with a backup mentor, both can also ensure communications from our side work well too.&lt;br /&gt;
&lt;br /&gt;
== Relations with education organisations ==&lt;br /&gt;
&lt;br /&gt;
In Belgium, there are two kind of internships:&lt;br /&gt;
* through IFAPME — really bureaucratic, but they seem to want to adapt to organisations needs&lt;br /&gt;
* from superior schools and universities — either they don&#039;t care, either they clearly consider they can impose the rules&lt;br /&gt;
&lt;br /&gt;
From France, we had problems with cases of on-site requirements during COVID-19 lockdowns.&lt;br /&gt;
&lt;br /&gt;
Requirements from the school need to be taken in consideration:&lt;br /&gt;
* what&#039;s the obligation of the mentor?&lt;br /&gt;
* jury participation? lot of documents to fill?&lt;br /&gt;
* is hybrid work acceptable?&lt;br /&gt;
&lt;br /&gt;
Experience shows we need in the future to refuse interns from schools with on-site requirements.&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Internship_guide/Best_practices_for_mentors&amp;diff=2371</id>
		<title>Internship guide/Best practices for mentors</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Internship_guide/Best_practices_for_mentors&amp;diff=2371"/>
		<updated>2026-02-21T15:32:11Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Rules we&amp;#039;d like to follow in the future */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Context and experience ==&lt;br /&gt;
&lt;br /&gt;
Nasqueron is a small-size open-source project and free culture community. When we offer an internship, the outcome is really different based on the motivation and the level of the intern.&lt;br /&gt;
&lt;br /&gt;
Our experience is based on 7 internships offered and it&#039;s only the second year we offer such a program, so the experience is based on a small dataset.&lt;br /&gt;
&lt;br /&gt;
The ideal intern is:&lt;br /&gt;
* self-directed&lt;br /&gt;
* motivated&lt;br /&gt;
* able to engage with the mentor&lt;br /&gt;
&lt;br /&gt;
Remote / non-remote balance doesn&#039;t seem to matter — we had a lukewarm experience with an intern on-site and a stellar experience with a remote intern with big timezone difference. Our workflows allow remote connection.&lt;br /&gt;
&lt;br /&gt;
Communication tools matter: we had good experiences with IRC and WhatsApp communication, mixed results on DevCentral integrated chat; we would like to experience what&#039;s going on with solutions like Mattermost/Zulip/Stoat/Slack/Discord.&lt;br /&gt;
&lt;br /&gt;
The mentor seems to matter too:&lt;br /&gt;
* Dorian and Dereckson looks hard to win — you need to be a good to very good contributor to gain their approval, either technically or with eagerness to learn.&lt;br /&gt;
* Eli is clearly more open to help a newcomer to find their first steps and takes care not to overwhelm them.&lt;br /&gt;
&lt;br /&gt;
== Rules we&#039;d like to follow in the future ==&lt;br /&gt;
* &#039;&#039;&#039;Backup.&#039;&#039;&#039; We really need to have a backup mentor for each internship.&lt;br /&gt;
* &#039;&#039;&#039;Remote or hybrid.&#039;&#039;&#039; A minimal number of days on-site isn&#039;t acceptable.&lt;br /&gt;
* &#039;&#039;&#039;Experience.&#039;&#039;&#039; Projects engagement show we can provide a really more meaningful internship for experienced students.&lt;br /&gt;
* &#039;&#039;&#039;Favour ops/security/network track.&#039;&#039;&#039; Internships in non-dev is rather hard to find, and Nasqueron tasks seem really infrastructure-oriented, so we can provide real projects, experience, knowledge and culture. That works and that works well (80% success), so that&#039;s we clearly bring something on the table here and an opportunity for interns to grow. For developers, it seems more complicated: our practices and infrastructure are clearly tailored for developers at ease with complicated tooling and workflows, and our project doesn&#039;t seem fit for newcomers, whatever we try — something also noticed on Wikimedia programs.&lt;br /&gt;
* &#039;&#039;&#039;Initial engagement.&#039;&#039;&#039; Ideally, tooling training (arc/git workflow) should be offered beforehand. We should offer a small task to complete in that goal.&lt;br /&gt;
* &#039;&#039;&#039;Communication.&#039;&#039;&#039; Continuous communication must occur: we need interns able to initiate the communication from their side too when needed, and with a backup mentor, both can also ensure communications from our side work well too.&lt;br /&gt;
&lt;br /&gt;
== Relations with education organisations ==&lt;br /&gt;
&lt;br /&gt;
In Belgium, there are two kind of internships:&lt;br /&gt;
* through IFAPME — really bureaucratic, but they seem to want to adapt to organisations needs&lt;br /&gt;
* from superior schools and universities — either they don&#039;t care, either they clearly consider they can impose the rules&lt;br /&gt;
&lt;br /&gt;
From France, we had problems with cases of on-site requirements during COVID-19 lockdowns.&lt;br /&gt;
&lt;br /&gt;
Requirements from the school need to be taken in consideration:&lt;br /&gt;
* what&#039;s the obligation of the mentor?&lt;br /&gt;
* jury participation? lot of documents to fill?&lt;br /&gt;
* is hybrid work acceptable?&lt;br /&gt;
&lt;br /&gt;
Experience shows we need in the future to refuse interns from schools with on-site requirements.&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Internship_guide/Best_practices_for_mentors&amp;diff=2370</id>
		<title>Internship guide/Best practices for mentors</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Internship_guide/Best_practices_for_mentors&amp;diff=2370"/>
		<updated>2026-02-21T15:31:22Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Rules we&amp;#039;d like to follow in the future */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Context and experience ==&lt;br /&gt;
&lt;br /&gt;
Nasqueron is a small-size open-source project and free culture community. When we offer an internship, the outcome is really different based on the motivation and the level of the intern.&lt;br /&gt;
&lt;br /&gt;
Our experience is based on 7 internships offered and it&#039;s only the second year we offer such a program, so the experience is based on a small dataset.&lt;br /&gt;
&lt;br /&gt;
The ideal intern is:&lt;br /&gt;
* self-directed&lt;br /&gt;
* motivated&lt;br /&gt;
* able to engage with the mentor&lt;br /&gt;
&lt;br /&gt;
Remote / non-remote balance doesn&#039;t seem to matter — we had a lukewarm experience with an intern on-site and a stellar experience with a remote intern with big timezone difference. Our workflows allow remote connection.&lt;br /&gt;
&lt;br /&gt;
Communication tools matter: we had good experiences with IRC and WhatsApp communication, mixed results on DevCentral integrated chat; we would like to experience what&#039;s going on with solutions like Mattermost/Zulip/Stoat/Slack/Discord.&lt;br /&gt;
&lt;br /&gt;
The mentor seems to matter too:&lt;br /&gt;
* Dorian and Dereckson looks hard to win — you need to be a good to very good contributor to gain their approval, either technically or with eagerness to learn.&lt;br /&gt;
* Eli is clearly more open to help a newcomer to find their first steps and takes care not to overwhelm them.&lt;br /&gt;
&lt;br /&gt;
== Rules we&#039;d like to follow in the future ==&lt;br /&gt;
* &#039;&#039;&#039;Backup.&#039;&#039;&#039; We really need to have a backup mentor for each internship.&lt;br /&gt;
* &#039;&#039;&#039;Remote or hybrid.&#039;&#039;&#039; A minimal number of days on-site isn&#039;t acceptable.&lt;br /&gt;
* &#039;&#039;&#039;Experience.&#039;&#039;&#039; Projects engagement show we can provide a really more meaningful internship for experienced students.&lt;br /&gt;
* &#039;&#039;&#039;Favour ops/security/network track.&#039;&#039;&#039; Internships in non-dev is rather hard to find, and Nasqueron tasks seem really infrastructure-oriented, so we can provide real projects, experience, knowledge and culture. That works and that works well (80% success), so that&#039;s we clearly bring something on the table here and an opportunity for interns to grow. For developers, it seems more complicated: our practices and infrastructure are clearly tailored for developers at ease with complicated tooling and workflows.&lt;br /&gt;
* &#039;&#039;&#039;Initial engagement.&#039;&#039;&#039; Ideally, tooling training (arc/git workflow) should be offered beforehand. We should offer a small task to complete in that goal.&lt;br /&gt;
* &#039;&#039;&#039;Communication.&#039;&#039;&#039; Continuous communication must occur: we need interns able to initiate the communication from their side too when needed, and with a backup mentor, both can also ensure communications from our side work well too.&lt;br /&gt;
&lt;br /&gt;
== Relations with education organisations ==&lt;br /&gt;
&lt;br /&gt;
In Belgium, there are two kind of internships:&lt;br /&gt;
* through IFAPME — really bureaucratic, but they seem to want to adapt to organisations needs&lt;br /&gt;
* from superior schools and universities — either they don&#039;t care, either they clearly consider they can impose the rules&lt;br /&gt;
&lt;br /&gt;
From France, we had problems with cases of on-site requirements during COVID-19 lockdowns.&lt;br /&gt;
&lt;br /&gt;
Requirements from the school need to be taken in consideration:&lt;br /&gt;
* what&#039;s the obligation of the mentor?&lt;br /&gt;
* jury participation? lot of documents to fill?&lt;br /&gt;
* is hybrid work acceptable?&lt;br /&gt;
&lt;br /&gt;
Experience shows we need in the future to refuse interns from schools with on-site requirements.&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Internship_guide/Best_practices_for_mentors&amp;diff=2369</id>
		<title>Internship guide/Best practices for mentors</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Internship_guide/Best_practices_for_mentors&amp;diff=2369"/>
		<updated>2026-02-21T15:30:40Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Rules we&amp;#039;d like to follow in the future */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Context and experience ==&lt;br /&gt;
&lt;br /&gt;
Nasqueron is a small-size open-source project and free culture community. When we offer an internship, the outcome is really different based on the motivation and the level of the intern.&lt;br /&gt;
&lt;br /&gt;
Our experience is based on 7 internships offered and it&#039;s only the second year we offer such a program, so the experience is based on a small dataset.&lt;br /&gt;
&lt;br /&gt;
The ideal intern is:&lt;br /&gt;
* self-directed&lt;br /&gt;
* motivated&lt;br /&gt;
* able to engage with the mentor&lt;br /&gt;
&lt;br /&gt;
Remote / non-remote balance doesn&#039;t seem to matter — we had a lukewarm experience with an intern on-site and a stellar experience with a remote intern with big timezone difference. Our workflows allow remote connection.&lt;br /&gt;
&lt;br /&gt;
Communication tools matter: we had good experiences with IRC and WhatsApp communication, mixed results on DevCentral integrated chat; we would like to experience what&#039;s going on with solutions like Mattermost/Zulip/Stoat/Slack/Discord.&lt;br /&gt;
&lt;br /&gt;
The mentor seems to matter too:&lt;br /&gt;
* Dorian and Dereckson looks hard to win — you need to be a good to very good contributor to gain their approval, either technically or with eagerness to learn.&lt;br /&gt;
* Eli is clearly more open to help a newcomer to find their first steps and takes care not to overwhelm them.&lt;br /&gt;
&lt;br /&gt;
== Rules we&#039;d like to follow in the future ==&lt;br /&gt;
* &#039;&#039;&#039;Backup.&#039;&#039;&#039; We really need to have a backup mentor for each internship.&lt;br /&gt;
* &#039;&#039;&#039;Remote or hybrid.&#039;&#039;&#039; A minimal number of days on-site isn&#039;t acceptable.&lt;br /&gt;
* &#039;&#039;&#039;Experience.&#039;&#039;&#039; Projects engagement show we can provide a really more meaningful internship for experienced students.&lt;br /&gt;
* &#039;&#039;&#039;Favour ops/security/network track.&#039;&#039;&#039; Internships in non-dev is rather hard to find, and Nasqueron tasks seem really infrastructure-oriented, so we can provide real projects, experience, knowledge and culture. That works and that works well (80% success). For developers, it seems more complicated: our practices and infrastructure are clearly tailored for developers at ease with complicated tooling and workflows.&lt;br /&gt;
* &#039;&#039;&#039;Initial engagement.&#039;&#039;&#039; Ideally, tooling training (arc/git workflow) should be offered beforehand. We should offer a small task to complete in that goal.&lt;br /&gt;
* &#039;&#039;&#039;Communication.&#039;&#039;&#039; Continuous communication must occur: we need interns able to initiate the communication from their side too when needed, and with a backup mentor, both can also ensure communications from our side work well too.&lt;br /&gt;
&lt;br /&gt;
== Relations with education organisations ==&lt;br /&gt;
&lt;br /&gt;
In Belgium, there are two kind of internships:&lt;br /&gt;
* through IFAPME — really bureaucratic, but they seem to want to adapt to organisations needs&lt;br /&gt;
* from superior schools and universities — either they don&#039;t care, either they clearly consider they can impose the rules&lt;br /&gt;
&lt;br /&gt;
From France, we had problems with cases of on-site requirements during COVID-19 lockdowns.&lt;br /&gt;
&lt;br /&gt;
Requirements from the school need to be taken in consideration:&lt;br /&gt;
* what&#039;s the obligation of the mentor?&lt;br /&gt;
* jury participation? lot of documents to fill?&lt;br /&gt;
* is hybrid work acceptable?&lt;br /&gt;
&lt;br /&gt;
Experience shows we need in the future to refuse interns from schools with on-site requirements.&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Internship_guide/Best_practices_for_mentors&amp;diff=2368</id>
		<title>Internship guide/Best practices for mentors</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Internship_guide/Best_practices_for_mentors&amp;diff=2368"/>
		<updated>2026-02-21T15:30:05Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: Created page with &amp;quot;== Context and experience ==  Nasqueron is a small-size open-source project and free culture community. When we offer an internship, the outcome is really different based on the motivation and the level of the intern.  Our experience is based on 7 internships offered and it&amp;#039;s only the second year we offer such a program, so the experience is based on a small dataset.  The ideal intern is: * self-directed * motivated * able to engage with the mentor  Remote / non-remote b...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Context and experience ==&lt;br /&gt;
&lt;br /&gt;
Nasqueron is a small-size open-source project and free culture community. When we offer an internship, the outcome is really different based on the motivation and the level of the intern.&lt;br /&gt;
&lt;br /&gt;
Our experience is based on 7 internships offered and it&#039;s only the second year we offer such a program, so the experience is based on a small dataset.&lt;br /&gt;
&lt;br /&gt;
The ideal intern is:&lt;br /&gt;
* self-directed&lt;br /&gt;
* motivated&lt;br /&gt;
* able to engage with the mentor&lt;br /&gt;
&lt;br /&gt;
Remote / non-remote balance doesn&#039;t seem to matter — we had a lukewarm experience with an intern on-site and a stellar experience with a remote intern with big timezone difference. Our workflows allow remote connection.&lt;br /&gt;
&lt;br /&gt;
Communication tools matter: we had good experiences with IRC and WhatsApp communication, mixed results on DevCentral integrated chat; we would like to experience what&#039;s going on with solutions like Mattermost/Zulip/Stoat/Slack/Discord.&lt;br /&gt;
&lt;br /&gt;
The mentor seems to matter too:&lt;br /&gt;
* Dorian and Dereckson looks hard to win — you need to be a good to very good contributor to gain their approval, either technically or with eagerness to learn.&lt;br /&gt;
* Eli is clearly more open to help a newcomer to find their first steps and takes care not to overwhelm them.&lt;br /&gt;
&lt;br /&gt;
== Rules we&#039;d like to follow in the future ==&lt;br /&gt;
* &#039;&#039;&#039;Backup.&#039;&#039;&#039; We really need to have a backup mentor for each internship.&lt;br /&gt;
* &#039;&#039;&#039;Remote or hybrid.&#039;&#039;&#039; A minimal number of days on-site isn&#039;t acceptable.&lt;br /&gt;
* &#039;&#039;&#039;Experience.&#039;&#039;&#039; Projects engagement show we can provide a really more meaningful internship for experienced students.&lt;br /&gt;
* &#039;&#039;&#039;Favour ops/security/network track.&#039;&#039;&#039; Internships in non-dev is rather hard to find, and Nasqueron tasks seem really infrastructure-oriented, so we can provide real projects, experience, knowledge and culture. That works and that works well (80% success). For developers, it seems more complicated: our practices and infrastructure are clearly tailored for developers at ease with complicated tooling and workflows.&lt;br /&gt;
* &#039;&#039;&#039;Initial engagement.&#039;&#039;&#039; Ideally, tooling training (arc/git workflow) should be offered beforehand. We should offer a small task to complete in that goal.&lt;br /&gt;
* &#039;&#039;&#039;Communication.&#039;&#039;&#039; Continuous communication must occur: we need interns able to initiate the communication from their side too when needed.&lt;br /&gt;
&lt;br /&gt;
== Relations with education organisations ==&lt;br /&gt;
&lt;br /&gt;
In Belgium, there are two kind of internships:&lt;br /&gt;
* through IFAPME — really bureaucratic, but they seem to want to adapt to organisations needs&lt;br /&gt;
* from superior schools and universities — either they don&#039;t care, either they clearly consider they can impose the rules&lt;br /&gt;
&lt;br /&gt;
From France, we had problems with cases of on-site requirements during COVID-19 lockdowns.&lt;br /&gt;
&lt;br /&gt;
Requirements from the school need to be taken in consideration:&lt;br /&gt;
* what&#039;s the obligation of the mentor?&lt;br /&gt;
* jury participation? lot of documents to fill?&lt;br /&gt;
* is hybrid work acceptable?&lt;br /&gt;
&lt;br /&gt;
Experience shows we need in the future to refuse interns from schools with on-site requirements.&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Internship_guide&amp;diff=2367</id>
		<title>Internship guide</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Internship_guide&amp;diff=2367"/>
		<updated>2026-02-21T14:43:07Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Resources for mentors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Resources for interns ==&lt;br /&gt;
* [[/Ergonomics]]&lt;br /&gt;
* [[/Onboarding]]&lt;br /&gt;
* [[How to communicate]]&lt;br /&gt;
* [[How to contribute code]]&lt;br /&gt;
* [https://devcentral.nasqueron.org/home/menu/view/174/ Contribute to projects] on DevCentral&lt;br /&gt;
* [[wolfplex:Mémento des stagiaires]] (French only)&lt;br /&gt;
&lt;br /&gt;
== Resources for mentors ==&lt;br /&gt;
* [[/Best practices for mentors]]&lt;br /&gt;
* [[/Colleges, universities and schools]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Internship guide|*]]&lt;br /&gt;
[[Category:Nasqueron documentation]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Docker-002&amp;diff=2366</id>
		<title>Docker-002</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Docker-002&amp;diff=2366"/>
		<updated>2026-02-20T18:51:47Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Properties */ +IPv6&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Docker Engine for production services. Supersedes [[Equatower]] and [[docker-001]].&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
* Hypervisor: [[hyper-001]]&lt;br /&gt;
* Network&lt;br /&gt;
** IP - drake: 172.27.27.5&lt;br /&gt;
** IP - public: 51.255.124.9 - 2001:470:1f13:365::50f7:ba11/64&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* [[Equatower]] contains still relevant notes&lt;br /&gt;
* [https://devcentral.nasqueron.org/source/operations/browse/main/pillar/paas/docker/docker-002/ Docker and containers configuration]&lt;br /&gt;
* [https://netbox.nasqueron.org/virtualization/virtual-machines/7/ NetBox] 🔒&lt;br /&gt;
&lt;br /&gt;
[[Category:Servers]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=ServPulse/Development_guide&amp;diff=2344</id>
		<title>ServPulse/Development guide</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=ServPulse/Development_guide&amp;diff=2344"/>
		<updated>2026-02-17T21:51:09Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Git workflow */ Link to docs/workflow.md&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Getting started ==&lt;br /&gt;
&lt;br /&gt;
 git clone https://devcentral.nasqueron.org/source/servpulse.git&lt;br /&gt;
 cd servpulse&lt;br /&gt;
 cp .env.example .env&lt;br /&gt;
 docker compose up&lt;br /&gt;
&lt;br /&gt;
The application will be available at:&lt;br /&gt;
* Status page: http://localhost:8080&lt;br /&gt;
* API: http://localhost:3000/api&lt;br /&gt;
&lt;br /&gt;
Tip: if you&#039;re maintainer of the project and need write access to the repository, you need to clone by SSH: &amp;lt;code&amp;gt;git clone ssh://vcs@devcentral.nasqueron.org:5022/source/servpulse.git&amp;lt;/code&amp;gt;. If you&#039;ve already cloned the repository, you can edit the URL in &amp;lt;code&amp;gt;.git/config&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Project structure ==&lt;br /&gt;
&lt;br /&gt;
 servpulse/&lt;br /&gt;
 ├── backend/          Express.js API server (MVC pattern)&lt;br /&gt;
 │   ├── controllers/  Request handlers&lt;br /&gt;
 │   ├── models/       Data access layer (raw pg queries)&lt;br /&gt;
 │   ├── routes/       API route definitions&lt;br /&gt;
 │   ├── middleware/    JWT authentication&lt;br /&gt;
 │   ├── services/     Business logic (notifications, health checks)&lt;br /&gt;
 │   ├── config/       App config (app.json) and database connection&lt;br /&gt;
 │   └── __tests__/    Jest unit tests&lt;br /&gt;
 ├── frontend/         Vue.js 3 application&lt;br /&gt;
 │   └── src/&lt;br /&gt;
 │       ├── components/   Reusable UI components&lt;br /&gt;
 │       ├── composables/  Vue 3 composables (useServices, useIncidents, etc.)&lt;br /&gt;
 │       ├── views/        Page views (StatusPage, AdminDashboard, AdminLogin)&lt;br /&gt;
 │       ├── plugins/      API client (Axios)&lt;br /&gt;
 │       ├── utils/        Status helpers and formatters&lt;br /&gt;
 │       └── router/       Vue Router config with auth guards&lt;br /&gt;
 ├── database/         SQL schema (init.sql)&lt;br /&gt;
 └── docker-compose.yml&lt;br /&gt;
&lt;br /&gt;
== Code conventions ==&lt;br /&gt;
&lt;br /&gt;
* [[Code_conventions|Nasqueron conventions]]&lt;br /&gt;
* Single quotes for strings&lt;br /&gt;
* camelCase for variables and functions&lt;br /&gt;
* Vue 3 Composition API (&amp;lt;code&amp;gt;&amp;lt;script setup&amp;gt;&amp;lt;/code&amp;gt;) for components&lt;br /&gt;
* Tailwind CSS utility classes for styling (no scoped styles)&lt;br /&gt;
* Raw pg queries in models (no ORM)&lt;br /&gt;
&lt;br /&gt;
== How to add a new feature ==&lt;br /&gt;
&lt;br /&gt;
=== Adding a backend resource ===&lt;br /&gt;
&lt;br /&gt;
# Add table to &amp;lt;code&amp;gt;database/init.sql&amp;lt;/code&amp;gt;&lt;br /&gt;
# Create &amp;lt;code&amp;gt;models/resourceModel.js&amp;lt;/code&amp;gt; — raw pg queries&lt;br /&gt;
# Create &amp;lt;code&amp;gt;controllers/resourceController.js&amp;lt;/code&amp;gt; — req/res handlers&lt;br /&gt;
# Create &amp;lt;code&amp;gt;routes/resourceRoutes.js&amp;lt;/code&amp;gt; — Express router with auth where needed&lt;br /&gt;
# Register routes in &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt;&lt;br /&gt;
# Add tests in &amp;lt;code&amp;gt;__tests__/controllers/resourceController.test.js&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Adding a frontend component ===&lt;br /&gt;
&lt;br /&gt;
# Create &amp;lt;code&amp;gt;.vue&amp;lt;/code&amp;gt; file in &amp;lt;code&amp;gt;src/components/&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;&amp;lt;script setup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
# Use Tailwind classes and existing utilities from &amp;lt;code&amp;gt;@/utils/status&amp;lt;/code&amp;gt;&lt;br /&gt;
# Import composables from &amp;lt;code&amp;gt;@/composables/&amp;lt;/code&amp;gt; for data&lt;br /&gt;
# Add tests in &amp;lt;code&amp;gt;src/components/__tests__/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Axios integration ==&lt;br /&gt;
&lt;br /&gt;
The API client is configured in &amp;lt;code&amp;gt;frontend/src/plugins/api.js&amp;lt;/code&amp;gt;. It uses Axios with a base URL from &amp;lt;code&amp;gt;VITE_API_URL&amp;lt;/code&amp;gt; and automatically attaches JWT tokens from localStorage via a request interceptor.&lt;br /&gt;
&lt;br /&gt;
Composables (&amp;lt;code&amp;gt;useServices&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;useIncidents&amp;lt;/code&amp;gt;, etc.) wrap the API calls and return reactive refs:&lt;br /&gt;
&lt;br /&gt;
 const { services, loading, error, fetchServices } = useServices()&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
 # Backend (Jest)&lt;br /&gt;
 cd backend &amp;amp;&amp;amp; npm test&lt;br /&gt;
&lt;br /&gt;
 # Frontend (Vitest)&lt;br /&gt;
 cd frontend &amp;amp;&amp;amp; npm run test:unit&lt;br /&gt;
&lt;br /&gt;
== Git workflow ==&lt;br /&gt;
&lt;br /&gt;
See {{Browse|servpulse|docs/workflow.md}} in the repository for the arc diff workflow.&lt;br /&gt;
&lt;br /&gt;
[[Category:ServPulse|Development guide]]&lt;br /&gt;
[[Category:Developer guide]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Template:Browse&amp;diff=2343</id>
		<title>Template:Browse</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Template:Browse&amp;diff=2343"/>
		<updated>2026-02-17T21:50:51Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: Created page with &amp;quot;&amp;lt;noinclude&amp;gt;== Example == &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{Browse|servpulse|docs/workflow.md}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; gives {{Browse|servpulse|docs/workflow.md}}  &amp;lt;/noinclude&amp;gt; [https://devcentral.nasqueron.org/source/{{{1}}}/browse/main/{{{2}}} {{{2}}}]&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;== Example ==&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{Browse|servpulse|docs/workflow.md}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; gives {{Browse|servpulse|docs/workflow.md}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
[https://devcentral.nasqueron.org/source/{{{1}}}/browse/main/{{{2}}} {{{2}}}]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=ServPulse/Development_guide&amp;diff=2342</id>
		<title>ServPulse/Development guide</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=ServPulse/Development_guide&amp;diff=2342"/>
		<updated>2026-02-17T21:47:08Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Getting started */ Update URL to https, note for maintainers write access = SSH&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Getting started ==&lt;br /&gt;
&lt;br /&gt;
 git clone https://devcentral.nasqueron.org/source/servpulse.git&lt;br /&gt;
 cd servpulse&lt;br /&gt;
 cp .env.example .env&lt;br /&gt;
 docker compose up&lt;br /&gt;
&lt;br /&gt;
The application will be available at:&lt;br /&gt;
* Status page: http://localhost:8080&lt;br /&gt;
* API: http://localhost:3000/api&lt;br /&gt;
&lt;br /&gt;
Tip: if you&#039;re maintainer of the project and need write access to the repository, you need to clone by SSH: &amp;lt;code&amp;gt;git clone ssh://vcs@devcentral.nasqueron.org:5022/source/servpulse.git&amp;lt;/code&amp;gt;. If you&#039;ve already cloned the repository, you can edit the URL in &amp;lt;code&amp;gt;.git/config&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Project structure ==&lt;br /&gt;
&lt;br /&gt;
 servpulse/&lt;br /&gt;
 ├── backend/          Express.js API server (MVC pattern)&lt;br /&gt;
 │   ├── controllers/  Request handlers&lt;br /&gt;
 │   ├── models/       Data access layer (raw pg queries)&lt;br /&gt;
 │   ├── routes/       API route definitions&lt;br /&gt;
 │   ├── middleware/    JWT authentication&lt;br /&gt;
 │   ├── services/     Business logic (notifications, health checks)&lt;br /&gt;
 │   ├── config/       App config (app.json) and database connection&lt;br /&gt;
 │   └── __tests__/    Jest unit tests&lt;br /&gt;
 ├── frontend/         Vue.js 3 application&lt;br /&gt;
 │   └── src/&lt;br /&gt;
 │       ├── components/   Reusable UI components&lt;br /&gt;
 │       ├── composables/  Vue 3 composables (useServices, useIncidents, etc.)&lt;br /&gt;
 │       ├── views/        Page views (StatusPage, AdminDashboard, AdminLogin)&lt;br /&gt;
 │       ├── plugins/      API client (Axios)&lt;br /&gt;
 │       ├── utils/        Status helpers and formatters&lt;br /&gt;
 │       └── router/       Vue Router config with auth guards&lt;br /&gt;
 ├── database/         SQL schema (init.sql)&lt;br /&gt;
 └── docker-compose.yml&lt;br /&gt;
&lt;br /&gt;
== Code conventions ==&lt;br /&gt;
&lt;br /&gt;
* [[Code_conventions|Nasqueron conventions]]&lt;br /&gt;
* Single quotes for strings&lt;br /&gt;
* camelCase for variables and functions&lt;br /&gt;
* Vue 3 Composition API (&amp;lt;code&amp;gt;&amp;lt;script setup&amp;gt;&amp;lt;/code&amp;gt;) for components&lt;br /&gt;
* Tailwind CSS utility classes for styling (no scoped styles)&lt;br /&gt;
* Raw pg queries in models (no ORM)&lt;br /&gt;
&lt;br /&gt;
== How to add a new feature ==&lt;br /&gt;
&lt;br /&gt;
=== Adding a backend resource ===&lt;br /&gt;
&lt;br /&gt;
# Add table to &amp;lt;code&amp;gt;database/init.sql&amp;lt;/code&amp;gt;&lt;br /&gt;
# Create &amp;lt;code&amp;gt;models/resourceModel.js&amp;lt;/code&amp;gt; — raw pg queries&lt;br /&gt;
# Create &amp;lt;code&amp;gt;controllers/resourceController.js&amp;lt;/code&amp;gt; — req/res handlers&lt;br /&gt;
# Create &amp;lt;code&amp;gt;routes/resourceRoutes.js&amp;lt;/code&amp;gt; — Express router with auth where needed&lt;br /&gt;
# Register routes in &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt;&lt;br /&gt;
# Add tests in &amp;lt;code&amp;gt;__tests__/controllers/resourceController.test.js&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Adding a frontend component ===&lt;br /&gt;
&lt;br /&gt;
# Create &amp;lt;code&amp;gt;.vue&amp;lt;/code&amp;gt; file in &amp;lt;code&amp;gt;src/components/&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;&amp;lt;script setup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
# Use Tailwind classes and existing utilities from &amp;lt;code&amp;gt;@/utils/status&amp;lt;/code&amp;gt;&lt;br /&gt;
# Import composables from &amp;lt;code&amp;gt;@/composables/&amp;lt;/code&amp;gt; for data&lt;br /&gt;
# Add tests in &amp;lt;code&amp;gt;src/components/__tests__/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Axios integration ==&lt;br /&gt;
&lt;br /&gt;
The API client is configured in &amp;lt;code&amp;gt;frontend/src/plugins/api.js&amp;lt;/code&amp;gt;. It uses Axios with a base URL from &amp;lt;code&amp;gt;VITE_API_URL&amp;lt;/code&amp;gt; and automatically attaches JWT tokens from localStorage via a request interceptor.&lt;br /&gt;
&lt;br /&gt;
Composables (&amp;lt;code&amp;gt;useServices&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;useIncidents&amp;lt;/code&amp;gt;, etc.) wrap the API calls and return reactive refs:&lt;br /&gt;
&lt;br /&gt;
 const { services, loading, error, fetchServices } = useServices()&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
 # Backend (Jest)&lt;br /&gt;
 cd backend &amp;amp;&amp;amp; npm test&lt;br /&gt;
&lt;br /&gt;
 # Frontend (Vitest)&lt;br /&gt;
 cd frontend &amp;amp;&amp;amp; npm run test:unit&lt;br /&gt;
&lt;br /&gt;
== Git workflow ==&lt;br /&gt;
&lt;br /&gt;
See &amp;lt;code&amp;gt;docs/workflow.md&amp;lt;/code&amp;gt; in the repository for the arc diff workflow.&lt;br /&gt;
&lt;br /&gt;
[[Category:ServPulse|Development guide]]&lt;br /&gt;
[[Category:Developer guide]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=User:Inidal&amp;diff=2341</id>
		<title>User:Inidal</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=User:Inidal&amp;diff=2341"/>
		<updated>2026-02-17T21:43:13Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: Dereckson moved page User:Inidal to User:Ieli: Automatically moved page while renaming the user &amp;quot;Inidal&amp;quot; to &amp;quot;Ieli&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[User:Ieli]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=User:Ieli&amp;diff=2340</id>
		<title>User:Ieli</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=User:Ieli&amp;diff=2340"/>
		<updated>2026-02-17T21:43:13Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: Dereckson moved page User:Inidal to User:Ieli: Automatically moved page while renaming the user &amp;quot;Inidal&amp;quot; to &amp;quot;Ieli&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{User&lt;br /&gt;
| Full name = Eli Iguer&lt;br /&gt;
| Presentation = I am a self-taught software developer based in Edmonton, Alberta, Canada 🇨🇦. My primary focus is on JavaScript and Python, but I am currently expanding my knowledge by learning Rust.&lt;br /&gt;
&lt;br /&gt;
In addition to my technical skills, I have a background in human resource management. Outside of work, I enjoy writing and mixing music, which I share on platforms such as YouTube and Bandcamp.&lt;br /&gt;
| Projects = [[ServPulse]]&amp;lt;br /&amp;gt;{{repo|notification-push}}&lt;br /&gt;
| DevCentral user feed = ieli&lt;br /&gt;
| DevCentral user board = user-ieli&lt;br /&gt;
| GitHub = ieliofficial&lt;br /&gt;
| Personal site = [https://inidal.dev/ Eli&#039;s Hub]&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Mail&amp;diff=2268</id>
		<title>Mail</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Mail&amp;diff=2268"/>
		<updated>2026-02-15T14:17:07Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Nasqueron maintains a mail infrastructure both for applications and for users.&lt;br /&gt;
&lt;br /&gt;
For the operations grimoire, see [[Operations grimoire/Mail]].&lt;br /&gt;
&lt;br /&gt;
== @nasqueron.org mail addresses ==&lt;br /&gt;
=== Use ===&lt;br /&gt;
To access your @nasqueron.org mailbox, you can use webmail or any client of your choice.&lt;br /&gt;
&lt;br /&gt;
Webmail:&lt;br /&gt;
* https://mail.nasqueron.org/snappymail/&lt;br /&gt;
&lt;br /&gt;
Server access:&lt;br /&gt;
&lt;br /&gt;
;IMAP&lt;br /&gt;
* mail.nasqueron.org on port 143 with STARTTLS support&lt;br /&gt;
* mail.nasqueron.org on port 993 for TLS&lt;br /&gt;
;POP3&lt;br /&gt;
* mail.nasqueron.org on port 110 with STARTTLS support&lt;br /&gt;
* mail.nasqueron.org on port 995 for TLS&lt;br /&gt;
;SMTP&lt;br /&gt;
* mail.nasqueron.org on port 587 with STARTTLS&lt;br /&gt;
* The SMTP server requires authentication&lt;br /&gt;
* The port 25 SHOULD be restricted to server-to-server connections&lt;br /&gt;
&lt;br /&gt;
Authentication:&lt;br /&gt;
* Your username is the FULL e-mail address, ie &amp;lt;code&amp;gt;user@nasqueron.org&amp;lt;/code&amp;gt;, not only &amp;lt;code&amp;gt;user&amp;lt;/code&amp;gt;&lt;br /&gt;
* Your password should work for IMAP, POP3 and SMTP servers&lt;br /&gt;
&lt;br /&gt;
Guides:&lt;br /&gt;
* [[Connect to mail server with Thunderbird]]&lt;br /&gt;
&lt;br /&gt;
To change password:&lt;br /&gt;
* If you know your password, it&#039;s self-service at https://admin.mail.nasqueron.org/auth/change-password&lt;br /&gt;
* If you lost your password, open a task on DevCentral, add #mail and #security projects&lt;br /&gt;
&lt;br /&gt;
=== Create a new mailbox ===&lt;br /&gt;
You can open a ticket on https://devcentral.nasqueron.org/ and associate it to the Mail tag.&lt;br /&gt;
&lt;br /&gt;
You can also ask on IRC Libera Chat #nasqueron-ops.&lt;br /&gt;
&lt;br /&gt;
== Host a domain ==&lt;br /&gt;
Any open-source or free culture project can host a domain at Nasqueron for mail hosting.&lt;br /&gt;
&lt;br /&gt;
When a domain uses reasonably low bandwidth and disk space (&amp;lt; 120 Gb), it can directly be hosted on our mail server, free of charge.&lt;br /&gt;
&lt;br /&gt;
For domains needing more resources, we can deploy a new server. In such case, you&#039;ll need to enter a co-billing agreement.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features:&#039;&#039;&#039;&lt;br /&gt;
* DKIM signature&lt;br /&gt;
* Help to setup DKIM, SPF and DMARC DNS records&lt;br /&gt;
* Web UI to create and manage mailboxes, aliases (ViMbAdmin) for your domains&lt;br /&gt;
* Webmail access&lt;br /&gt;
* POP3 / IMAP / SMTP access&lt;br /&gt;
* We can also setup mailing lists - we use Sympa at Nasqueron, possibility to setup Majordomo 2 or Mailman&lt;br /&gt;
* Participation to the governance discussions&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To request&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Open a task on [https://devcentral.nasqueron.org/ DevCentral] tagged with the Mail project where you present your open-source or free culture project and your needs. A member of Nasqueron Operations SIG will contact you and setup resources according your request.&lt;br /&gt;
&lt;br /&gt;
== Domains ==&lt;br /&gt;
&lt;br /&gt;
Mail core infrastructure:&lt;br /&gt;
* @nasqueron.org (general purpose, normal to high priority)&lt;br /&gt;
* @wolfplex.be and @wolfplex.org (for Wolfplex Hackerspace) and @ook.space (mainly a test domain)&lt;br /&gt;
* Yes, we can add custom domains there&lt;br /&gt;
&lt;br /&gt;
Still to configure:&lt;br /&gt;
* @lists.nasqueron.org (mailing lists, low to normal priority)&lt;br /&gt;
&lt;br /&gt;
Servers domains:&lt;br /&gt;
* @dwellers.nasqueron.org (not configured, low priority)&lt;br /&gt;
* @ysul.nasqueron.org (works)&lt;br /&gt;
&lt;br /&gt;
Some subdomains are dedicated to applications and handled by 3rd party providers:&lt;br /&gt;
* @devcentral.nasqueron.org is managed by Mailgun for Phabricator ingoing and outgoing mail&lt;br /&gt;
* @discourse.nasqueron.org is managed by Mandrill for Discourse outgoing mail&lt;br /&gt;
&lt;br /&gt;
No @*.nasqueron.org mail is handled by Google for applications.&lt;br /&gt;
&lt;br /&gt;
== Get support ==&lt;br /&gt;
&lt;br /&gt;
Angelina, Dorian and Dereckson can help you. Open a task on DevCentral to request support for any mail related task:&lt;br /&gt;
&lt;br /&gt;
{{Call for action&lt;br /&gt;
|link=https://devcentral.nasqueron.org/maniphest/task/edit/form/1/?projects=mail&amp;amp;subscribers=dereckson,dorianwinty,aceppaluni&lt;br /&gt;
|text=Get mail support&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributor guide]]&lt;br /&gt;
[[Category:Mail]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Lexicon&amp;diff=2266</id>
		<title>Lexicon</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Lexicon&amp;diff=2266"/>
		<updated>2026-02-15T13:05:47Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* S */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This lexicon defines key terms, expressions, and internal concepts used across the Nasqueron open source project.&lt;br /&gt;
&lt;br /&gt;
== B ==&lt;br /&gt;
&lt;br /&gt;
; Bastion&lt;br /&gt;
: A hardened entry point to connect securely to the Nasqueron infrastructure, generally via SSH. Only the bastion is exposed to the Internet; internal hosts are accessed through it.&lt;br /&gt;
: 📖 [[Operations grimoire/Recommended SSH configuration]]&lt;br /&gt;
&lt;br /&gt;
== C ==&lt;br /&gt;
&lt;br /&gt;
; CARP&lt;br /&gt;
: Common Access Redundancy Protocol (CARP) is a protocol which allows multiple hosts to share the same IP address.&lt;br /&gt;
: 📖 [[Protocol CARP]]&lt;br /&gt;
: 📖 [https://docs.freebsd.org/en/books/handbook/advanced-networking/#carp FreeBSD Handbook]&lt;br /&gt;
&lt;br /&gt;
== D ==&lt;br /&gt;
&lt;br /&gt;
; DevCentral&lt;br /&gt;
: The name of the Phabricator/Phorge instance used at Nasqueron to coordinate tasks, track issues, and perform code reviews across projects.&lt;br /&gt;
&lt;br /&gt;
== E ==&lt;br /&gt;
&lt;br /&gt;
; Eglide&lt;br /&gt;
: A shell hosting project operated by Nasqueron members. Focused on providing traditional Linux shell environments for learning, scripting, and digital minimalism.&lt;br /&gt;
: 📖 [[Eglide]]&lt;br /&gt;
&lt;br /&gt;
== F ==&lt;br /&gt;
&lt;br /&gt;
; Forest&lt;br /&gt;
: A group of servers, with specific UNIX groups to create and users to provision. The concept of forest is only used for users/groups ACL, as services to provisions are by roles instead.&lt;br /&gt;
&lt;br /&gt;
== H ==&lt;br /&gt;
&lt;br /&gt;
; Hackerspace&lt;br /&gt;
: A collaborative community space where members share tools, skills, and ideas. Wolfplex Hackerspace serves as a physical counterpart to the online Nasqueron ecosystem.&lt;br /&gt;
&lt;br /&gt;
; Infrastructure as Code (IaC)&lt;br /&gt;
: The practice of defining system configuration and provisioning entirely through cod using tools like Ansible, Terraform, SaltStack, ensuring reproducibility and transparency.&lt;br /&gt;
&lt;br /&gt;
== K ==&lt;br /&gt;
&lt;br /&gt;
; Keycloak&lt;br /&gt;
: The preferred open source solution for implementing Single Sign-On (SSO) and Identity Management (IDM) across Nasqueron services.&lt;br /&gt;
&lt;br /&gt;
; Keruald&lt;br /&gt;
: Set of libraries to build PHP applications.&lt;br /&gt;
: [[Keruald]]&lt;br /&gt;
&lt;br /&gt;
== M ==&lt;br /&gt;
&lt;br /&gt;
; Manifest&lt;br /&gt;
: A YAML or JSON file describing configuration or metadata for a project, service, or deployment. Manifests are versioned in Git.&lt;br /&gt;
&lt;br /&gt;
; Manyrepo&lt;br /&gt;
: A hybrid approach between monorepo and polyrepo, where related components are grouped together in a few larger repositories. Used in a few Nasqueron projects to balance modularity with ease of maintenance.&lt;br /&gt;
: A repository which looks like its own separate repository, but exported from a monorepo. Needed for some packages tooling like Composer. That&#039;s the strategy used to publish Keruald libraries.&lt;br /&gt;
&lt;br /&gt;
; Monorepo&lt;br /&gt;
: A single repository containing multiple projects or components, allowing shared tooling, consistent dependency management, and atomic changes across modules.&lt;br /&gt;
&lt;br /&gt;
== N ==&lt;br /&gt;
&lt;br /&gt;
; Node&lt;br /&gt;
: A specific server in our Operations repository context. A node belongs to a forest. The server can be a physical server, a VM or a network appliance.&lt;br /&gt;
&lt;br /&gt;
== O ==&lt;br /&gt;
&lt;br /&gt;
; OmniTools&lt;br /&gt;
: A PHP library developed by Nasqueron, providing reusable utilities and abstractions across projects&lt;br /&gt;
&lt;br /&gt;
; Omni-OS&lt;br /&gt;
: The infrastructure strategy combining FreeBSD, Rocky Linux / CentOS Stream, and Debian to leverage the strengths of multiple operating systems.&lt;br /&gt;
&lt;br /&gt;
== P ==&lt;br /&gt;
; Polyrepo&lt;br /&gt;
: A source code organization strategy where each project or service has its own separate repository. Common when projects evolve independently or have different lifecycles.&lt;br /&gt;
&lt;br /&gt;
== S ==&lt;br /&gt;
&lt;br /&gt;
; ServPulse&lt;br /&gt;
: Project to create a status page.&lt;br /&gt;
: 📖 [[ServPulse]]&lt;br /&gt;
&lt;br /&gt;
; SSO&lt;br /&gt;
: Single Sign-On. A centralized authentication mechanism allowing contributors to log in once to access multiple Nasqueron services seamlessly.&lt;br /&gt;
&lt;br /&gt;
; Salt&lt;br /&gt;
: Refers to SaltStack, the configuration management tool used for provisioning and maintaining Nasqueron infrastructure nodes.&lt;br /&gt;
&lt;br /&gt;
== T ==&lt;br /&gt;
&lt;br /&gt;
; Tigraki&lt;br /&gt;
: Former server name, originating from the Aion universe. Represents curiosity and technical creativity.&lt;br /&gt;
&lt;br /&gt;
== W ==&lt;br /&gt;
&lt;br /&gt;
; Waystone&lt;br /&gt;
: A namespace for Obsidan Workspaces ecosystem, to use on Packagist/Composer, inspired by magical or navigational stones guiding travelers.&lt;br /&gt;
&lt;br /&gt;
; WindRiver&lt;br /&gt;
: Dedicated development server&lt;br /&gt;
: 📖 [[WindRiver]], [[Devserver reference]]&lt;br /&gt;
&lt;br /&gt;
; Wolfplex&lt;br /&gt;
: The physical hackerspace and community in Belgium linked to Nasqueron. Hosts events, experimentation, and outreach.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;This lexicon evolves with the project. Contributors are encouraged to expand and refine it as new terms appear or gain significance at Nasqueron.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Lexicon&amp;diff=2265</id>
		<title>Lexicon</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Lexicon&amp;diff=2265"/>
		<updated>2026-02-15T13:05:06Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: +CARP&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This lexicon defines key terms, expressions, and internal concepts used across the Nasqueron open source project.&lt;br /&gt;
&lt;br /&gt;
== B ==&lt;br /&gt;
&lt;br /&gt;
; Bastion&lt;br /&gt;
: A hardened entry point to connect securely to the Nasqueron infrastructure, generally via SSH. Only the bastion is exposed to the Internet; internal hosts are accessed through it.&lt;br /&gt;
: 📖 [[Operations grimoire/Recommended SSH configuration]]&lt;br /&gt;
&lt;br /&gt;
== C ==&lt;br /&gt;
&lt;br /&gt;
; CARP&lt;br /&gt;
: Common Access Redundancy Protocol (CARP) is a protocol which allows multiple hosts to share the same IP address.&lt;br /&gt;
: 📖 [[Protocol CARP]]&lt;br /&gt;
: 📖 [https://docs.freebsd.org/en/books/handbook/advanced-networking/#carp FreeBSD Handbook]&lt;br /&gt;
&lt;br /&gt;
== D ==&lt;br /&gt;
&lt;br /&gt;
; DevCentral&lt;br /&gt;
: The name of the Phabricator/Phorge instance used at Nasqueron to coordinate tasks, track issues, and perform code reviews across projects.&lt;br /&gt;
&lt;br /&gt;
== E ==&lt;br /&gt;
&lt;br /&gt;
; Eglide&lt;br /&gt;
: A shell hosting project operated by Nasqueron members. Focused on providing traditional Linux shell environments for learning, scripting, and digital minimalism.&lt;br /&gt;
: 📖 [[Eglide]]&lt;br /&gt;
&lt;br /&gt;
== F ==&lt;br /&gt;
&lt;br /&gt;
; Forest&lt;br /&gt;
: A group of servers, with specific UNIX groups to create and users to provision. The concept of forest is only used for users/groups ACL, as services to provisions are by roles instead.&lt;br /&gt;
&lt;br /&gt;
== H ==&lt;br /&gt;
&lt;br /&gt;
; Hackerspace&lt;br /&gt;
: A collaborative community space where members share tools, skills, and ideas. Wolfplex Hackerspace serves as a physical counterpart to the online Nasqueron ecosystem.&lt;br /&gt;
&lt;br /&gt;
; Infrastructure as Code (IaC)&lt;br /&gt;
: The practice of defining system configuration and provisioning entirely through cod using tools like Ansible, Terraform, SaltStack, ensuring reproducibility and transparency.&lt;br /&gt;
&lt;br /&gt;
== K ==&lt;br /&gt;
&lt;br /&gt;
; Keycloak&lt;br /&gt;
: The preferred open source solution for implementing Single Sign-On (SSO) and Identity Management (IDM) across Nasqueron services.&lt;br /&gt;
&lt;br /&gt;
; Keruald&lt;br /&gt;
: Set of libraries to build PHP applications.&lt;br /&gt;
: [[Keruald]]&lt;br /&gt;
&lt;br /&gt;
== M ==&lt;br /&gt;
&lt;br /&gt;
; Manifest&lt;br /&gt;
: A YAML or JSON file describing configuration or metadata for a project, service, or deployment. Manifests are versioned in Git.&lt;br /&gt;
&lt;br /&gt;
; Manyrepo&lt;br /&gt;
: A hybrid approach between monorepo and polyrepo, where related components are grouped together in a few larger repositories. Used in a few Nasqueron projects to balance modularity with ease of maintenance.&lt;br /&gt;
: A repository which looks like its own separate repository, but exported from a monorepo. Needed for some packages tooling like Composer. That&#039;s the strategy used to publish Keruald libraries.&lt;br /&gt;
&lt;br /&gt;
; Monorepo&lt;br /&gt;
: A single repository containing multiple projects or components, allowing shared tooling, consistent dependency management, and atomic changes across modules.&lt;br /&gt;
&lt;br /&gt;
== N ==&lt;br /&gt;
&lt;br /&gt;
; Node&lt;br /&gt;
: A specific server in our Operations repository context. A node belongs to a forest. The server can be a physical server, a VM or a network appliance.&lt;br /&gt;
&lt;br /&gt;
== O ==&lt;br /&gt;
&lt;br /&gt;
; OmniTools&lt;br /&gt;
: A PHP library developed by Nasqueron, providing reusable utilities and abstractions across projects&lt;br /&gt;
&lt;br /&gt;
; Omni-OS&lt;br /&gt;
: The infrastructure strategy combining FreeBSD, Rocky Linux / CentOS Stream, and Debian to leverage the strengths of multiple operating systems.&lt;br /&gt;
&lt;br /&gt;
== P ==&lt;br /&gt;
; Polyrepo&lt;br /&gt;
: A source code organization strategy where each project or service has its own separate repository. Common when projects evolve independently or have different lifecycles.&lt;br /&gt;
&lt;br /&gt;
== S ==&lt;br /&gt;
&lt;br /&gt;
; SSO&lt;br /&gt;
: Single Sign-On. A centralized authentication mechanism allowing contributors to log in once to access multiple Nasqueron services seamlessly.&lt;br /&gt;
&lt;br /&gt;
; Salt&lt;br /&gt;
: Refers to SaltStack, the configuration management tool used for provisioning and maintaining Nasqueron infrastructure nodes.&lt;br /&gt;
&lt;br /&gt;
== T ==&lt;br /&gt;
&lt;br /&gt;
; Tigraki&lt;br /&gt;
: Former server name, originating from the Aion universe. Represents curiosity and technical creativity.&lt;br /&gt;
&lt;br /&gt;
== W ==&lt;br /&gt;
&lt;br /&gt;
; Waystone&lt;br /&gt;
: A namespace for Obsidan Workspaces ecosystem, to use on Packagist/Composer, inspired by magical or navigational stones guiding travelers.&lt;br /&gt;
&lt;br /&gt;
; WindRiver&lt;br /&gt;
: Dedicated development server&lt;br /&gt;
: 📖 [[WindRiver]], [[Devserver reference]]&lt;br /&gt;
&lt;br /&gt;
; Wolfplex&lt;br /&gt;
: The physical hackerspace and community in Belgium linked to Nasqueron. Hosts events, experimentation, and outreach.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;This lexicon evolves with the project. Contributors are encouraged to expand and refine it as new terms appear or gain significance at Nasqueron.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Lexicon&amp;diff=2264</id>
		<title>Lexicon</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Lexicon&amp;diff=2264"/>
		<updated>2026-02-15T13:02:33Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* F */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This lexicon defines key terms, expressions, and internal concepts used across the Nasqueron open source project.&lt;br /&gt;
&lt;br /&gt;
== B ==&lt;br /&gt;
&lt;br /&gt;
; Bastion&lt;br /&gt;
: A hardened entry point to connect securely to the Nasqueron infrastructure, generally via SSH. Only the bastion is exposed to the Internet; internal hosts are accessed through it.&lt;br /&gt;
: 📖 [[Operations grimoire/Recommended SSH configuration]]&lt;br /&gt;
&lt;br /&gt;
== D ==&lt;br /&gt;
&lt;br /&gt;
; DevCentral&lt;br /&gt;
: The name of the Phabricator/Phorge instance used at Nasqueron to coordinate tasks, track issues, and perform code reviews across projects.&lt;br /&gt;
&lt;br /&gt;
== E ==&lt;br /&gt;
&lt;br /&gt;
; Eglide&lt;br /&gt;
: A shell hosting project operated by Nasqueron members. Focused on providing traditional Linux shell environments for learning, scripting, and digital minimalism.&lt;br /&gt;
: 📖 [[Eglide]]&lt;br /&gt;
&lt;br /&gt;
== F ==&lt;br /&gt;
&lt;br /&gt;
; Forest&lt;br /&gt;
: A group of servers, with specific UNIX groups to create and users to provision. The concept of forest is only used for users/groups ACL, as services to provisions are by roles instead.&lt;br /&gt;
&lt;br /&gt;
== H ==&lt;br /&gt;
&lt;br /&gt;
; Hackerspace&lt;br /&gt;
: A collaborative community space where members share tools, skills, and ideas. Wolfplex Hackerspace serves as a physical counterpart to the online Nasqueron ecosystem.&lt;br /&gt;
&lt;br /&gt;
; Infrastructure as Code (IaC)&lt;br /&gt;
: The practice of defining system configuration and provisioning entirely through cod using tools like Ansible, Terraform, SaltStack, ensuring reproducibility and transparency.&lt;br /&gt;
&lt;br /&gt;
== K ==&lt;br /&gt;
&lt;br /&gt;
; Keycloak&lt;br /&gt;
: The preferred open source solution for implementing Single Sign-On (SSO) and Identity Management (IDM) across Nasqueron services.&lt;br /&gt;
&lt;br /&gt;
; Keruald&lt;br /&gt;
: Set of libraries to build PHP applications.&lt;br /&gt;
: [[Keruald]]&lt;br /&gt;
&lt;br /&gt;
== M ==&lt;br /&gt;
&lt;br /&gt;
; Manifest&lt;br /&gt;
: A YAML or JSON file describing configuration or metadata for a project, service, or deployment. Manifests are versioned in Git.&lt;br /&gt;
&lt;br /&gt;
; Manyrepo&lt;br /&gt;
: A hybrid approach between monorepo and polyrepo, where related components are grouped together in a few larger repositories. Used in a few Nasqueron projects to balance modularity with ease of maintenance.&lt;br /&gt;
: A repository which looks like its own separate repository, but exported from a monorepo. Needed for some packages tooling like Composer. That&#039;s the strategy used to publish Keruald libraries.&lt;br /&gt;
&lt;br /&gt;
; Monorepo&lt;br /&gt;
: A single repository containing multiple projects or components, allowing shared tooling, consistent dependency management, and atomic changes across modules.&lt;br /&gt;
&lt;br /&gt;
== N ==&lt;br /&gt;
&lt;br /&gt;
; Node&lt;br /&gt;
: A specific server in our Operations repository context. A node belongs to a forest. The server can be a physical server, a VM or a network appliance.&lt;br /&gt;
&lt;br /&gt;
== O ==&lt;br /&gt;
&lt;br /&gt;
; OmniTools&lt;br /&gt;
: A PHP library developed by Nasqueron, providing reusable utilities and abstractions across projects&lt;br /&gt;
&lt;br /&gt;
; Omni-OS&lt;br /&gt;
: The infrastructure strategy combining FreeBSD, Rocky Linux / CentOS Stream, and Debian to leverage the strengths of multiple operating systems.&lt;br /&gt;
&lt;br /&gt;
== P ==&lt;br /&gt;
; Polyrepo&lt;br /&gt;
: A source code organization strategy where each project or service has its own separate repository. Common when projects evolve independently or have different lifecycles.&lt;br /&gt;
&lt;br /&gt;
== S ==&lt;br /&gt;
&lt;br /&gt;
; SSO&lt;br /&gt;
: Single Sign-On. A centralized authentication mechanism allowing contributors to log in once to access multiple Nasqueron services seamlessly.&lt;br /&gt;
&lt;br /&gt;
; Salt&lt;br /&gt;
: Refers to SaltStack, the configuration management tool used for provisioning and maintaining Nasqueron infrastructure nodes.&lt;br /&gt;
&lt;br /&gt;
== T ==&lt;br /&gt;
&lt;br /&gt;
; Tigraki&lt;br /&gt;
: Former server name, originating from the Aion universe. Represents curiosity and technical creativity.&lt;br /&gt;
&lt;br /&gt;
== W ==&lt;br /&gt;
&lt;br /&gt;
; Waystone&lt;br /&gt;
: A namespace for Obsidan Workspaces ecosystem, to use on Packagist/Composer, inspired by magical or navigational stones guiding travelers.&lt;br /&gt;
&lt;br /&gt;
; WindRiver&lt;br /&gt;
: Dedicated development server&lt;br /&gt;
: 📖 [[WindRiver]], [[Devserver reference]]&lt;br /&gt;
&lt;br /&gt;
; Wolfplex&lt;br /&gt;
: The physical hackerspace and community in Belgium linked to Nasqueron. Hosts events, experimentation, and outreach.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;This lexicon evolves with the project. Contributors are encouraged to expand and refine it as new terms appear or gain significance at Nasqueron.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Lexicon&amp;diff=2263</id>
		<title>Lexicon</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Lexicon&amp;diff=2263"/>
		<updated>2026-02-15T13:02:01Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* M */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This lexicon defines key terms, expressions, and internal concepts used across the Nasqueron open source project.&lt;br /&gt;
&lt;br /&gt;
== B ==&lt;br /&gt;
&lt;br /&gt;
; Bastion&lt;br /&gt;
: A hardened entry point to connect securely to the Nasqueron infrastructure, generally via SSH. Only the bastion is exposed to the Internet; internal hosts are accessed through it.&lt;br /&gt;
: 📖 [[Operations grimoire/Recommended SSH configuration]]&lt;br /&gt;
&lt;br /&gt;
== D ==&lt;br /&gt;
&lt;br /&gt;
; DevCentral&lt;br /&gt;
: The name of the Phabricator/Phorge instance used at Nasqueron to coordinate tasks, track issues, and perform code reviews across projects.&lt;br /&gt;
&lt;br /&gt;
== E ==&lt;br /&gt;
&lt;br /&gt;
; Eglide&lt;br /&gt;
: A shell hosting project operated by Nasqueron members. Focused on providing traditional Linux shell environments for learning, scripting, and digital minimalism.&lt;br /&gt;
: 📖 [[Eglide]]&lt;br /&gt;
&lt;br /&gt;
== F ==&lt;br /&gt;
&lt;br /&gt;
; Forest&lt;br /&gt;
: A group of servers, with specific UNIX groups to create and users to provision.&lt;br /&gt;
: It&#039;s for ACL users/groups only, as services to provisions are by roles instead.&lt;br /&gt;
&lt;br /&gt;
== H ==&lt;br /&gt;
&lt;br /&gt;
; Hackerspace&lt;br /&gt;
: A collaborative community space where members share tools, skills, and ideas. Wolfplex Hackerspace serves as a physical counterpart to the online Nasqueron ecosystem.&lt;br /&gt;
&lt;br /&gt;
; Infrastructure as Code (IaC)&lt;br /&gt;
: The practice of defining system configuration and provisioning entirely through cod using tools like Ansible, Terraform, SaltStack, ensuring reproducibility and transparency.&lt;br /&gt;
&lt;br /&gt;
== K ==&lt;br /&gt;
&lt;br /&gt;
; Keycloak&lt;br /&gt;
: The preferred open source solution for implementing Single Sign-On (SSO) and Identity Management (IDM) across Nasqueron services.&lt;br /&gt;
&lt;br /&gt;
; Keruald&lt;br /&gt;
: Set of libraries to build PHP applications.&lt;br /&gt;
: [[Keruald]]&lt;br /&gt;
&lt;br /&gt;
== M ==&lt;br /&gt;
&lt;br /&gt;
; Manifest&lt;br /&gt;
: A YAML or JSON file describing configuration or metadata for a project, service, or deployment. Manifests are versioned in Git.&lt;br /&gt;
&lt;br /&gt;
; Manyrepo&lt;br /&gt;
: A hybrid approach between monorepo and polyrepo, where related components are grouped together in a few larger repositories. Used in a few Nasqueron projects to balance modularity with ease of maintenance.&lt;br /&gt;
: A repository which looks like its own separate repository, but exported from a monorepo. Needed for some packages tooling like Composer. That&#039;s the strategy used to publish Keruald libraries.&lt;br /&gt;
&lt;br /&gt;
; Monorepo&lt;br /&gt;
: A single repository containing multiple projects or components, allowing shared tooling, consistent dependency management, and atomic changes across modules.&lt;br /&gt;
&lt;br /&gt;
== N ==&lt;br /&gt;
&lt;br /&gt;
; Node&lt;br /&gt;
: A specific server in our Operations repository context. A node belongs to a forest. The server can be a physical server, a VM or a network appliance.&lt;br /&gt;
&lt;br /&gt;
== O ==&lt;br /&gt;
&lt;br /&gt;
; OmniTools&lt;br /&gt;
: A PHP library developed by Nasqueron, providing reusable utilities and abstractions across projects&lt;br /&gt;
&lt;br /&gt;
; Omni-OS&lt;br /&gt;
: The infrastructure strategy combining FreeBSD, Rocky Linux / CentOS Stream, and Debian to leverage the strengths of multiple operating systems.&lt;br /&gt;
&lt;br /&gt;
== P ==&lt;br /&gt;
; Polyrepo&lt;br /&gt;
: A source code organization strategy where each project or service has its own separate repository. Common when projects evolve independently or have different lifecycles.&lt;br /&gt;
&lt;br /&gt;
== S ==&lt;br /&gt;
&lt;br /&gt;
; SSO&lt;br /&gt;
: Single Sign-On. A centralized authentication mechanism allowing contributors to log in once to access multiple Nasqueron services seamlessly.&lt;br /&gt;
&lt;br /&gt;
; Salt&lt;br /&gt;
: Refers to SaltStack, the configuration management tool used for provisioning and maintaining Nasqueron infrastructure nodes.&lt;br /&gt;
&lt;br /&gt;
== T ==&lt;br /&gt;
&lt;br /&gt;
; Tigraki&lt;br /&gt;
: Former server name, originating from the Aion universe. Represents curiosity and technical creativity.&lt;br /&gt;
&lt;br /&gt;
== W ==&lt;br /&gt;
&lt;br /&gt;
; Waystone&lt;br /&gt;
: A namespace for Obsidan Workspaces ecosystem, to use on Packagist/Composer, inspired by magical or navigational stones guiding travelers.&lt;br /&gt;
&lt;br /&gt;
; WindRiver&lt;br /&gt;
: Dedicated development server&lt;br /&gt;
: 📖 [[WindRiver]], [[Devserver reference]]&lt;br /&gt;
&lt;br /&gt;
; Wolfplex&lt;br /&gt;
: The physical hackerspace and community in Belgium linked to Nasqueron. Hosts events, experimentation, and outreach.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;This lexicon evolves with the project. Contributors are encouraged to expand and refine it as new terms appear or gain significance at Nasqueron.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Lexicon&amp;diff=2262</id>
		<title>Lexicon</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Lexicon&amp;diff=2262"/>
		<updated>2026-02-15T13:00:51Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* E */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This lexicon defines key terms, expressions, and internal concepts used across the Nasqueron open source project.&lt;br /&gt;
&lt;br /&gt;
== B ==&lt;br /&gt;
&lt;br /&gt;
; Bastion&lt;br /&gt;
: A hardened entry point to connect securely to the Nasqueron infrastructure, generally via SSH. Only the bastion is exposed to the Internet; internal hosts are accessed through it.&lt;br /&gt;
: 📖 [[Operations grimoire/Recommended SSH configuration]]&lt;br /&gt;
&lt;br /&gt;
== D ==&lt;br /&gt;
&lt;br /&gt;
; DevCentral&lt;br /&gt;
: The name of the Phabricator/Phorge instance used at Nasqueron to coordinate tasks, track issues, and perform code reviews across projects.&lt;br /&gt;
&lt;br /&gt;
== E ==&lt;br /&gt;
&lt;br /&gt;
; Eglide&lt;br /&gt;
: A shell hosting project operated by Nasqueron members. Focused on providing traditional Linux shell environments for learning, scripting, and digital minimalism.&lt;br /&gt;
: 📖 [[Eglide]]&lt;br /&gt;
&lt;br /&gt;
== F ==&lt;br /&gt;
&lt;br /&gt;
; Forest&lt;br /&gt;
: A group of servers, with specific UNIX groups to create and users to provision.&lt;br /&gt;
: It&#039;s for ACL users/groups only, as services to provisions are by roles instead.&lt;br /&gt;
&lt;br /&gt;
== H ==&lt;br /&gt;
&lt;br /&gt;
; Hackerspace&lt;br /&gt;
: A collaborative community space where members share tools, skills, and ideas. Wolfplex Hackerspace serves as a physical counterpart to the online Nasqueron ecosystem.&lt;br /&gt;
&lt;br /&gt;
; Infrastructure as Code (IaC)&lt;br /&gt;
: The practice of defining system configuration and provisioning entirely through cod using tools like Ansible, Terraform, SaltStack, ensuring reproducibility and transparency.&lt;br /&gt;
&lt;br /&gt;
== K ==&lt;br /&gt;
&lt;br /&gt;
; Keycloak&lt;br /&gt;
: The preferred open source solution for implementing Single Sign-On (SSO) and Identity Management (IDM) across Nasqueron services.&lt;br /&gt;
&lt;br /&gt;
; Keruald&lt;br /&gt;
: Set of libraries to build PHP applications.&lt;br /&gt;
: [[Keruald]]&lt;br /&gt;
&lt;br /&gt;
== M ==&lt;br /&gt;
&lt;br /&gt;
; Manifest&lt;br /&gt;
: A YAML or JSON file describing configuration or metadata for a project, service, or deployment. Manifests are versioned in Git.&lt;br /&gt;
&lt;br /&gt;
; Manyrepo&lt;br /&gt;
: A hybrid approach between monorepo and polyrepo, where related components are grouped together in a few larger repositories. Used in a few Nasqueron projects to balance modularity with ease of maintenance.&lt;br /&gt;
: A repository which looks like its own separate repository, but exported from a monorepo. Needed for some packages tooling like Composer. That&#039;s the strategy used to publish Keruald libraries.&lt;br /&gt;
&lt;br /&gt;
; Monorepo&lt;br /&gt;
: A single repository containing multiple projects or components, allowing shared tooling, consistent dependency management, and atomic changes across modules.&lt;br /&gt;
&lt;br /&gt;
== O ==&lt;br /&gt;
&lt;br /&gt;
; OmniTools&lt;br /&gt;
: A PHP library developed by Nasqueron, providing reusable utilities and abstractions across projects&lt;br /&gt;
&lt;br /&gt;
; Omni-OS&lt;br /&gt;
: The infrastructure strategy combining FreeBSD, Rocky Linux / CentOS Stream, and Debian to leverage the strengths of multiple operating systems.&lt;br /&gt;
&lt;br /&gt;
== P ==&lt;br /&gt;
; Polyrepo&lt;br /&gt;
: A source code organization strategy where each project or service has its own separate repository. Common when projects evolve independently or have different lifecycles.&lt;br /&gt;
&lt;br /&gt;
== S ==&lt;br /&gt;
&lt;br /&gt;
; SSO&lt;br /&gt;
: Single Sign-On. A centralized authentication mechanism allowing contributors to log in once to access multiple Nasqueron services seamlessly.&lt;br /&gt;
&lt;br /&gt;
; Salt&lt;br /&gt;
: Refers to SaltStack, the configuration management tool used for provisioning and maintaining Nasqueron infrastructure nodes.&lt;br /&gt;
&lt;br /&gt;
== T ==&lt;br /&gt;
&lt;br /&gt;
; Tigraki&lt;br /&gt;
: Former server name, originating from the Aion universe. Represents curiosity and technical creativity.&lt;br /&gt;
&lt;br /&gt;
== W ==&lt;br /&gt;
&lt;br /&gt;
; Waystone&lt;br /&gt;
: A namespace for Obsidan Workspaces ecosystem, to use on Packagist/Composer, inspired by magical or navigational stones guiding travelers.&lt;br /&gt;
&lt;br /&gt;
; WindRiver&lt;br /&gt;
: Dedicated development server&lt;br /&gt;
: 📖 [[WindRiver]], [[Devserver reference]]&lt;br /&gt;
&lt;br /&gt;
; Wolfplex&lt;br /&gt;
: The physical hackerspace and community in Belgium linked to Nasqueron. Hosts events, experimentation, and outreach.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;This lexicon evolves with the project. Contributors are encouraged to expand and refine it as new terms appear or gain significance at Nasqueron.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Main_Page&amp;diff=2259</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Main_Page&amp;diff=2259"/>
		<updated>2026-02-14T18:45:38Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Projects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{DISPLAYTITLE:&amp;lt;span style=&amp;quot;color:white;width:0;font-size:0;&amp;quot;&amp;gt;{{FULLPAGENAME}}&amp;lt;/span&amp;gt;}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin-bottom: 2em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 3.75em; margin-bottom: 0.25em;&amp;quot; class=&amp;quot;color-magnetic-three&amp;quot;&amp;gt;Agora&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 3em;&amp;quot; class=&amp;quot;color-magnetic-two&amp;quot;&amp;gt;The Nasqueron wiki &amp;amp; collaboration space.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;block-col block-col-half&amp;quot;&amp;gt;&lt;br /&gt;
== Welcome to Nasqueron ==&lt;br /&gt;
&lt;br /&gt;
🏴 Nasqueron is a budding community of creative people, writers, developers and thinkers.&lt;br /&gt;
&lt;br /&gt;
🌱👨🏽‍🤝‍👨🏼🧑🏾‍🤝‍🧑🏻🙋🏾‍♂️👩🏾 You&#039;ll find here like-minded people to connect to, hang out, and build projects.&lt;br /&gt;
&lt;br /&gt;
📃 We focus on free culture, ethics and to be a positive change. Our software is open source our datasources and content are licensed under CC-BY-SA or CC-BY license. We share values like respect, justice and equity.&lt;br /&gt;
&lt;br /&gt;
❤️ We like experiments, originality and to discover new things.&lt;br /&gt;
&lt;br /&gt;
👽 We are Nasqueron.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;block-col block-col-half&amp;quot;&amp;gt;&lt;br /&gt;
== Agora ==&lt;br /&gt;
&#039;&#039;&#039;Agora&#039;&#039;&#039; is the Nasqueron wiki.&lt;br /&gt;
&lt;br /&gt;
Like an Agora, it&#039;s intended to be a public open space used for assemblies, with a focus on collaboration.&lt;br /&gt;
&lt;br /&gt;
📙📚✏️ As this is a wiki, feel free to edit it.&amp;lt;br&amp;gt;&lt;br /&gt;
You can [https://forms.nasqueron.org/nasqueron-requests/agora-account/new request an account here] or  [irc://libera.chat/wolfplex ask on IRC].&lt;br /&gt;
&lt;br /&gt;
You&#039;ll mostly find here:&lt;br /&gt;
&lt;br /&gt;
* development and contribution information&lt;br /&gt;
* infrastructure / servers / operations documentation&lt;br /&gt;
* project ideas&lt;br /&gt;
* various notes&lt;br /&gt;
* the content you deem relevant&lt;br /&gt;
&lt;br /&gt;
You can read this main page to explore content, [[Special:Search|do a search]] or [[:Category:Nasqueron root category|browse categories]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;clear&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin-bottom: 2em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 3.75em; margin-bottom: 0.25em;&amp;quot; class=&amp;quot;color-magnetic-three&amp;quot;&amp;gt;Contribute&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;block-col block-col-half&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Free culture &amp;amp; open source ==&lt;br /&gt;
;Guides&lt;br /&gt;
* [[How to contribute code]]&lt;br /&gt;
* [[Code conventions]]&lt;br /&gt;
* [[Dev policies]]&lt;br /&gt;
* [[Devserver reference]]&lt;br /&gt;
* [[AI content]]&lt;br /&gt;
&lt;br /&gt;
;DevCentral&lt;br /&gt;
* [https://devcentral.nasqueron.org/tag/good-first-issue/ Good first issues]: you can start here if you would like a nice landing to our projects&lt;br /&gt;
* [https://devcentral.nasqueron.org/home/menu/view/174/ Contribute to projects]&lt;br /&gt;
* [https://devcentral.nasqueron.org/w/new-repo/ Create a new repository]&lt;br /&gt;
&lt;br /&gt;
;Programs &amp;amp; resources&lt;br /&gt;
* [[Monday office hours]]&lt;br /&gt;
* [[Dev zone/Skills sharing]]&lt;br /&gt;
* [https://join.nasqueron.org Internship &amp;amp; Mentoring programs]&lt;br /&gt;
* [[Internship guide]]&lt;br /&gt;
* [[Nasqueron Labs]], workshops to explore new ideas&lt;br /&gt;
&lt;br /&gt;
;Recipes&lt;br /&gt;
* [[Static sites]]&lt;br /&gt;
* [[Dev zone/Vault|Vault]]&lt;br /&gt;
&lt;br /&gt;
;Dev notes for specific projects&lt;br /&gt;
* [[Limiting Factor]]&lt;br /&gt;
* [[Dev zone/Reports|Nasqueron Reports]]&lt;br /&gt;
&lt;br /&gt;
== Services ==&lt;br /&gt;
* [[Planet]]&lt;br /&gt;
* [[Tools.nasqueron.org]]&lt;br /&gt;
* [[Social media accounts]]&lt;br /&gt;
* [[MediaWiki SaaS]]&lt;br /&gt;
* [[XMPP|Openfire instance]] (XMPP)&lt;br /&gt;
* [[Devserver reference|Development servers]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;block-col block-col-half&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Infrastructure ==&lt;br /&gt;
* [[Operations grimoire]]&lt;br /&gt;
* [[Servers]] map&lt;br /&gt;
&lt;br /&gt;
[[File:Nasqueron Operations Grimoire.jpg|thumb|right|The [[Operations grimoire‎|Nasqueron operations grimoire]] or &#039;&#039;&#039;NOG&#039;&#039;&#039;, the reference to deal with anything on the servers]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nasqueron? ==&lt;br /&gt;
* [[Poem]]&lt;br /&gt;
* To connect with the community, [[Zed]]&lt;br /&gt;
* To declare yourself a Nasqueron inhabitant, [[We are Nasqueron]]&lt;br /&gt;
&lt;br /&gt;
== Projects ==&lt;br /&gt;
* [[Notifications center]]&lt;br /&gt;
* [[Nasqueron Datasources]]&lt;br /&gt;
* [[API]]&lt;br /&gt;
* [[ServPulse]]&lt;br /&gt;
&lt;br /&gt;
; Current network work&lt;br /&gt;
* [[GRE tunnel]]&lt;br /&gt;
* [[Protocol CARP]]&lt;br /&gt;
&lt;br /&gt;
; References&lt;br /&gt;
* [[Registries]] - OID, tags, XML schemas&lt;br /&gt;
&lt;br /&gt;
; Consolidated resources&lt;br /&gt;
* [https://devcentral.nasqueron.org/project/ All projects on DevCentral]&lt;br /&gt;
* [[Projects index]]&lt;br /&gt;
&lt;br /&gt;
; Draft projects ideas&lt;br /&gt;
* [[Tasacora]]&lt;br /&gt;
* [[Fastes consulaires]]&lt;br /&gt;
* [[Utopia Book Reader]]&lt;br /&gt;
&lt;br /&gt;
== Pads ==&lt;br /&gt;
* [[Dereckson pad]]&lt;br /&gt;
* [[Design]]&lt;br /&gt;
&lt;br /&gt;
== Events ==&lt;br /&gt;
* [[Hackathon geodata]]&lt;br /&gt;
&lt;br /&gt;
== We participe to ==&lt;br /&gt;
* [[TrustSpace]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=ServPulse&amp;diff=2248</id>
		<title>ServPulse</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=ServPulse&amp;diff=2248"/>
		<updated>2026-02-12T20:48:29Z</updated>

		<summary type="html">&lt;p&gt;Dereckson: /* Team */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;ServPulse&#039;&#039;&#039; is an open-source status-page platform for publishing the status of services, components, and infrastructure. Its goal is to make it easy to communicate incidents, maintenance, and uptime metrics in a transparent way.&lt;br /&gt;
&lt;br /&gt;
ServPulse is designed to be self-hostable, simple to deploy, and extensible. It provides a foundation for teams and communities to manage status pages, integrate with monitoring tools, and notify users automatically.&lt;br /&gt;
&lt;br /&gt;
The project is community-driven: contributions to the code, documentation, themes, integrations, or translations are all welcome. ServPulse aims to remain open, reliable, and adaptable to different environments, while keeping the setup and use straightforward.&lt;br /&gt;
&lt;br /&gt;
== Technology stack ==&lt;br /&gt;
* Back-end&lt;br /&gt;
** Express.js service&lt;br /&gt;
** API documented according OpenAPI specification&lt;br /&gt;
** PostgreSQL database&lt;br /&gt;
&lt;br /&gt;
* Front-end&lt;br /&gt;
** Vue.js&lt;br /&gt;
** Unit tests in [https://vitest.dev/ Vitest]&lt;br /&gt;
** API queried through [https://axios-http.com/docs/intro Axios]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
* [https://devcentral.nasqueron.org/p/ieli/ Eli] (lead developer)&lt;br /&gt;
* Amine (developer)&lt;br /&gt;
* [[User:Dereckson|Dereckson]] (technical advisory)&lt;br /&gt;
&lt;br /&gt;
Thanks for help to map stories:&lt;br /&gt;
&lt;br /&gt;
* {{u|DorianWinty}}&lt;br /&gt;
* Fauve&lt;br /&gt;
&lt;br /&gt;
== Discussion spaces ==&lt;br /&gt;
* Report issues: [https://devcentral.nasqueron.org/tag/servpulse/ DevCentral]&lt;br /&gt;
* Team discussions: [https://discord.gg/DZQK8Dd8Xd Discord]&lt;br /&gt;
&lt;br /&gt;
== Activities ==&lt;br /&gt;
; Analysis&lt;br /&gt;
* [[/Note of Intent]]&lt;br /&gt;
* [[/Other existing solutions]]&lt;br /&gt;
* [[/Development guide]]&lt;br /&gt;
* [[/Project identity]]: why ServPulse name&lt;br /&gt;
* [[/Domain]]: names used in the project&lt;br /&gt;
* [[/User stories]]&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* [https://devcentral.nasqueron.org/project/view/149/ DevCentral project board]&lt;br /&gt;
* [https://devcentral.nasqueron.org/source/servpulse/ Repository]&lt;br /&gt;
&lt;br /&gt;
[[Category:ServPulse]]&lt;/div&gt;</summary>
		<author><name>Dereckson</name></author>
	</entry>
</feed>