Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Plugin system #3575

Open
WesleyAC opened this issue Nov 26, 2024 · 8 comments
Open

[feature] Plugin system #3575

WesleyAC opened this issue Nov 26, 2024 · 8 comments
Labels
enhancement New feature or request

Comments

@WesleyAC
Copy link

WesleyAC commented Nov 26, 2024

Is your feature request related to a problem ?

It's come up several times that a plugin system might be useful for various features that shouldn't be in the core code but people still want. In general, it's difficult for people to compile and maintain their own patches to GtS, and a stable plugin API solves that by allowing people to modify the functionality of their servers in a shareable way with a minimal amount of work.

Describe the solution you'd like.

I don't have a specific solution I'd like to propose, I'm just making this issue to capture thoughts about the problem space and possible solutions.

WASM has come up in previous discussions about this, and could potentially be a good solution, but it should be considered in the context of other options. Notably, I believe GtS already comes with a WASM runtime for sandboxing risky C libraries like ffmpeg.

Describe alternatives you've considered.

This issue exists to discuss alternatives.

Additional context.

Related issues:

I would love to hear in this issue:

  • What would users and server operators like plugins for?
  • What APIs would plugin authors like to have available?
  • What languages do people want to write plugins in?
  • What advice do people who have designed or used plugin systems for other software have about designing something like this?
@WesleyAC WesleyAC added the enhancement New feature or request label Nov 26, 2024
@WesleyAC
Copy link
Author

WesleyAC commented Nov 26, 2024

Here are some plugins I think it would be cool to see:

  • Things for filtering incoming posts, antispam, moderation, etc
  • Experiments in different ways of federating blocklists
  • Different sorting mechanisms for the timeline
  • Adding support for experimental activitypub extensions
    • *key/*oma-style emoji reactions
    • E2E encrypted DMs
  • Native support for Bookwyrm's review activity types
  • Goofy oulipo.social / dolphin.town style nonsense. hellsite.site had some of this at some point and it was fun

For writing plugins, I would be happiest in Rust or Python, with TypeScript/Javascript or Lua also being perfectly acceptable to me. From what I understand it is doable to write WASM modules in all of those languages.

@WesleyAC
Copy link
Author

Another thing that I've wanted to implement before are "dynamic blocklists" of some sort (blocking all open-registration server, blocking all servers with more than a certain number of users, etc). That seems like a ideal job for a plugin.

@tsmethurst
Copy link
Contributor

This is something @NyaaaWhatsUpDoc has been thinking about lately as well :) Though I can't remember where her thinking was going re: structure and language.

@technomancy
Copy link
Contributor

I have a plugin system implemented at https://github.com/technomancy/gotosocial/tree/plugin from quite some time ago. Here's an example of what a plugin looks like in my version: https://github.com/superseriousbusiness/gotosocial/blob/a34888664dc7e796cfdcfdbb5482a8e2d03971ef/plugins/autocw.lua

I haven't worked on it much because I don't think it's possible to maintain a stable API in a 3rd-party fork; it would need to be merged to mainline GTS for it to be viable, and Tobi and crew would have to commit to maintaining a stable API; it felt like a lot to ask the team to commit to such a thing.

However, if there is appetite from the maintainers to commit to a stable plugin API, I would be happy to put together a more detailed design document and proposal. I have been reading some research on what automated moderation tooling might look like: https://letterbook.com/blog/post/2024/11/18/moderation-tooling-research.html and I think it might even be possible to design a plugin API that hides the differences between GTS and other servers in such a way that you could even write plugins that could be shared with other servers.

@WesleyAC
Copy link
Author

WesleyAC commented Dec 1, 2024

@technomancy very neat!

I think in terms of maintenance burden, it'd be worth putting some effort into thinking about how to structure the APIs to be the least susceptible to churn/breakage upon refactoring in the GTS codebase. Focusing on having things be generic and well-defined enough that plugins could be compatible with different fediverse servers seems like a reasonable goal there. Some thought should be put into versioning of the GTS/plugin interface API.

I spent a little time looking at WASM/WASI, Lua, etc. Here are the options as I see them:

  • WASM + WASI
    • Pros:
      • We already ship a WASM runtime in all supported builds
      • Plugins can be written in many different languages
      • Very performant
      • Good security properties (memory safe, capabilities, etc)
    • Cons:
      • Some languages are kind of a pain to bundle into WASM files, potentially large binaries
      • WASM files are not easily inspectable/editable, requires a compilation step
  • Lua
    • Pros:
      • Very easy to embed
      • Plugin files can be directly edited/inspected
    • Cons:
      • Only one language, compiling things into Lua is not something people really do
      • Requires a new dependency (Lua interpreter)
      • Given that the Lua interpreter is written in C and GTS calls all C code via WASM anyways (I think?) we would presumably be running in WASM anyways, which feels kind of goofy to me
  • Some other interpreted language (javascript, etc)
    • I haven't seriously evaluated any other interpreters, but they would all have the same upsides and downsides as Lua, with the ease of embedding probably being pretty variable.
    • Javascript would probably be more popular among plugin authors than Lua (although there are definitely advocates for both)
  • Some kind of shared library system
    • Cons:
      • Security disaster waiting to happen
      • Requires different executables for different architectures
      • Probably a pain in the ass toolchain-wise
    • Pros:
      • Not enough to outweigh the cons

From that, WASM/WASI seems like a pretty clear winner (and that's not too surprising to me, given that WASI describes itself saying "We believe that every project with a plugin model should be using WASI" — it's very much built for this usecase.

I'm curious how people involved with the project feel about that — is a WASM-based plugin system (or a plugin system more generally) something you'd be open to, given the additional maintenance overhead it would add? If so, I'd be happy to work with @technomancy & whoever else is interested on trying to specify/work on this.

@technomancy
Copy link
Contributor

Mostly agree, but I have a few corrections:

  • Only one language, compiling things into Lua is not something people really do

I work with Fennel, which one of several languages that compile to Lua. There's Moonscript/Yuescript, Urn, and Amulet off the top of my head that also target the Lua runtime; probably others too. It's an ideal compilation target in a lot of ways.

  • Given that the Lua interpreter is written in C and GTS calls all C code via WASM anyways (I think?) we would presumably be running in WASM anyways, which feels kind of goofy to me

You could maybe do it this way, but it would be better to use one of the existing pure-golang ports of the Lua VM; either gopher-lua or go-lua which don't have any FFI requirements. My proof-of-concept above uses gopher-lua, which is about 15kloc; granted this is kind of a lot, but at least it's not C code.

I think you're right than some other setup other than Lua or WASM would be a bad idea, because a plugin system would not be viable without a capabilities system, and those are the only two VMs I know which make it easy to build out capabilities systems. I've done this in several different applications in Lua, (technically Fennel, but it works the same way) and it's very easy to do in a way that's both secure and convenient.

In the end I think it comes down to:

Plugin files can be directly edited/inspected

How important is it for plugins to have a "view source" button? IMO when you're bringing in code of uncertain provenance, making it a black box is not ideal. In addition, being able to take a plugin you've installed and tweak it slightly can be very powerful; I'm thinking of the sharing and remixing features of https://scratch.mit.edu and https://tic80.com that are powered by view-source+edit.

Of course, while I think the potential for that kind of functionality is very compelling (especially when remixed plugins themselves could be published over activitypub), I don't personally have a good grasp of what the maintenance cost of bringing in a new dependency is, so I have a great view of the upsides without being able to see the downsides.

@WesleyAC
Copy link
Author

WesleyAC commented Dec 1, 2024

I work with Fennel, which one of several languages that compile to Lua. There's Moonscript/Yuescript, Urn, and Amulet off the top of my head that also target the Lua runtime; probably others too. It's an ideal compilation target in a lot of ways.

Yeah, I guess when I said "is not something people really do" I meant more that the set of languages that compile into Lua is much much less popular/well-known/widely used than the set of languages that can be compiled/bundled into WASM.

You could maybe do it this way, but it would be better to use one of the existing pure-golang ports of the Lua VM; either gopher-lua or go-lua which don't have any FFI requirements. My pro

Oh, neat! I didn't know about those, that indeed seems like it largely negates that disadvantage (at the cost of possibly having a slightly less widely compatible implementation of Lua, although from looking at the docs of gopher-lua it seems probably fine)

In the end I think it comes down to:

Plugin files can be directly edited/inspected

How important is it for plugins to have a "view source" button? IMO when you're bringing in code of uncertain provenance, making it a black box is not ideal. In addition, being able to take a plugin you've installed and tweak it slightly can be very powerful; I'm thinking of the sharing and remixing features of https://scratch.mit.edu and https://tic80.com that are powered by view-source+edit.

Yeah, I agree that this is the major thing that Lua has going for it. And I do care quite a bit about this, for instance, glit.sh is a project of mine very much in that vein.

I think for me it comes down to flexibility and ease-of-use vs inspectability and malleability. In particular, the argument that most persuades me that WASM would be a better choice goes like this:

  • The more people are able to write plugins with the skillset they already have, the better the plugin ecosystem and thus fedi ecosystem will be
  • WebAssembly has a larger set of languages that target it
  • In a WebAssembly plugin world, it could still be just as easy to write plugins in inspectable and malleable, by having a lua plugin that simply loads a lua script and translates between the WASM API and a Lua API. You could also imagine a javascript plugin, a python plugin, etc, that allow people who want to write in those languages to ship source code as the thing that users actually run. This does require trusting the author of the interpreter plugin, but I think that's a fairly acceptable tradeoff.

Obviously people need to actually go and write the lua (and javascript and python and whatever) pluins, but it strikes me that that would be fairly simple and only need to happen once, and the maintenance on those would probably be pretty minor, just tracking the upstream interpreter releases.

There are also a couple more minor but still notable advantages that WASM has:

  • Ease of distribution: a single WASM file vs potentially a directory of Lua code. This can seem like a minor thing but IMO it can be significant, especially for admins that are not versed enough in command line stuff for extracting .tar.gz files or figuring out the recursive flags to scp/rsync or whatever on the command line to be easy.
  • Library ecosystem: The ecosystem of libraries that can be used in WASM is several orders of magnitude larger than in Lua. Additionally, we don't have any good way of using libraries that use the Lua C FFI safely, whereas WASM has a great story for using C libraries.

@technomancy
Copy link
Contributor

Another angle to this is who the intended audience for writing plugins would be. For me personally, I know ten languages and have written a few compilers, but if you asked me to make some code that runs in wasm, I would have no idea where to start. The documentation I've been able to find is either too high-level to be useful, or it assumes you're already an expert. Do I need to learn Rust?

Meanwhile I've taught Lua to elementary-age children without much trouble.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants