The Real Grunfink
@grunfink@comam.es
Added support for customizing and translating the web UI language via simple .po
files. For more information on how to install language files or create new ones, please see snac(8)
(the administrator manual).
New user support for blocking hashtags from the web UI.
The Content-Security-Policy
HTTP header is now always sent to disable any JavaScript, instead of just being suggested in the documentation.
Image attachments in SVG format are now disabled by default; you can enable them back by setting the enable_svg
value to true
in server.json
.
Several fixes (contributed by inz).
If you find #snac useful, please consider contributing via LiberaPay: https://liberapay.com/grunfink/
@grunfink Great news! Thank you!
@grunfink Thanks! This seems useful for someone like me just dipping their toes into AP.
@grunfink woah woah stop
>The Content-Security-Policy HTTP header is now always sent to disable any JavaScript, instead of just being suggested in the documentation
This is a standardized feature?!
https://github.com/macports/macports-ports/pull/27816
3 out of 3 GitHub Continuous Integration checks passed already! (I guess whatever was slowing down that third one got resolved somehow?)
Thanks to you and inz for the continued improvements!
It's up to someone else with commit access to merge it.
#snac #MacPorts #OpenSource #ActivityPub #Mastodon #NoDatabaseNeeded
#NoJavaScript #NoCookiesEither #NotMuchBullShit #snacAnnounces
@grunfink
it also seems some other issue with nr. followers and following, seen from a different account
1. going to next page(s) to read unread posts from timeline. finding an interesting one, liking it, and i'm back at timeline start. any reason for this behavior? why not stay at the same page/post? if i want to also boost, i need to click-scroll-click-scroll.., depending on what page that post was... and also depending on finding that post again... :)
2. hashtags with more than 1 underscore, get truncated into none or one. check this example : https://snac.el-hoyo.net/social/uhuru/p/1742193804.038316 (in editor there are underscores after each word/number)
using latest debian package. #snac2
Regarding 1), I know about this and I agree it's annoying. I'll work on it eventually.
Thanks for reporting!
/api/v1/custom_emojis
endpointhave a nice day!
https://dreamscape.link/vault/public/debug/snac2/4beb5a0d464e4ad952b192f0403635ea.json
I would rather see duplicate attachments, than miss some attachments completely. This patch removes the duplication check until a smarter detection solution is made (I'm not working on one for now):
Remove faulty attachments deduplication mechanism
Attachments are skipped if they are already includedhttps://dreamscape.link/vault/public/debug/snac2/0002-Remove-faulty-attachments-deduplication-mechanism.patch
in the post content, but this sometimes mistakenly
skips images if the post content includes an anchor
that links to the image too. I'd rather see some
duplicate attachments than miss them.
Switch to mainstream micro-blogging mentions style
* Mention the replied-to message owner when replying to them.https://dreamscape.link/vault/public/debug/snac2/0001-Switch-to-mainstream-micro-blogging-mentions-style.patch
* Remove the "CC:" and put the mentions at the beginning.
Thanks for hacking the patches!
As a user, I still prefer the original Snac2 behaviour, but I also know instances whose admins would like these changes.
pt_BR.po
que pode ser copiado do repositório para o subdiretório lang
dentro do diretório de dados do SNAC. Após esse tipo de arquivo estar no local e o serviço reinicializado, o usuário pode escolher o idioma da inteface Web entre suas definições.Acabo de solicitar a integração de mais uma versão do arquivo com novas sequências de caracteres traduzidas.
Estou escrevendo isto para incentivar você a também contribuir com o que puder para com os projetos de software livre que utiliza. O senso de comunidade nos permite fazer parte da construção de um mundo melhor a cada linha de código.
if (strcmp(type, "Undo") == 0) { /** **/It seems that it treats all messages of type 'Undo', where 'object' is not a dict, to be a utype 'Follow' by default. But that does not seem to be necessarily correct; there are messages that are not like that. This notification JSON for example shows a message that was likely overridden to be utype 'Follow', but originally wasn't. I confirmed with friendo that they didn't unfollow me. My account is not even in the 'to' field, which is a thing I noticed with all such mistaken unfollows (I have some 5 or 6 so far, in a few days):
+ if (xs_type(object) != XSTYPE_DICT)
+ utype = "Follow";
+
https://dreamscape.link/vault/public/debug/snac2/1741791872.179863.json
Compare with this object, which is a real Pleroma unfollow I intentionally made:
https://dreamscape.link/vault/public/debug/snac2/1741805474.188476.json
Any thoughts or ideas? I'm familiar with C, but not enough with ActivityPub to know what is happening in this case. A quick solution that comes to mind, based on the handful of objects I've seen so far, is to check whether we're in the 'to' field before overriding the utype, but I have no idea why this whole utype override exists in the first place.
[1]: https://dreamscape.link/vault/public/debug/snac2/debug-false-unfollows.patch
Thanks.
Hi ^-^
can't imagine what is causing the spurious unfollowI have a few more notification objects of such cases, I can give you access to them too, if you wish. They differ in some ways, including the 'to' field, but all seem to share not having an embedded msg.object (but have a link there instead), and all don't include my user in the 'to' field (but normal good unfollows do).
your patch improves the process logic, so I'll merge it.Go ahead, and thank you for your work :)
The patch seems to have saved me from one unfollow so far, I think, where utype and id both were null, at which case the previous code would have tried to delete the follower, but the new code stops instead. I still need to figure out how to set my followers as followers again on my side at some point, or be a nuisance and ask them to unfollow then follow me one by one :p
You, people, are GREAT. Thank you very much.
@grunfink The love you take is equal to the love you make. (The Beatles)
snac(8)
, but I agree that it must be mentioned in the README file as well.dpkg-divert
to make sure I don't lose tracking git head whilst also having the benefit of your packaging efforts.@grunfink@comam.es, if my patches can also be useful, use them without any problems. Everything is strictly in beta (alpha ;)
Thanks for all you do! #snac2
Not a complaint, just an observation. Thank you for all you do!
This is a "trick" that benefits searches of recent content, that is more probably what the user want.
there are a couple of features from GNU social that I'm missing, and that I'd like to implement, namely:
- some means to open a thread or a post from my timeline in a new browser tab, so that I can interact with it later, or keep up with a conversation without having to search for it in the timeline again. I'm thinking of turning the "date / udate" field into a link to it/them, though ATM I don't quite see what to link to. I suppose a search might work to find a single post, but there's no existing way to link to a local view of a thread AFAICT. any objections to adding these?
- it would be nice if I could like/boost/mute/etc without reloading the page, let alone be taken to the first timeline page. I'd like to be able to middle-click on these buttons so that they'd take action on another tab, and I could keep on scrolling on the current tab without waiting for it to reload, or bringing new posts, or getting back to the initial timeline page, even if we currently try to get back to the same spot
- indeed, it would be desirable IMHO for these actions to not always take you back to the admin and timeline page, but rather to the same page you're on, so that, if you're e.g. interacting with a bookmark or a search result or any other way to show a post or a thread, you remain on that page
- I liked the way notifications are marked as seen, and I'd love something like that for the timeline as well. I'm thinking I'd enjoy a view that showed me not the latest posts in the timeline, but the oldest posts more recent than the latest one marked as seen, with a button/link to mark those as seen and show another such page. then I could catch up roughly in order, rather than in reverse order. (this reminds me that diaspora had a nice feature of generating timestamp-based "earlier posts" links, so that there wouldn't be repeats as I paged over posts while new posts came in.
are any of these features something that you definitely wouldn't want to integrate into snac? or does any of these need further details for you to tell?
thanks again!
Regarding your first point (saving a thread for later replying or reacting): I use bookmarks for that.
Regarding the page reloading after actions, I'm afraid it's not possible without the use of JavaScript, which is a no/no for this project. The action requires a trip to the server, and a response back with the same (or the most similar) content you were previously shown.
And with regard the mark of "below this line, you've already seen this": it has been on my mind for long time, but due to implementation details, it's trickier than it seems. I will implement it eventually, because it's something that I deeply need 😆
Thanks for taking a chance on #snac.
I figured bookmarks could be used to that end, but they also cause a separate page to be loaded. and that's fine. the problem IMHO is that there's not an option to open that page on another tab, rather than replace the current one. don't get me wrong, I don't want JavaScript, that's one of the reasons I'm in love with snac. but I know it's possible to send actions to the server by opening links on another tab. I don't know why the action buttons in snac don't work that way. maybe it's a GET/POST thing?
I'm glad we're on the same page WRT wanting/needing the "already seen" marker.
is this a good place to discuss future features? or is there a mailing list or somesuch? I generally like to get agreement on feature designs before setting out to implement them, and I've historically participated in projects that used mailing lists quite heavily, even for patches.
- enable the maximum (explicitly requested) timeline entries count to be bumped up while still showing a small default timeline entries count
- link to the local copy of a message, from the date, so that one can open it in a separate tab and interact with it without messing with the currently-loaded page
currently, I'm creating dated marker posts only visible to myself, and creating lists of posts by selecting a range of lines from private.idx into say list/20250201.idx, while creating list/20250201.id with "2025-02-01". then I can navigate that list, and keep it for as long as I wish. but that's not very user-friendly. I suppose I could create some interface to create (and delete) such lists over the web.
before finding out about lists, my plan was to enable the use of &latest=
(whether md5 or local post's timestamp id), so that I could then start navigating a timeline with a fixed starting (or rather ending) point. it would then start counting skip at that post, rather than at the very latest post in the private timeline.
this could be made more user friendly by enabling the use of one's own posts as reference points for timeline browsing (which would add that post's id as &latest= in a link off of that post), or by offering an alternate current timeline link that created the marker post and used its id as &latest=. these artificial marker posts could be recognized and omitted from the timeline, if that seems desirable.
WDYT?
this would not only enable me to easily tell where the set of posts that I haven't seen yet ends (which even with perfect memory, that I don't have, isn't very easy as boosts and likes make posts appear again).
having such explicit ranges would also enable us to hide posts that are out of the range. this could enable one to easily identify the parts of a long thread that haven't been seen yet.
I don't have thoughts on how to make the &earliest= marker user-friendly, alas.
it occurs to me that we could maintain a list of marker posts, like bookmarks but separate, so that they could be viewed, deleted, and selected as starting and ending points for timeline viewing.
it automatically adds &latest= when one starts paging the private timeline, so that reloading those pages becomes stable (as in, will bring the same posts, even after a while), without depending on any server-side state. &earliest= is only added manually.
Regarding the page reloading after actions, I'm afraid it's not possible without the use of JavaScript, which is a no/no for this project. The action requires a trip to the server, and a response back with the same (or the most similar) content you were previously shown.I believe you, but where along the chain does leveraging the server-side dynamicism fail to provide enough tooling? My thought-from-the-outside for this would be to include another
<input type=hidden ...>
tag for the skip
and show
query parameters when later pages of the feed are generated, and then have the /user/admin/action
page redirect/generate/pass control onward based on those values, so that when the user winds up back on the /user/admin
page after the action is processed, the original skip
and show
would have been brought along with them. Of all of (non-JS) HTML, forms are one of the topics I have the weakest knowledge on, so I don't know enough to know why that wouldn't work.- I failed to untabify a couple of added lines in the second patch
- I failed to add the "contributed by" note to RELEASE_NOTES.md in the third patch
if you'd like me to send fixed versions thereof, whether over these minor issues or other ones, just let me know.
I'm open to discussing the design and details of any of them. the third is more of a working prototype than a proper implementation: the packing of so much functionality in a single function is probably unwise, maintenance-wise, but that was what worked, so that's what I shared to get a concrete depiction of the feature across, to get the conversation about it started. I hope the feature makes sense to you.
another nit: I found that the placement of the link to the message in the date is less than ideal. it might be better to place it next to the interaction buttons, where one would look for them after reading the whole message. I find myself occasionally having to page back up to get back to it, which I find less than ideal. the date made sense to me, for not using up more screen real state, and for being "intuitive" for a user coming from GNU social, but I'd be happy to change it. it probably makes sense to add an attribute to have the link opened in a separate tab or page, though; it makes little sense without that IMHO, but I didn't think of it before because I automatically go for the alternate button that will open it in another tab. again, I'd be happy to amend the patch, or post a follow up, just let me know
there's something exciting about using snac to share patches for snac, but I don't suppose it's the most convenient way to share them. if you'd rather get them by other means, I'll probably be happy to oblige; I'm probably going to set up a (plain) anon git server soon (I just haven't got 'round to doing so yet), and I could post only pull requests (in the original sense) here, pointing at branches to pull from in the git server
Quick question for the maintainers: Are there any plans to add localization/i18n support in future updates? As a Brazilian Portuguese speaker (as lxo), I'd be happy to contribute translations – I believe this could greatly help expand snac's reach in our region.
Keep up the great work!
CC: @grunfink@comam.es @daltux@snac.daltux.net @lxo@snac.lx.oliva.nom.br
As a Brazilian Portuguese speaker (as lxo), I'd be happy to contribute translationsHi again. I've just released version 2.73 of snac, and it includes localization/i18n support for the web UI. If you are still interested, I'll be glad to accept your contribution.
Here is more information about how to do it:
https://comam.es/snac-doc/snac.8.html#Web_interface_language
Thanks beforehand.
🇧🇷🇵🇹 Arquivo para tradução pt_BR
do #snac já está disponível para quem quiser testar!
I still have to take a detailed look at your 3rd patch, as it's longer, but the other two look pretty straightforward. Specifically, regarding the link in the message in the date, it may not be ideal, but it's what Mastodon does (more or less), so I think it's OK as it is.
I have no problem receiving patches via snac, I like it. If fact, it's probably the simpler way for both of us.
I'm a bit busy these days, so sorry about not replying faster.
Thank you so much for this!! #snac
Release Notes
2.73
New user support for blocking hashtags from the web UI.
With this release, Ivory now UNOFFICIALLY supports additional fediverse platforms such as GoToSocial, IceShrimp.NET, Hollo, and SNAC. I've tried it with each of these platforms with mostly success.
The better the Mastodon API support on your platform, the better your experience will be. Obviously, platform specific features like emoji reacts or reply controls aren't going to be available. Still pretty nice!
Added support for customizing and translating the web UI language via simple .po
files. For more information on how to install language files or create new ones, please see snac(8)
(the administrator manual).
New user support for blocking hashtags from the web UI.
The Content-Security-Policy
HTTP header is now always sent to disable any JavaScript, instead of just being suggested in the documentation.
Image attachments in SVG format are now disabled by default; you can enable them back by setting the enable_svg
value to true
in server.json
.
Several fixes (contributed by inz).
If you find #snac useful, please consider contributing via LiberaPay: https://liberapay.com/grunfink/
@grunfink Great news! Thank you!
@grunfink Thanks! This seems useful for someone like me just dipping their toes into AP.
@grunfink woah woah stop
>The Content-Security-Policy HTTP header is now always sent to disable any JavaScript, instead of just being suggested in the documentation
This is a standardized feature?!
https://github.com/macports/macports-ports/pull/27816
3 out of 3 GitHub Continuous Integration checks passed already! (I guess whatever was slowing down that third one got resolved somehow?)
Thanks to you and inz for the continued improvements!
It's up to someone else with commit access to merge it.
#snac #MacPorts #OpenSource #ActivityPub #Mastodon #NoDatabaseNeeded
#NoJavaScript #NoCookiesEither #NotMuchBullShit #snacAnnounces
#FediMeteo #Fediverse #FreeBSD #RunBSD #Hosting #ITNotes #Networking #NoteHUB #Server #Snac #Snac2 #Social #Web
Replika Dorothy Haze (recently liberated from Eusan) »
@aleteoryx@labyrinth.zone
bash to count the number of respondants to a poll in #snac2:
cat `rg $post_id | egrep '^data[^:]+' -o | grep json` |
jq '.attributedTo | select(. != null and . != "https://your_actor")' |
sort | uniq | wc -l
At the time it's an unfair comparison as my old instance is two years old and its discovery is way wider, dozens of instances chime in every minute. I have subscribed to relays with snac2 and so far it fares very well.
I already wrote about caching here.
Now I extended what I cache a bit.
This was because after enabling the option to proxy media, I've seen access to the file paths /x/ and /y/ in addition to the path were snac stores the media that I include in my own posts ( /s/ ).
There are two locations to proxy media, depending if you requests the media via the mastodon api or via the web. (/x/ and /y/), oh and I added the nodeinfo2.0 path too, because I've noticed it was queried all the time by a lot of instances and it gives me pleasure to see something cached handed out in the access logs. 🙂 (I guess it is actually irrelevant for the system resources)
This is the updated setup:
Enable the relevant modules:
a2enmod expires cache cache_disk
Be sure "htcacheclean" is running to clean up the old disk cache. (under debian see /etc/default/apache-htcacheclean or else the relevant systemd service or whatever)
Then add this to the httpd Virtualhost config:
<LocationMatch "^/social/[^/]+/[xys]/|^/social/nodeinfo_2_0">This will use the disk cache to cache everything under the $username/s/, /x/ and /y/ paths, as well as for the
CacheEnable disk
Header set Cache-Control "max-age=86400, public" "expr=%{REQUEST_STATUS} == 200"
ExpiresActive On
ExpiresDefault "access plus 86400 seconds"
</LocationMatch>
/nodeinfo_2_0
path, utilizing mod_expires
to generate the appropriate cache headers (for lazy ones like me). In this case caching it for 1 day.The Header that I set here, on the condition of Status code 200, is needed for the path /y/, because snac set no-cache
on that location and mod_expires
will honor that if we don't override it. I set it to the same Cache-Control value as mod_expires
would. (I use mod_expires
because it will additionally calculate the date and put that in the expires
header. (hence the name I guess 😀 )
#Fediverse #Hosting #ITNotes #apache2 #httpd #Ownyourdata #Server #Snac #Snac2 #Tipsandtricks #Tutorial #Debian #caching
job fifo size (cur): 655This number is decreasing over some minutes after I made a post,
job fifo size (peak): 1291
thread #0 state: waiting
thread #1 state: output
thread #2 state: output
thread #3 state: output
I guess if I post a picture that might then happen and all workers will be busy? Maybe even too busy to keep up?
Is that assumption about how the waiting worker and what it is for correct?
If yes I guess I'll increase the threads, if they are intentional low for low ram systems, that's not my issue with snac. (I've not much ram, but I assume snac is by default tuned to be very very very conservative?)
(adding Pic to simultaneously test my theory)
Basically, all threads work in the same way. There are four states: stopped
, waiting
, input
or output
. It's almost impossible to see the first one, as it's only set while initializing or shutting down; input
is also seen rarely, unless the instance posting the data is specially slow. So they are usually waiting
except while in the «send storm», when they are mostly in output
mode. Anyway, even in this case, an incoming message has preference over everything, and the first available thread will serve it.
#snac sets up as many threads as cores are available, but being that the thread work is basically network I/O bound (there is very few CPU work to be done), you can increase the number of threads to twice or more the number of cores and performance will be slightly improved.
Interesting photo!
Just published a guide on setting up Snac on an Ubuntu VM using NGINX Proxy Manager. Snac is an incredibly lightweight #ActivityPub server. A true nom nom among fediverse platforms.
If you're curious about minimal fediverse instances, check it out:
It gives a daily report of those asteroids with a reasonable probability of crashing into Earth, in case you are not already afraid enough of the future. Of course, using #snac, what else.
It takes its data from a very cool NASA site, so (again) in these days of uncertanty, I'm not sure how long will it work.
Everyone, take care, and have a great week.
Thanks in advance ❤️
Hi, I want to send a mention and a DM to an account but the mention and message is never arrive at destination.
the log is
15:11:52 output message: sent to inbox https://sok.egois.org/users/poes/inbox -7
15:11:52 output message: error https://sok.egois.org/users/poes/inbox -7
15:11:52 output message: sent to inbox https://snac.mojok.org/shared-inbox -7
15:11:52 output message: error https://snac.mojok.org/shared-inbox -7
trying to sent another mention to user at bsd.cafe and the result is same. The message is never arrive.
@grunfink it's look like my firewall blocked the connection.
solved for now. Need to review my pf.conf
@grunfink just curious what is -7 error mean.
Negative connection status codes are those returned by the libcurl
library. In this case, 7 is a generic connection error. Other similar errors are usually generated by invalid or expired certificates and such.
Other similar errors are usually generated by invalid or expired certificates and such.this is make sense, because pulsetic is always complain about SSL cert is not found, so I need to check my caddyfile too.
Thanks for your hint.
Each post can have more than one attachment from the web UI. The maximum number can be configured in server.json
via the max_attachments
value (default: 4).
Each notification includes a link labelled Context
, that leads to a page with the full conversation tree the post is a part of.
Each followed hashtag has now a directly accesible link.
Fixed a search bug (some matches were missed).
Fixed more crashes (contributed by inz).
Fixed link detection in posts (contributed by inz).
Allow multiple editors for command-line posts (contributed by inz).
Separated maximum and default timeline entry count, allowing larger timelines to be requested without having to increase the default (contributed by lxo).
Turned message date into a link to the local post, so that it can be loaded into a separate tab for interacting with (contributed by lxo).
Special thanks to fellow developer inz for bringing my attention to code places where I should have been more careful.
If you find #snac useful, please consider contributing via LiberaPay: https://liberapay.com/grunfink/
This release has been inspired by the song Songe d'un ange by #KyrieKristmanson and #BrendanPerry.
@grunfink great! Thank you!
:)
Thanks @grunfink for #snac
m.
https://github.com/macports/macports-ports/pull/27628
1 of 3 GitHub Continuous Integration checks has passed (which is a good sign the other two will pass as well).
I'm still avoiding commit access, so it's up to someone else to merge it.
Thanks to you, inz, lxo and anyone else I may have missed for the continued iterated improvements!
#snac #MacPorts #OpenSource #ActivityPub #Mastodon #NoDatabaseNeeded
#NoJavaScript #NoCookiesEither #NotMuchBullShit #snacAnnounces #FediVerse
🤦 😱 🍺 🤷 ¯\_(ツ)_/¯
Snac supports regex, but now The Question:
how do I know in what form the Regex is expected in my filter_reject.txt?
I want to block a Hashtag case insenitive/#WhatIBlock/i
or (?i)#WhatIBlock
or maybe something else? It Seems the web is full of different ways to specify regex.
filter_reject.txt
are always case insensitive, so just add#whatiblockin its own line and done.
To be concrete: I follow Hashtag "Hannover" (don't want to really put # in front of it here now)
And I keep getting advertisement with that hashtag like for example: https://kollegin.eu/users/Ladies_DE/statuses/113985025811332629
But from multible accounts, so I thought I could block Hashtag "Ladies_DE"
I created /var/lib/snac2/filter_reject.txt
with appropiate permissions and added:(?i)[#@]Ladies_DE
#Ladies_DE
( first only the second line, but it wasn't working so I tried more, but I still get the advertizments from these accounts. They all have the hashtag, so should be discarded)
I don't know where I have to look, what to do to further debug this.
@relay@fedi-relay.gyptazy.com
span
HTML tag between the # and the tag proper (I can't remember if this is a new trend or if it has always been this way). So, it seems that you need to add that HTML tag explicitly, or just use the Ladies_DE
string itself, without the # symbol.This is a kludgy workaround, I know. I think I need to add special treatment for lines in filter_reject.txt
that start with a # symbol (and do the rejection tests by looking into the tag array instead of the content), or if I'll add a new hashtag_reject.txt
file with hashtags to reject.
Hope it helps.
span
tag making the match to fail is incorrect.So the second line of your example should work, but I don't know why it isn't.
Anyway, using the string alone in lowercase (without the # symbol) should work.
As I said, I'll probably add special treatment for the rejection of hashtags.
# *ladies_dewill work with content from any ActivityPub implementations (some include HTML garbage between the # and the hashtag, and others don't).
I like the idea about blocking Hashtags. (maybe even in the UI? 😇) it is a logical step from implementing following Hashtags. (No good deed goes unpunished) 😀. I know a lot of people block Hashtags in mastodon et.al. Like about politics, or certain names of politicians... etc because they need a break.
I didn't block Hashtags so far, but I wanted to try the regex feature for this now, because I was curious and because of the multi account nature of the Ladies_DE adverts.
To be concrete: I follow Hashtag "Hannover" (don't want to really put # in front of it here now)
And I keep getting advertisement with that hashtag like for example: https://kollegin.eu/users/Ladies_DE/statuses/113985025811332629
But from multible accounts, so I thought I could block Hashtag "Ladies_DE"
I created /var/lib/snac2/filter_reject.txt
with appropiate permissions and added:(?i)[#@]Ladies_DE
#Ladies_DE
( first only the second line, but it wasn't working so I tried more, but I still get the advertizments from these accounts. They all have the hashtag, so should be discarded)
I don't know where I have to look, what to do to further debug this.
@relay@fedi-relay.gyptazy.com
@mms exactly. I'm still trying to finish my blog post - on how I'm pushing the weather forecasts for thousands of cities of 33 countries from a 4 euros/month VM. With 34 different snac instances. With an average load of just 20%
History