feat: WebDAV asset upload to public_dir#257
Conversation
The handler will only be added if the cfg=webav is set. This uses a conditional compilation function as cfg expressions are experimental. When feature=webdav is enabled and there is a public dir, the new /_/dav routes will be added. It requires configuration of a Bearer token to authorize the request. It will refuse to upload assets if it's not configured
4b5dcb8 to
1ca09de
Compare
|
Feel free to close it as not intended addition to the codebase. Integrating directly on the I'd understanding not wanting to add such feature to |
|
Let me start with a bit of a disclaimer:
Ok, with my confusion out of the way, what's the ultimate goal here? E.g. I'm wondering what's the benefit of rcloning assets over WebDAV rather than some other protocol? Just curios.
That could be cool. Happy to push changes to make components generally more useful. I would have zero concerns adding a WebDAV component if we can make it work. If you have a list of issues, I can try to pay them down.
There isn't really a way to write the config. Heck there isn't even a way to read the config. We should certainly add the latter (currently we use a hack for auth-ui). I'd be a bit more careful on the former. In principle we should allow components to have their own isolated configs somewhere. Would that be enough to read the webdav token from? |
Yeah, I know this might be a niche scenario, and I'd also prefer to extend using WASM to not clobber the core design with this extension. My idea was to have a Trailbase backend hosted on my container orchestrator accepting new front-end deployments, without requiring container restarts or new base image deployments. Something like old-school PHP shared host, where someone can drag frontend files using CyberDuck. I know a more typical deployment scenario would have a JS Fronted repo building a base image baked with the compiled assets, trigger CI, upload the image, and trigger a new deploy version. But this project I'm working on with someone that might be able to edit the JS/HTML/CSS themselves, but might not be very versed with the Git commit/CI/wait-a-while/redeploy flow. So the idea of the workflow is:
As this project uses Sqlite, it's not very happy to run on a NFS mount. So I'm using a block storage with exclusive access to the "pod" deployment. There are several other ways I could achieve this flow tho:
None of the options are terrible by themselves, or not viable to be done, but I thought it would be nice to have a single process that serves public assets and accept updates. It would look a lot similar to an old-school XAMPP server and more similar to anyone used to customize their MySpace profile.
I much rather extend it with WASM, as I mentioned before, and I've started tackling it this way also, but then it started to become a bigger changeset, which requires some additional alignment on how to approach:
I think this extension would stress some of the current design strategies of the WASM extension, but I'm not sure if it's good stress or bad stress hahaha
Yup, it would work fine as isolated config, as long as there is a method to integrate with the Admin UI. I'd rather have a way to expose the configs to the UI editor, otherwise I guess each WASM extension would also need to bundle their own frontend bundling and it can get inconsistent It would also be fine to have the filesystem read/write isolated to the WASM process, as long as the main process can also read the |
|
Thanks a ton for the thoughtful reply, sharing the overall intent and the issues you ran into with the WASM approach. And sorry for the latent reply. You got me at CyberDuck, which I haven't used for 20 years but is absolutely a blast from the past :). Nostalgia aside, my biggest (and arguably wishful) concern is complicating a distributed deploy going forward. I'll also only play devils advocate once: if you have a partner who's not comfortable with git, maybe having a CI/CD-verification step is an especially good idea, since uploading assets straight to prod does introduce an additional failure mode. That said, ultimately you need to do what works for you :yolo:. As for your other options, you may already run an nginx/caddy for TLS termination, so letting it serve your assets probably wouldn't add much complexity 🤷♀️ Now, back to your original proposal. Personally, I'd still favor a WASM component approach. Looking at your list of per-requisites:
We should allow wildcard matches anyway (if we don't already do).
There might be some nuance, naively this looks like the previous point. I would expect the
Would this even be needed, feels more like a nice to have? Naively you'd configure your access once and never change again? That said, we're discussing the ability to add admin sub-pages via WASM components on a parallel thread: feel free to chime in (#252). The WASM Host limits the filesystem access to Read-Only (if I understood it correctly)
Good point. I'd be very happy to extend it to include write access. Read or write, longer term we should have system to grant capabilities to WASM components (similar to mobile apps), since both are priviledged operations which may be sensitive for 3rd party components. At the moment we're really only concerned with 1st and 2nd party components, where both read and write are less of a concern.
It's much appreciated 🙏 - this is exactly what is needed to make the component system more useful. |
|
Thank you for considering this approach, anyway. I understand the concerns of extending the core crate. I'm glad we had the chance to discuss it anyway. I'll close this PR and explore further what is needed from the WASM extension method instead, if that is ok.
Yeah, from a reliability perspective a CI pipeline would be better. I was leaning towards autonomy of editing on this project tho, closer to what MySpace used to offer on this project than correctness and safety. I want to foster a WYSIWYG dev flow instead of production reliability industry I'd apply on other scenarios 😄
Yup, I could design it different ways. But the all-in-one single-binary looked as the nicest option IMO
Yeah, setting it up once on deployment would be fine also. I've looked over the settings method as a more general integration imagining others could want to enable it temporarily without restarting the service. It's a bit unclear to me how the WASM plugin can read config options at this moment also, even if it's env environments/cli args.
Maybe in the manifest of the WASM (being discussed on the other issue) it could declare permissions, and these are reviewed on |
|
Don't get me wrong, I wasn't trying to tell you how to set up your environment.
This conversation has carried into #252. Independent of FS access, settings could be handled separately. For example, if you look at mobile development you can read/write settings through a persistent KV store (e.g. shared preferences) w/o FS access. FS access whether it's read or write is strictly more priviledged. I think it would make sense for me as one of the next steps to add a per-component persistent KV store - appreciated
Yeah, that's pretty much what would be needed (longer term) - appreciated |
|
It's all good 😄 I fully understand the maintainer-side concerns on adopting such deployment model. I'm not taking it personally. I'll watch over the discussion on the other issue, and see what I can get along the way on the WASM refactoring. Is it ok to open draft PRs for WASM changes as discussion points, even if they don't land? |
Absolutely. That said, it may save some time and/or tokens if we first have a quick chat on more major things. Also always happy to help, get my hands dirty and do upfront work. |
This PR introduces an (experimental) WebDAV asset uploading to
public_dir.This make it much easier to keep the service running and upload just HTML, CSS
and Javascript assets using something like
rcloneorCyberduck.I've tried to use the WASM guest API to implement it, but WebDAV has multiple
additional HTTP Methods. Changing the WASM API to support all of them (or ANY
matcher) seemed more intrictate.
The WASM guest API also seems limited to change the
Configof the service (orI didn't fully understand the scope of KV functions). So instead I've
implemented it directly on the service core with conditional
feature = webdavto allow opt-out.
For now this is covered:
Bearer $tokenauthentication to upload assetsI'm not so familiar on how to write end-to-end tests in the project, and I'll
spend more time over the week trying to udnerstand it. Meanwhile, it can be tested locally using
rclone:Closes #255
PS: the large diff seems to be caused by a more recentDoneprotocupdating many.tslines. I'll figure out if I can downgrade my version to reduce the noise