-
-
Notifications
You must be signed in to change notification settings - Fork 747
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
Add UNIX domain socket transport #6183
Comments
Sounds good, thanks for the detailled suggestion! |
https://docs.python.org/3/library/socket.html The code in It seems like The remote code is rather complex and not very nice to work with, I'ld like to avoid additional complexity or risks there. |
Sockets can be turned into file objects for feature parity using the makefile api. https://docs.python.org/3/library/socket.html#socket.socket.makefile If those readable / writable objects can be used, it may be possible without pain. The only caveat would be that the socket server would have a one client at a time limit for lock parity. |
But |
in the case of socket fd integers - on unix read/write are equivalent to send/recv without flags |
@ThomasWaldmann You can call Thanks to #6270 giving me a nice starting point I just started looking into Borg's remote code and I agree that the current implementation is indeed not so easy to work with. The code very much confused me, especially whether However, looking at the code, Lines 198 to 201 in 1e1c922
What confuses me about this is that the "client" part, i.e. the Lines 589 to 592 in 1e1c922
Popen's stderr is then sent (here) to If all of this is true, it's basically really just replacing the fds on both ends by the fds of a
On a important side note: My intention with this suggestion is not making However, out of curiosity @RonnyPfannschmidt, why is |
Makefile isn't, the need for locking limits based on usage patterns |
@PhrozenByte btw, windows support is coming, @RayyanAnsari works on it (no remote repos yet though). |
About
Is that a good, usual syntax or are there better ideas? We need to transport socket path and repo path via that URL. Update: hmm, can we always assume that both must be local paths? So we could create the socket file inside the repo path? If so, we could use:
and just create the socket inside the repo dir as "socket" or ".socket". |
❤️ for #7519 😊
It mimics Borg's So, in the end, we can choose what inconsistency we want: We can use
No.
Am I right that your thinking about requiring local paths originates in the impracticability of
However, I still see the impracticability of So,
|
Thanks for the feedback (I had similar ideas/concerns, but just wanted something simple to get going and then refine after feedback). The reason why I chose double-slash + socket_abs_path is that this could grow support for TCP sockets (by using a server name or IP and port after the double-slash instead of the UDS path). The Your idea with a separate --socket option would also work, but is a bit inconsistent compared to ssh://server:port/path borg URLs where the server and port are part of the repo url and not contained in a separate (e.g. --ssh) option. So, how could we get a socket file path at place of SOCKET without parsing ambiguities?
Hmm, how about just mandating that SOCKET:
That would result in these usage patterns:
|
A more radical approach could be splitting that url into |
Yeah, good point. I agree, adding a Thinking about it, adding the socket's path to Adding a
In the future we might even not just look in the repo's path, but in other default locations as well. I just had a whole bunch of ideas, e.g.
In practice, this means that
You mean like |
@PhrozenByte about stderr: yeah, the borg serve function does not really use it, but the borg repository code emits logging messages on stderr (which usually go either directly to e.g. the console (for a local repo) or get sent via the ssh connection to the clientside code in RemoteRepository). So, guess we have that problem that there is no easy solution with just 1 bidi UDS.
So, guess all we have left is to multiplex stdout and stderr over one channel (and de-mux on the other side). Why is there no fd012-mux-socket-demux-fd012 tool? :-) |
That's very, very unfortunate 😒 Since Borg uses Python's built-in logging facility, I'd indeed recommend creating a To avoid this we could multiplex stdout and stderr, by e.g. prefixing all messages with a channel indicator (a single byte would do, e.g. Yet another solution is to quite literally open a second channel for stderr (i.e. calling I'd vote for the second approach, it's a good compromise. But indeed, this idea is no longer as easy as I initially thought it would be 😞
I'm not 100% sure what you mean. Are you referring to some log messages actually belonging to the server, not the client? I agree, this is a delicate topic, but there's no solution other than checking every single log message whether it's meant for the client, or the server. However, due to our "one client, one socket" policy, we don't really have to think about this right now: we just send everything to the client, the same way we already do for SSH. How we do this (see above), doesn't really matter IMHO. We won't really need this differentiation until we implement a "full Borg server". |
about socket file in the repo directory: that would limit operations to existing repos, we can't have the socket file in a repo dir that does not yet exist. |
Great work Thomas! 👏 ❤️ I agree. However, the issue what path to use for The "right place" for the socket is However, there are two open questions with
First, what's the right place for the socket if Second, what shall we do when Last, we should allow the user to give us a "definitive answer" where one wants his stuff... So a Just for record, I was also thinking about a So, let's wrap this up: We always use |
For most of the logic, we want to use https://github.com/platformdirs/platformdirs/blob/main/src/platformdirs/unix.py#L155 Misc. fs helpers already exist there: https://github.com/borgbackup/borg/blob/master/src/borg/helpers/fs.py Note: |
socket file permissions: Would that be a problem? Usually we have these scenarios:
Hmm, guess if one had a scenario where multiple different users would want to access the same socket file location for different user scenario: |
Yes, group r+w is required for scenarios with different unprivileged users on the same machine; this includes my original scenario in which the About using |
@PhrozenByte could you file a bug at |
|
@PhrozenByte merged stuff into master. if you have time, guess it would be good to give it some practical testing. |
/kind enhancement
When creating full system backups one must usually run Borg as
root
to avoid permission issues. However, it might be undesirable to store these backups as root, as people often prefer storing backups in known places (like/var/backups
) owned by dedicated users (like the defaultbackup
user in Debian-based distributions).Right now there are only two possible solutions to accomplish this:
chown
the repo afterborg create
et al. exitslocalhost
using SSH as different user (as suggested by @ThomasWaldmann, see references below)IMO this is a reasonable use case and Borg should support it without taking such rather desperate solutions.
Thus I'd like to suggest adding a
socket://
transport (likesocket:///run/borg/borg.sock
) to Borg. The socket should be created byborg serve
by accepting an additional--socket
option with a path (e.g.borg serve --socket /run/user/1000/borg/borg.sock
, umask 0117). Howborg serve
is being invoked is up to the user.borg create
et al. can now connect to this socket using thesocket://
transport (e.g.borg create socket:///run/borg/borg.sock /path/to/backup
).Even though this is not the goal, it also makes https://github.com/borgbackup/borg/blob/master/docs/deployment/pull-backup.rst#socat easier by eliminating
socat
. It might also enable some more use cases I just can't think of right now.As I don't know Borg's sources I can't really judge the complexity, but since Borg already supports remote transports with
borg serve
, this could be as easy as replacingsys.stdin
/sys.stdout
ofborg serve
with a UNIX domain socket and to letborg create
et al. communicate with this socket instead of thessh
subprocess.References
- #4082 (comment)
- #3587 (comment)
The text was updated successfully, but these errors were encountered: