Skip to content

Send email notifications about email updates - #200

Merged
hannesm merged 16 commits into
mainfrom
update_u
Jan 25, 2026
Merged

hannesm merged 16 commits into
mainfrom
update_u

Conversation

@PizieDust

@PizieDust PizieDust commented Dec 28, 2025

Copy link
Copy Markdown
Collaborator

This PR runs a background check on all running unikernel instances and then sends emails to users concerned about which unikernels have updates.

Email example

image

@PizieDust
PizieDust requested a review from hannesm December 28, 2025 19:11
@PizieDust

Copy link
Copy Markdown
Collaborator Author

For unikernel updates notifications, we can run a simple cronjob that calls the endpoint with a validate authentication header:

0 0 * * * /usr/bin/curl -X GET "https://mollymawk.robur.coop/api/admin/unikernels/check-updates" -H "Authorization: Bearer YOUR_TOKEN_HERE"

@PizieDust

Copy link
Copy Markdown
Collaborator Author

This PR is being merged into #199 so we can see only the commits that belong here. Once #199 is merged, will rebase and then change the merge to be into the main branch.

@hannesm

hannesm commented Dec 29, 2025

Copy link
Copy Markdown
Contributor

I've not looked into the code, but I don't understand why there is an HTTP endpoint and an external trigger needed. What is the advantage over "every day at Y o'clock, gather the updates and send mails"? To me it feels like (a) there's some other system needed for the trigger (which can fail), (b) there's a DoS vector (calling every second that endpoint leads to mollymawk doing lots of work and sending lots of mails).

@PizieDust

Copy link
Copy Markdown
Collaborator Author

@hannesm I think the CI failure is unrelated to the PR

@hannesm

hannesm commented Jan 20, 2026

Copy link
Copy Markdown
Contributor

@hannesm I think the CI failure is unrelated to the PR

yes, this should be fixed by rerunning (ref ocaml/dune#13299 and the workaround ocaml/opam-repository#29219). I restarted the failing builds.

Comment thread email_config.ml Outdated
Comment thread unikernel.ml Outdated
Comment thread unikernel.ml
let delay = seconds_until_next_midnight () in
Logs.info (fun m -> m "Next background update in %.0f seconds" delay);
Mirage_sleep.ns (Duration.of_sec (int_of_float delay)) >>= fun () ->
Lwt.catch

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What kind of exceptions do you expect here? I'm curious why using Lwt.catch now, while I thought our code would not expose exceptions (apart from out of memory). In your testing, did you encounter some exception here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I didn't encounter any specific bugs but my understanding is that (I could be wrong), with Lwt.async if something fails, the loop won't get restarted automatically and since we are calling external services (builder_web) etc, I'm not sure if everything will always go well, so Lwt.catch was in case something happens, then atleast the loop can run again the next midnight..

Comment thread unikernel.ml
Lwt.pause () >>= fun () ->
let http = Paf.http_service ~error_handler request_handler in
let (`Initialized th) = Paf.serve http service in
Lwt.pause () >>= fun () ->

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't understand these Lwt.pause () -- but I think you discussed them with Romain?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Without Lwt.pause I was facing a terrible issue where the scheduler might be running but nothing else in mollymawk works, as in, I couldn't open the web platform at all, it will timeout continously.

Comment thread utils.ml
port : int;
sender_email : Mrmime.Mailbox.t;
mollymawk_domain : string;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this persisted to disk? Do we need to care about old configurations (and somewhere increase a version number)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

We do persist this to disk (in case the server is restarted), but I do not think we should care about old configurations or version control them even though what is affected is that all previously sent emails with a different base-url (mollymawk_domain) will lead to dead ends potentially. But I wonder if we should work on getting mollymawk to be able to handle all the different base-urls. Maybe we can setup a trigger, whenever the base-url is changed, an email is sent to all users informing them of this change, and what to do about previously sent emails.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just to be sure, there are already running mollymawk instance(s) which have some data persisted to disk. Now you revise the data format, so what will happen with these old data on disk? Will mollymawk fail to start? Will it discard the configuration?

@PizieDust PizieDust Jan 23, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Our live mollymawk instance was not update with email configuration yet, so we personally will not face this issue but if there is any live instance of mollymawk which was updated then what happens is mollymawk will discard the change, and the user will have to enter the email configuration again for emails to work, but mollymawk will start, just that email configs will be null

@hannesm

hannesm commented Jan 20, 2026

Copy link
Copy Markdown
Contributor

Looks good, thanks!

@hannesm

hannesm commented Jan 22, 2026

Copy link
Copy Markdown
Contributor

I'm not sure what to do here. So, this PR is against another branch - shouldn't this be against the main branch?

@PizieDust
PizieDust changed the base branch from email_notifs to main January 23, 2026 05:38
@PizieDust

Copy link
Copy Markdown
Collaborator Author

I'm not sure what to do here. So, this PR is against another branch - shouldn't this be against the main branch?

I rebased onto main, and cherrypicked the commits from the other branch that were needed for this. So I think this is fine now.

@hannesm
hannesm merged commit 7dbba0c into main Jan 25, 2026
2 checks passed
@hannesm
hannesm deleted the update_u branch January 25, 2026 19:25
@hannesm

hannesm commented Jan 25, 2026

Copy link
Copy Markdown
Contributor

thanks.

PizieDust added a commit that referenced this pull request Feb 3, 2026
* update email template

* use system email as from email

* store domain used by mollymawk

* template email for update emails notification

* better failed email messages

* check email updates and send emails

* add mollymawks domain to links

* have a scheduler for background checks within mollymawk

* remove back ground update endpoint

* add lwt.pause

* change fields to from for sender_email and base_url for mollymawk domain

* formatted code

* rename to from and base_url

* use duration.of_f

* safe to wait for an hour rather than 60 seconds which could lead to spamming users

* fix minor bug

---------

Co-authored-by: Automated ocamlformat GitHub action, developed by robur.coop <autoformat@robur.coop>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants