Skip to content

Conversation

@cliffmccarthy
Copy link
Contributor

  • Added a class hierarchy of Deployer objects which implement install(), configure(), and activate() methods for each of the components that comprise a chatmail server.
  • This is intended to provide the same functionality as the current process, though the order of the individual steps has been changed to organize them into the three separate stages of deployment.
  • For more information, see the individual commit messages. The commits are intended to be individually reviewable logical steps in the transformation of the code. Also see the discussion of the new code structure in ARCHITECTURE.md.
  • So far, I have tested this code on fresh installs and some upgrade scenarios, but I have not tested every possible upgrade path from past releases of chatmail/relay.

- Moved the "Add 9.9.9.9 to resolv.conf" step earlier, before the
  creation of users or updates to any config files.  This should not
  affect any of those operations.  Moving this step earlier makes it
  easier to accommodate the restructuring of the deployment process
  into separate components with separate stages for install,
  configure, and activate.
- Added a Deployer class that defines the base for objects that will
  handle installation of individual components, with install,
  configure, and activate stages.  Subclasses will override the
  implementation methods of those stages as needed, while the base
  class handles all the logic of deciding which stages to execute.
- The CMDEPLOY_STAGES environment variable is used to determine what
  stages to run.  If this is not defined, all stages run as usual.
- Added import of Deployer to cmdeploy/__init__.py.  This is not yet
  used, but the next series of commits will use it.
- In deploy_chatmail(), define an empty list of deployers, and call
  the create_groups() and create_users() methods for the items in the
  list.  This list will get filled with Deployer objects in the next
  series of commits.
- Removed now-unused 'debug' variable from deploy_chatmail().
- Note that this moves the installation of the opendkim package
  earlier in the deployment sequence.  Previously, it was installed
  during the _configure_opendkim() routine.
- This splits the existing deploy_iroh_relay() routine into methods
  for the install, configure, and activate stages.
- This splits the existing deploy_acmetool() routine into methods for
  the install, configure, and activate stages.
- This splits the existing deploy_mtail() routine into methods for the
  install, configure, and activate stages.
- This splits the existing _uninstall_mta_sts_daemon() routine into
  methods for the configure and activate stages.
- This replaces the existing _remove_rspamd() routine with a method
  for the install stage.
- Split _install_remote_venv_with_chatmaild() into three routines, to
  handle the install, configure, and activate stages.
- This moves the upload of chatmail.ini later in the deployment
  process, because it is a configuration file specific to the
  instance, not software installation that would be uniform across all
  deployments.
- This moves the installation of cron earlier in the deployment sequence.
- This class is a special case because it has a dependency on the
  Postfix and Dovecot deployers.  When deciding whether to restart the
  echobot service, it needs to know whether the Postfix and Dovecot
  deployers restarted their services.  To support this dependency, the
  PostfixDeployer and DovecotDeployer objects are passed to the
  EchobotDeployer object, so it can check their was_restarted
  attributes.
- This adds a step to create /var/www in the install stage, because
  the directory needs to exist for the rsync in the configure stage to
  work.
- This splits the existing deploy_turn_server() routine into methods
  for the install, configure, and activate stages.
- The 'curl' program is used in TurnDeployer and IrohDeployer, so it
  makes more sense to install it at the beginning in ChatmailDeployer,
  rather than have each thing that uses it install it separately.
- The previous commits that added Deployer classes mostly kept
  deployment operations in the same order that they were in before.
  To organize the process into separate stages for install, configure,
  and activate, we need to reorder the method calls.  This is the
  commit that does that, and thus this is the commit that has the
  largest effect on the order of operations.
- The calls for the deployer objects are all reordered here so that
  the methods are called in the same sequence for each stage.  This
  will allow us to collect the calls into loops in the next commit.
  This commit provides a way to see a diff showing exactly how the
  sequence changed.
- The sequence of deployers was largely based on preserving the order
  of the "activate" stage, as this seems like the place order might be
  the most likely to matter.  Installation of packages and
  configuration of files should generally be able to run in any order.
  (ChatmailDeployer handles updating the apt data, and therefore needs
  to be first, however.)
- Revised deploy_chatmail() to use all_deployers to call the
  install(), configure(), and activate() methods on all the deployers,
  rather than listing them explicitly in the code.
- Updated ARCHITECTURE.md to describe the Deployer class hierarchy and
  the motivations behind it.
Copy link
Contributor

@missytake missytake left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love it! It makes the whole structure much clearer, and the commit structure made it very pleasant to review.

I have some small suggestions, none of them critical.

I like how it stays inconsistent whether a Deployer class is definied in cmdeploy/__init__.py or in a subdirectory (with acmetool). I think many of the Deployers could be in subdirectories, because they are pretty isolated, like turn, iroh, opendkim, journald, and mtail. For some it might make sense to have them in __init__.py because you can see at one glance whether they interact with other services (like acmetool, actually?).

I started the CI in #696, so we can notice errors, just in case.
We should probably have more than just my review for this, as it changes the structure deeply? @hpk42 @link2xt

Comment on lines +1037 to +1046
files.put(
name="Add Deltachat OBS GPG key to apt keyring",
src=importlib.resources.files(__package__).joinpath(
"obs-home-deltachat.gpg"
),
dest="/etc/apt/keyrings/obs-home-deltachat.gpg",
user="root",
group="root",
mode="644",
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be completely removed as we don't install dovecot from OBS anymore :) We don't need to set present=False imo because the file doesn't hurt either.

Comment on lines +1186 to +1188
nginx_deployer,
rspamd_deployer,
fcgiwrap_deployer,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
nginx_deployer,
rspamd_deployer,
fcgiwrap_deployer,
fcgiwrap_deployer,
nginx_deployer,
rspamd_deployer,

I think we should activate fcgiwrap before nginx actually, otherwise there might be a short time where nginx routes to the fcgiwrap port but nothing listens.

Comment on lines +1175 to +1177
chatmail_deployer,
turn_deployer,
unbound_deployer,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
chatmail_deployer,
turn_deployer,
unbound_deployer,
chatmail_deployer,
unbound_deployer,
turn_deployer,

My head finds it more logical to do unbound before turn deployment, as DNS resolving is more system preparation.

Having turn being deployed next to iroh-relay makes sense as well.

I don't see a technical necessity to do it either way though.

rspamd_deployer,
fcgiwrap_deployer,
echobot_deployer,
journald_deployer,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit surprised journald is activated so late in the process - isn't logging important to the entire process, too? I think it should be directly before or after chatmail_deployer.

Comment on lines +1 to 3
## Chatmail Server

This diagram shows components of the chatmail server; this is a draft
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Chatmail Server
This diagram shows components of the chatmail server; this is a draft
# Chatmail Relay
This diagram shows components of the chatmail relay server; this is a draft

Let's use chatmail relay or chatmail relay server ;) it does in some situations make sense to say "chatmail relay server" to clarify that it runs on servers; In general we like to say "relay" instead of "server" to point out that it doesn't really store messages and only relays them.

@missytake
Copy link
Contributor

CI fails to download iroh-relay on the ipv4-only runner o.0 this did not happen before. Any ideas?

--> Starting operation: Download iroh-relay 
    [staging-ipv4.testrun.org]   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
    [staging-ipv4.testrun.org]                                  Dload  Upload   Total   Spent    Left  Speed
    [staging-ipv4.testrun.org] 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (6) Could not resolve host: github.com
    [staging-ipv4.testrun.org] 
    [staging-ipv4.testrun.org] gzip: stdin: unexpected end of file
    [staging-ipv4.testrun.org] tar: This does not look like a tar archive
    [staging-ipv4.testrun.org] tar: ./iroh-relay: Not found in archive
    [staging-ipv4.testrun.org] tar: Exiting with failure status due to previous errors
    [staging-ipv4.testrun.org] Error: executed 0 commands

Maybe unbound needs to be activated before the installation step? This would mess with the general concept of course.

@cliffmccarthy
Copy link
Contributor Author

CI fails to download iroh-relay on the ipv4-only runner o.0 this did not happen before. Any ideas?

The "Download chatmail-turn" step runs almost the exact same thing and it worked in that run. The only thing that happened between that step and "Download iroh-relay" was installation of unbound, so that does suggest that unbound has something to do with it. I wonder if we can do the same thing I did with nginx to prevent the service from starting up as soon as it is installed.

@missytake
Copy link
Contributor

missytake commented Oct 27, 2025

Ah, then unbound is out of the box simply misconfigured for an ipv4 only host?

- On an IPv4-only system, if unbound is started but not configured, it
  causes subsequent steps to fail to resolve hosts.
- Revised UnboundDeployer.install_impl() to use policy-rc.d to prevent
  the service from starting when installed.  This is the same
  mechanism used to keep nginx from starting on install.
@cliffmccarthy
Copy link
Contributor Author

Ah, then unbound is out of the box simply misconfigured for an ipv4 only host?

That seems possible, given what we have observed here. I haven't investigated how it works very deeply.

I made the revision to use policy-rc.d like with nginx, and it works fine on a fresh install. You can cherry-pick commit 32b0472 onto the CI pull request to see if that solves it for the IPv4 system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants