piscsi icon indicating copy to clipboard operation
piscsi copied to clipboard

Support for action hook scripts

Open bzeiss opened this issue 3 years ago • 13 comments

Feature proposal

Describe the issue

It would be nice if rascsi supported action hook scripts that are executed when actions on images (attach, detach, eject) are executed. This is for non-Apple situations where Netatalk cannot be used (e.g. DOS/Windows boxes, samplers).

Use case:

  • samba/sftp/etc. access to rascsi
  • disk images with linux-known filesystems (like fat16) can be mounted to a shared folder that is made available via samba/sftp etc. when a drive is detached/ejected, but not when it is attached. This allows to conventiently exchange files with that disk image.
  • Thus it would be insanely convenient if it was possible to drop a shell script into a hooks folder that is executed with parameters that allows to automatically mount the disk image content to a shared folder on a detaching/ejecting action and dismount the mounted folder before an attaching action.

As far as I can think of, the following hooks would be necessary:

  • pre-action hook (dismount before attachment)
  • post-action hook (mount after detachment)
  • init hook (directly after rascsi startup before rascsi-web loads the default.json)

For the script itself, it needs to be called with parameters:

  • $image (ideally including path)
  • $action

Based on that I think all necessary decisions can be made how to handle each image.

bzeiss avatar Dec 23 '21 08:12 bzeiss

This might only work with the web UI, but not with rasctl or other clients, because they cannot automatically execute scripts before an action. Having the web UI execute a script related to a rascsi core action tends to increase the coupling between the web UI and the core, which may cause issues. On the other hand, it is possible to have the rascsi core call scripts as part of a remote operation with a system() call. When executing a remote interface operation the optional name of a script to be executed might be passed, for instance. This approach is independent of the client used.

All in all, I don't like the idea of more or less being able to execute anything, and potentially with root permissions. rascsi tends to become a security risk. If a sequence of commands shall be executed one can use a regular script for this. This script call call the required actions and can call rasctl for the rascsi-related part.

uweseimet avatar Dec 23 '21 09:12 uweseimet

True, valid points. The best core-based idea I would have to address these points would be to send events through d-bus or so for decoupling, but it still wouldn't solve the problem that waiting for the hook scripts would require waiting. It would require some kind of asynchronous confirmation mechanism before attaching which seems too odd.

At the same time, I think adding this functionality to the existing web-ui seems off as well to me. I think it's a typical backend task. Maybe the best thing would indeed be to build something like a rascsi adapter for home assistant and automate everything necessary there. I'll try taking a look at that.

I'm not sure if it makes much sense to keep this ticket open. Maybe someone comes up with a better idea.

bzeiss avatar Dec 23 '21 11:12 bzeiss

I suggest to keep it open, at least for some time. Maybe there is an alternative approach we have not yet thought about.

uweseimet avatar Dec 23 '21 11:12 uweseimet

One other idea that comes to my mind which would actually still be compatible with rascsi control as well as the web interface is a proxy on port 6868 for the rascsi management interface, i.e., it acts as the entry gate and can do all kinds of weird stuff (more things come to mind the longer I think about it like automatic backups for example) that shouldn't be done by default.

I may give this a try the next days.

bzeiss avatar Dec 23 '21 12:12 bzeiss

So as a small christmas present for myself, I have hacked together a proof of concept rascsi interface proxy that essentially is just a pass through proxy with hooks on attach/detach/eject events where currently only the necessary information for additional behavior (as described above) is shown. It depends on socket_cmd.py in src/web and I have copied stuff from all over and adapted it for my needs. It's obviously just hacked together, but I do wonder whether something like this in pretty is something that would be interesting for the general rascsi audience.

rascsi_proxy.zip

bzeiss avatar Dec 24 '21 16:12 bzeiss

I have played around with this a little more. So while still not pretty, it is in general now doing what I want it to do. A few details are missing though like better handling for the case when a device is busy during the unmount process.

rascsi_proxy_03.zip

The idea is that the automouner looks for [imagename].automount in the same path where image files is located in. Within that .automount file, there is expected to be one parameter mount_options where for each image a specific mount configuration can be provided (for example, mounting offsets, filesystem types etc.). If that file does not exist, the automounter does not try to mount or unmount the image.

automount

bzeiss avatar Dec 25 '21 16:12 bzeiss

@akuker @rdmark @uweseimet Is this interesting enough that I should continue work on this on a rascsi branch on this github or should I keep this separate?

bzeiss avatar Dec 25 '21 17:12 bzeiss

I think this is interesting enough and there may be other use cases where this is helpful. I do share the concerns about the ability to upload and execute scripts as root. But, I think it would be cool to have this as an optional feature (disabled by default though). That way people who really know what they're doing can enable it as an advanced feature.

akuker avatar Dec 26 '21 21:12 akuker

Ok, here is what I propose:

I'll create a branch of devellop that I work on with a directory RASCSI/src/proxy. In there, I will build an isolated tool with it's own systemd start script, venv etc. In the beginning, it will have some amount of code duplication with the web interface. There are some commonalities that are needed in both (parts from ractl_cmd.py and socket_cmd.py). I have adapted some the parts that I needed slightly to not be hardwired against localhost and port 6868 any more. We'll have to figure out then whether we'll live with that duplication or whether it makes sense to refactor some parts out into a slightly more generic rascsi protobuf client library for python that is then used by the proxy and the web interface.

bzeiss avatar Dec 26 '21 21:12 bzeiss

@bzeiss We already have mild code duplication in ractl_cmd.py and socket_cmd.py between rascsi-web and the OLED monitor packages. Three-way code duplication is definitely a spot when maintenance becomes a real headache. I'd love to try to break out common code and create common classes. Is this something you'd like to take a stab at?

Related discussion in: https://github.com/akuker/RASCSI/issues/455

rdmark avatar Dec 26 '21 22:12 rdmark

Ah, I see. I do agree, it kind of makes sense to start with the restructuring first. I'll probably want to create that proxy branch anyway since I want the existing code to be archived somewhere, but it'll probably need some major rework afterwards. Yeah, why not. I can take a stab at it, at least the python folders, I'm happy to help. I'll continue with the restucture discussion in #455.

bzeiss avatar Dec 26 '21 22:12 bzeiss

Please hold off on any restructuring in the develop branch until the v21.12 release is tagged. (Currently shooting for Dec 29th). Excited to see what you come up with!

akuker avatar Dec 28 '21 01:12 akuker

This ticket reminds me of https://github.com/PiSCSI/piscsi/issues/353. After almost 2 years of inactivity, what should be the next steps?

uweseimet avatar Oct 16 '23 22:10 uweseimet