Repository navigation
vnc_clean: stop the session by display in vnc and vnc_container - #1000
Conversation
|
|
||
| #{vnc_clean} | ||
| [[ -n ${display} ]] && vncserver -kill :${display} | ||
| [[ -n ${display} ]] && #{container_command} exec instance://#{@instance_name} vncserver -kill :${display} |
There was a problem hiding this comment.
I'm finding that the default vnc_clean (issued above this) already does this correctly.
ood_core/lib/ood_core/batch_connect/templates/vnc_container.rb
Lines 251 to 255 in 88deb05
I've got this output here where the default vnc_clean already stops so when this is issued, it errors.
+ awk '/^:/{system("kill -0 "$2" 2>/dev/null || apptainer exec instance://990eb0d3-fac6-40af-b0e7-31aefcbb7bfb vncserver -kill "$1)}'
+ apptainer exec instance://990eb0d3-fac6-40af-b0e7-31aefcbb7bfb vncserver -list
Killing Xvnc process ID 54
+ [[ -n 1 ]]
+ apptainer exec instance://990eb0d3-fac6-40af-b0e7-31aefcbb7bfb vncserver -kill :1
Can't find file /root/.vnc/p0220.ten.osc.edu:1.pid
You'll have to kill the Xvnc process manually
Seems strange to even have this 2nd fallback that just checks for the display environment variable and not an actual vnc server because the environment variable doesn't clear when the vncserver stops. I.e., [[ -n $display ]] will always be true.
I'm also finding that the original clean this is based off of has the opposite behavior - the default vnc_clean fails and always comes to this fallback which then works...
Still looking into why one would work and the other wouldn't but it seems to me we don't need this fallback and what's in vnc_clean should work.
There was a problem hiding this comment.
I am now realizing vnc_clean works by coincidence in this file - kill -0 <containerPID> fails because the container is PID namespaced and containerPID is not the host PID. So the || expression then moves on to correctly kill the process.
Not sure why they used an || expression in the vnc template or even bothered to grab it out of vncserver -list.
In any case, it seems to me that vnc_clean should be updated in both files and this 2nd fallback removed. I think vncserver -kill :${display} is the way to go without extracting from vncserver -list as there may be multiple servers running anyhow.
There was a problem hiding this comment.
Really sorry at the delay, but this got a bit more involved in the tests than i was expecting.
Agreed, and done in both templates. vnc_clean now kills by display (-kill :${display}, run inside the instance for vnc_container), and the second kill line in clean_script is gone.
I kept [[ -n ${display} ]], moved inside vnc_clean. You're right that it's always true once the server has started, so it doesn't tell us whether the server is alive. That's not its job. vnc_clean also runs before each attempt in the startup retry loop, and in clean_up 1 when the server never starts, and display isn't set yet in either place. Without the guard those would run vncserver -kill : with an empty display, which TurboVNC rejects with an error, so a failed start would fill the log with those errors on top of the real one.
Tests:
vnc_test.rbandvnc_container_test.rb:vnc_cleankills only this job's display, does nothing before the server starts, andclean_scriptkills exactly once.- New
vnc_cleanup_test.rb: runs the whole rendered job script against fakevncserver, websockify and container commands, and checks what gets killed when the script exits, fails, websockify fails, or the server never starts. It also checks that another job's session on the node is left alone, and that the container template kills inside the instance beforeinstance stop. It fails on master for the originalvnc_containererror inclean_upfunction #931 bug, and runs in about 2.5s.
Two side effects:
- The stale-session sweep is gone, so old crashed sessions aren't cleaned up from
~/.vncanymore. Given what you found about-listacross jobs and PID namespaces, that seemed like the right trade. - A site that overrides
:vnc_cleannow owns the whole cleanup, since the hard-coded kill line is gone. I can add a CHANGELOG note if you'd like.
Also rebased onto master and moved the container test to test/batch_connect/.
There was a problem hiding this comment.
A site that overrides :vnc_clean now owns the whole cleanup, since the hard-coded kill line is gone. I can add a CHANGELOG note if you'd like.
CHANGELOG does not appear to be up to date, but yea I think that's probably a good idea to update it. Doesn't look like the official docs say what vnc_clean does so that'll need an update too.
There was a problem hiding this comment.
Added a CHANGELOG entry under Unreleased (plus the missing one for #1006 since why not). For the docs, I opened OSC/ood-documentation#1438, which documents vnc_clean along with the vncserver_cmd/vncpasswd_cmd options from #1006. It should merge after this one, since it describes the new vnc_clean behavior.
vnc_clean walked vncserver -list and killed sessions whose PID failed kill -0. In vnc_container those PIDs are from the instance's PID namespace, so the host-side check can't tell live from dead. It failed for our live session, killed it, and the second kill in clean_script then errored on the missing pid file. In vnc the check passed for our live session, so the second line was the one doing the work. Kill by display in vnc_clean for both templates and drop the second line. display is unset until the server starts, so the call in the startup loop and after a failed start does nothing.
The unit tests check vnc_clean on its own. These render each template, run the whole job script against fake vncserver, websockify and container commands, and check which displays get killed when the script exits, when it fails, when websockify fails, and when the server never starts. Also that another job's session is left alone, and that the container template kills inside the instance before stopping it.
Most of the test's run time was the template's own sleeps: up to 0.9s between each of 10 start retries, and 1s while polling for websockify. A sleep on the job's PATH shortens just those and runs any other sleep as normal. 15s to about 2.5s.
Lmod sets BASH_ENV, so every bash the test starts sourced its init first. With a 0.1s init that took the file from 2.5s to 41s. module is stubbed in the test, so unset BASH_ENV for the job. The fake websockify also outlived each test: the template starts it inside $(...), so clean_up's pkill -P $$ can't reach it. Teardown now kills it.
a2e3f00 to
9768ac7
Compare
Real vncserver doesn't return until Xvnc is up. The fake did, so on a busy CI runner the template's pgrep -s 0 Xvnc could run before the background process became Xvnc, see no server, and retry on the next display. Clean-up then killed :2 and the tests expecting :1 failed.
vnc_clean: stop the session by display in vnc and vnc_container
johrstrom
left a comment
There was a problem hiding this comment.
Both vnc and vnc_container templates work for me.
What does this PR do?
vnc_cleanwalkedvncserver -listand killed sessions whose PID failedkill -0, andclean_scriptthen ran a second kill by display.vnc_container, the PIDs from-listare from the instance's PID namespace, so the host-sidekill -0can't tell live from dead.vnc_cleankilled our session and the second kill then errored. The second kill also ran on the host rather than in the container (vnc_containererror inclean_upfunction #931).vnc, the check passed for our live session, so the second line was the one doing the work.-listcan also include the user's other sessions on the node.Now both templates'
vnc_cleankill only this job's display (inside the instance forvnc_container), and the second line is gone. The[[ -n ${display} ]]guard stays insidevnc_clean, because it also runs in the startup retry loop and after a failed start, beforedisplayis set.vncserver -kill :errors on TurboVNC.Behavior changes:
~/.vnc.:vnc_cleannow owns the whole cleanup.Related issue
Closes #931
Testing
Tests included
test/batch_connect/vnc_test.rbandtest/batch_connect/vnc_container_test.rb:vnc_cleankills only this job's display, does nothing before the server starts, andclean_scriptkills once.test/batch_connect/vnc_cleanup_test.rb(new): runs each whole rendered job script against fakevncserver, websockify and container commands. Checks what gets killed on a normal exit, a script failure, a websockify failure, and a server that never starts. Also checks that another job's session is left alone, and thatvnc_containerkills inside the instance beforeinstance stop. Fails on master forvnc_containererror inclean_upfunction #931.bundle exec rake testandbundle exec rake specare green.Checklist
Anything else?
Not yet run against a real container with this branch. The end-to-end test uses fake
vncserverand container commands, and doesn't reproduce the instance's PID namespace. Killing by display doesn't depend on PIDs, though, so the namespace shouldn't matter here.The container
clean_scriptnow renders as:@johrstrom, if the apptainer setup from your review is still around, a run against this branch would confirm it.