xpra icon
Bug tracker and wiki

Opened 4 years ago

Last modified 13 months ago

#408 new enhancement

Support "singleton" mode -- start xpra instance only if no other live instance exists

Reported by: krlmlr Owned by: krlmlr
Priority: major Milestone: future
Component: server Version:
Keywords: Cc:

Description

I would like to propose an enhancement to xpra:

Support for --singleton switch to xpra start that will result in a no-op if a live session exists (as seen by xpra list). If this switch is given, xpra writes sourceable shell scripts to a predefined location (say, ~/.xpra/display-$HOSTNAME.sh, .csh, .fish) that export the DISPLAY variable to the value used by the singleton. (In anticiptation to a solution for #172...)

The purpose is to achieve a behavior similar to Gentoo's keychain. This is a tool which ensures that an ssh-agent is always available and accessible from the shell. There, keychain is started from .profile, ensures that one ssh-agent is up and running and adds keys to that agent, possibly querying for a passphrase. This tool also creates sourceable shell scripts that contain proper values for SSH_AGENT_PID and SSH_AUTH_SOCK -- these scripts are normally sourced from .bashrc or the equivalent for the other shells.

If xpra had such a facility, one could finally seamlessly integrate xpra with screen, using pretty much the same approach as keychain. Of course, it would be possible to implement this in an external script, and I'd be willing to do so. However, I think this feature is better suited within xpra itself.

References:

http://stackoverflow.com/a/18041092/946850 for a more verbose description of keychain in the context of using SSH keys with cron jobs

http://krlmlr.github.io/2013/08/07/integrating-xpra-with-screen/ for an attempt to integrate xpra with screen -- works, but the solution proposed above would be better.

Change History (11)

comment:1 Changed 4 years ago by Antoine Martin

Owner: changed from Antoine Martin to krlmlr

I am still unclear on what you are trying to achieve? You are describing a process rather than a problem that needs solving. What does this have to do with #172 for example? How does this help in choosing a free display number?
(FWIW: I am well aware of how keychain and ssh-agent work)


A singleton per what? per DISPLAY or per user session?
If per user session, you still need to choose a DISPLAY to use, which may still clash with other users..

Please explain what it is that you are trying to do.


Other notes:

  • putting a hardcoded username in the system wide config file is very bad practise, use your own config file for that .xpra/xpra.conf

Or, if you want this feature, we could quite easily allow you to specify:

socket-dir = /tmp/xpra-$USERNAME

And expand this variable at runtime instead. (ticket please)

  • not sure if you are aware of it, but you don't need screen to start your apps from within xpra:
    • --start-child will keep them running even if your ssh shell disconnects
    • you can use ssh *and* start-child in one: xpra start ssh:HOST:DISPLAY --start-child=SOMECMD
  • looking for X11 sockets in /tmp/ is horrible and won't work with multi-user as it is

comment:2 in reply to:  1 Changed 4 years ago by krlmlr

Thanks a lot for your detailed and fast reply.

Replying to antoine:

I am still unclear on what you are trying to achieve? You are describing a process rather than a problem that needs solving.

.

I have edited my post at http://krlmlr.github.io/2013/08/07/integrating-xpra-with-screen/ , hope this makes my intention a bit clearer.

.

What does this have to do with #172 for example? How does this help in choosing a free display number?

.

It doesn't. But once xpra chooses display numbers on its own, it will help if xpra creates a small sourceable file that just reads DISPLAY=###; export DISPLAY.

.

A singleton per what? per DISPLAY or per user session?

.

A singleton per user. xpra start --singleton is like xpra start the first time and no-op the second, third, ... time unless the xpra instance terminates.

.

Other notes:

  • putting a hardcoded username in the system wide config file is very bad practise, use your own config file for that .xpra/xpra.conf

Or, if you want this feature, we could quite easily allow you to specify:

socket-dir = /tmp/xpra-$USERNAME

And expand this variable at runtime instead. (ticket please)

.

#414, if it's really that simple.

.

  • not sure if you are aware of it, but you don't need screen to start your apps from within xpra:
    • --start-child will keep them running even if your ssh shell disconnects
    • you can use ssh *and* start-child in one: xpra start ssh:HOST:DISPLAY --start-child=SOMECMD

.

No, I really want to start GUI apps from within Screen and keep them persistent across connections, at least as long as Screen is running. Things should "just work". I was indeed investigating xpra start $DISPLAY --start-child=screen --exit-with-children, but there are problems with this approach:

  • The command line doesn't work as is, xpra terminates immediately, probably because Screen terminates
  • If I add --no-daemon, xpra's chatter distorts the output of Screen

I didn't open a ticket for that issue because I think that a keychain-like solution is more elegant.

.

  • looking for X11 sockets in /tmp/ is horrible and won't work with multi-user as it is

.

I still fail to see why. I seem to have reading permissions on /tmp/.X11-unix. What happens if other X sessions exist, will I be unable to list this directory?

comment:3 Changed 4 years ago by Antoine Martin

OK, I think I get it now.
You want a singleton xpra session per user.

Some more notes:

The window title is set to $HOSTNAME.


That's done automatically already by xpra, see --title.

It doesn't. But once xpra chooses display numbers on its own, it will help if xpra creates a small sourceable file that just reads DISPLAY=###; export DISPLAY.


We purposedly remove DISPLAY from "~/.xpra/run-xpra so that it can be used for any session (used by ssh connection) - but I guess singleton mode could add it there, or we could put it somewhere else.

The command line doesn't work as is, xpra terminates immediately, probably because Screen terminates


Either:

  • don't use --exit-with-children
  • don't launch screen but something you can launch from, screen is not an X11 app, "xterm" is for example


I seem to have reading permissions on /tmp/.X11-unix


Many reasons, permissions is one, your script breaks with multiple users, etc..

Last edited 4 years ago by Antoine Martin (previous) (diff)

comment:4 in reply to:  3 ; Changed 4 years ago by krlmlr

Replying to totaam:

Some more notes:

The window title is set to $HOSTNAME.


That's done automatically already by xpra, see --title.


My script https://gist.github.com/krlmlr/6165018#file-xpra-attach-ssh sets the title for the terminal window that is running xpra attach, not the title string of the GUI application windows. (Useful e.g. in connection with guake.) So, it seems that --title doesn't help much.

It doesn't. But once xpra chooses display numbers on its own, it will help if xpra creates a small sourceable file that just reads DISPLAY=###; export DISPLAY.


We purposedly remove DISPLAY from ~/.xpra/run-xpra ... we could put it somewhere else.


"Somewhere else" would be great :-)

The command line doesn't work as is, xpra terminates immediately, probably because Screen terminates


Either:

  • don't use --exit-with-children
  • don't launch screen but something you can launch from, screen is not an X11 app, "xterm" is for example


One way to get a bash shell with SSH agent support is to run ssh-agent bash. My attempt was similar in style: I wanted the Screen to inherit the environment created by xpra, especially the DISPLAY environment variable.

I seem to have reading permissions on /tmp/.X11-unix


Many reasons, permissions is one, your script breaks with multiple users, etc..


I'm aware of the race condition, but I really don't see why the script breaks with multiple users. I just tried my Debian server, I was able to list /tmp/.X11-unix with another user account and saw the socket from my primary user account. The directory contains only socket X5557, when running my scriptlet

echo $(( $( (echo 5555; ls /tmp/.X11-unix/X* 2> /dev/null) | sed 's/^.*\/X//' | sort -n | tail -n 1) + 1))

for the second user account it outputs (correctly) 5558. So, what's wrong here short of the race condition (display might be grabbed by other process between query and allocation attempt)? Perhaps other distributions are affected? Other versions of X11? Other use cases?

I'm sure you've seen this question: http://stackoverflow.com/q/2520704/946850 . The accepted answer is more or less what I've suggested in my previous comment, except that I would try display numbers in some pseudo-random order.

comment:5 in reply to:  4 ; Changed 4 years ago by Antoine Martin

Replying to krlmlr:

My script https://gist.github.com/krlmlr/6165018#file-xpra-attach-ssh sets the title for the terminal window that is running xpra attach, not the title string of the GUI application windows. (Useful e.g. in connection with guake.) So, it seems that --title doesn't help much.


I'll take your word for it, right now the script shows:

#!/bin/sh
 
ATTACH_TO=ssh:$1
 
echo -n "\033]0;xpra $1\007"
echo "Attaching to $ATTACH_TO..." >> /dev/stderr
xpra attach $ATTACH_TO

I guess the logic to generate the arguments got moved somewhere else.

One way to get a bash shell with SSH agent support is to run ssh-agent bash. My attempt was similar in style: I wanted the Screen to inherit the environment created by xpra, especially the DISPLAY environment variable.


If that's all you want, then I don't see the problem with --start-child, just don't use --exit-with-children.

I'm aware of the race condition, but I really don't see why the script breaks with multiple users. I just tried my Debian server, I was able to list /tmp/.X11-unix with another user account and saw the socket from my primary user account. The directory contains only socket X5557, when running my scriptlet


The race condition is one, and the info you provided in #172 (-displayfd) is the right solution for that.

echo $(( $( (echo 5555; ls /tmp/.X11-unix/X* 2> /dev/null) | sed 's/^.*\/X//' | sort -n | tail -n 1) + 1))

for the second user account it outputs (correctly) 5558. So, what's wrong here short of the race condition (display might be grabbed by other process between query and allocation attempt)? Perhaps other distributions are affected? Other versions of X11? Other use cases?

I'm sure you've seen this question: http://stackoverflow.com/q/2520704/946850 . The accepted answer is more or less what I've suggested in my previous comment, except that I would try display numbers in some pseudo-random order.


As for multiple users, I haven't thought about this in great detail, but I'm pretty sure that there are other problems lurking here. What if you have a real X11 display already? Or worse, you have an xpra shadow of a real X11 display... you probably expect the singleton not to take that one into account... etc.

Last edited 4 years ago by Antoine Martin (previous) (diff)

comment:6 in reply to:  5 Changed 4 years ago by krlmlr

Replying to antoine:

I'll take your word for it, right now the script shows:

#!/bin/sh
 
ATTACH_TO=ssh:$1
 
echo -n "\033]0;xpra $1\007"
echo "Attaching to $ATTACH_TO..." >> /dev/stderr
xpra attach $ATTACH_TO

I guess the logic to generate the arguments got moved somewhere else.


The script is fine just like that. A host name or address is expected as parameter, the title string of the terminal is set to xpra <host name> by the line starting with echo -n.

I wanted the Screen to inherit the environment created by xpra, especially the DISPLAY environment variable.


If that's all you want, then I don't see the problem with --start-child, just don't use --exit-with-children.


But in this setting I want xpra to terminate once Screen quits, i.e. when the last terminal window inside Screen closes. Why do you think it's wrong to use --exit-with-children here?

What if you have a real X11 display already?


The real X11 display has its own entry in /tmp/.X11-unix. But anyway, -displayfd is a better solution to #172, so let's keep it at that.

Or worse, you have an xpra shadow of a real X11 display... you probably expect the singleton not to take that one into account... etc.


I'm not using shadows, but I think shadow sessions should indeed be just ignored when the --singleton switch is used.

comment:7 Changed 4 years ago by Antoine Martin

Why do you think it's wrong to use --exit-with-children here?


I thought you were having problems with xpra terminating early when you used it with screen.

comment:8 in reply to:  7 Changed 4 years ago by krlmlr

Replying to totaam:

Why do you think it's wrong to use --exit-with-children here?


I thought you were having problems with xpra terminating early when you used it with screen.


No, Screen terminates, presumably because it doesn't get a tty when running without --no-daemon. If, on the other hand, I use --no-daemon, xpra output interferes with Screen.

comment:9 Changed 4 years ago by Antoine Martin

Milestone: future

No, Screen terminates, presumably because it doesn't get a tty when running without --no-daemon. If, on the other hand, I use --no-daemon, xpra output interferes with Screen.


Gotcha, not sure what can be done about this.

comment:10 Changed 4 years ago by Norman Rasmussen

btw, you could use ssh_config's LocalCommand

(make sure PermitLocalCommand is true) to launch xpra-attach-ssh, instead of having to execute it manually.

Last edited 4 years ago by Antoine Martin (previous) (diff)

comment:11 Changed 13 months ago by Antoine Martin

FYI: the proxy now supports starting new sessions on demand, see #1319.

It shouldn't be too difficult to enhance it to re-use existing sessions if they exist... how to identify those sessions is not really clear to me, maybe the "session-name" could be used?

Note: See TracTickets for help on using tickets.