Orchestrate Prosody using a separate container #236
RemiBardon
started this conversation in
Ideas
Replies: 2 comments
-
@valeriansaliou I'm wrapping up a few things but after I'm done I'll move on to this. While it might seem a bit overkill just to make and restore backups, it really is a far cleaner solution. Not doing this would probably cause as much work in the long run (maybe even short term, I'm sure it's a can of worms). Conceptually, are you okay with it? |
Beta Was this translation helpful? Give feedback.
0 replies
-
Sounds good |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Context
Architecture of a Prose Pod
Currently, Prose Pods are made of three parts:
prose-pod-server
prose-pod-api
Prosody is configured using a file on disk, and its data is persisted in different formats as files in a directory.
For security reasons, Prosody data files are only accessible to the Prose Pod Server, and the Prose Pod API has no way to access it. The only thing from a Prose Pod Server that the Prose Pod API has access to is the directory containing configuration files (
/etc/prosody
) — which could already be considered too much since it contains SSL certificates. For reasons detailed in ADR: Interact with Prosody using a REST API, the Prose Pod API uses a Prosody module exposing a HTTP ReST API to perform actions in Prosody (update team members, reload the configuration file…).Problems encountered with the current architecture
Cumbersome bootstrapping (which is planned to be redesigned)
This architecture posed a lot of challenges since the very beginning, and continues posing more and more of them. The bootstrapping process1 already shows limitations2 which will be cumbersome for users in production environments, forcing a redesign in the near future. We haven’t though about a new design, but keeping the current architecture we would probably end up with a very bad design.
Factory reset that can leak data
As we introduce higher-level operations like performing a factory reset (#130), we really hit technical limitations:
prosodyctl reload
prosodyctl reload
could leak data that’s kept in memory (e.g. caches)LifecycleManager
to allow the API to reload itself at runtime, which adds a ton of unnecessary complexityMemberService
caches) are not emptied, which could leak dataBackup & restore which would need to be implemented in Lua
Because the API doesn’t have access to Prosody data, backup (#131) and restore (#132) features (which still need to be designed) would need to be implemented in Prosody, in Lua. We are not very experienced in Lua and creating a tarball/zip in Lua then stream it to the API would likely be easy to get wrong.
Another consequence of writing it in Prosody is that we’d have to make a new release of the Server every time we work on the backup or restore features in the API. The Prose Pod Server could be used as a standalone XMPP server, therefore it seems incorrect to make releases just for work on Prose Pod API features.
Prosody storage migration which would add complexity in the API code
The Prose Pod API already supports creating a Prose Pod Server with different storage backends in Prosody. However, once the choice has been made, one cannot change this or it would break their Prose Pod. Prosody has a migration tool called Prosody Migrator, but adding support for it would add a ton of logic in the API code, therefore adding complexity in our day-to-day work. This logic could at least be hidden away.
Proposal: a new container used for orchestration
We create a new Docker image called
prose-pod-orchestrator
or something like that (though IMO we should avoidprose-pod-ctl
in case we create a CLI one day), which would act as an orchestrator for all other parts of the Prose Pod. It wouldn’t expose any port externally, and would be called exclusively by the Prose Pod API. Its role would be to perform lifecycle operations (start, restart, migrate DB…) on other parts of the Prose Pod, and synchronize all of it.Note: This proposal was sparked by MattJ saying:
Cumbersome bootstrapping: fixed
It could, at startup, generate the bootstrapping configuration for Prosody, then start both Prosody and the API. This would greatly simplify the administration of a Prose Pod.
Data leaks on factory resets: fixed
By completely killing Server and API containers, it would ensure no in-memory data can leak, while simplifying the code in both projects.
This would allow also us to use SQLite as Prosody's default backend, improving performance significantly for some operations.
Backups & restore: easy
Since it wouldn’t be accessible via the outside World like the Prose Pod API is, and its feature set would be very limited, we could mount Prosody’s data directory into it and let it handle backup and restore features. Since it would be written in a safer language than Lua (very likely in Rust), performing those operations would be a lot easier to get right and maintain. We could even easily write tests to ensure backups can be restored3!
Prosody storage migrations: easy
We could wrap all migration logic in the orchestrator, allowing it to stop the API while performing migrations on the Server, or even do migrations on the API’s database which aren’t currently supported.
Prosody-specific code in the API: still there partly, but won’t grow too much
Since it would need to generate bootstrapping configurations, and would very likely be written in Rust, we could reuse the
prosody-config
crate in the orchestrator. However, the API would still have a ton of Prosody-related code, because it needs to send stanzas viamod_rest
and interact withmod_admin_rest
andmod_http_oauth2
. It wouldn’t make sense to use the orchestrator for all of this so we’ll have to keep it in the API unfortunately.Consequences
TODO
Notes
Since Prosŏdy IM Chatroom messages aren’t persisted, here is an archive of the conversation which sparked this idea (bold style added by me for readability):
Prosŏdy IM Chatroom archive (click to expand)
Rémi (me):
MattJ:
Rémi (me):
MattJ:
Zash:
MattJ:
Rémi (me):
MattJ:
Rémi (me):
MattJ:
Rémi (me):
MattJ:
Rémi (me):
MattJ:
Rémi (me):
Jonas’:
Rémi (me):
MattJ:
Jonas’:
MattJ:
Zash:
Jonas’:
Rémi (me):
MattJ:
Rémi (me):
Rémi (me):
MattJ:
Footnotes
Starting Prosody alongside the API with shared credentials and configuration to allow the first interaction between the API and the Server at startup ↩
The bootstrapping configuration file is mounted in both the API and the Server, but the API cannot update it before Prosody starts to add the module it requires, so if it’s incorrect then the Prose Pod is unusable. We will change some configuration over time, to add new administration modules or change the way we configure them (before the first startup), and this will break all clients and force them to update the file manually. It really is bad UX and should be avoided. ↩
Would it be more complicated otherwise? Not entirely sure, but it would with this architecture. ↩
Beta Was this translation helpful? Give feedback.
All reactions