osc-vnc 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +169 -0
  6. data/Rakefile +1 -0
  7. data/config/script.yml +35 -0
  8. data/examples/desktop/xstartup +5 -0
  9. data/examples/paraview/fvwm/fvwmrc +80 -0
  10. data/examples/paraview/fvwm/winxp/images/close-activedown.xpm +237 -0
  11. data/examples/paraview/fvwm/winxp/images/close-activeup.xpm +286 -0
  12. data/examples/paraview/fvwm/winxp/images/close-inactive.xpm +88 -0
  13. data/examples/paraview/fvwm/winxp/images/maximize-activedown.xpm +190 -0
  14. data/examples/paraview/fvwm/winxp/images/maximize-activeup.xpm +257 -0
  15. data/examples/paraview/fvwm/winxp/images/maximize-inactive.xpm +66 -0
  16. data/examples/paraview/fvwm/winxp/images/title-active.xpm +58 -0
  17. data/examples/paraview/fvwm/winxp/images/title-inactive.xpm +58 -0
  18. data/examples/paraview/xstartup +17 -0
  19. data/examples/totalsim-desktop/config/menus/applications.menu +84 -0
  20. data/examples/totalsim-desktop/config/menus/settings.menu +20 -0
  21. data/examples/totalsim-desktop/images/TS_LOGO.jpg +0 -0
  22. data/examples/totalsim-desktop/xlogout +8 -0
  23. data/examples/totalsim-desktop/xstartup +20 -0
  24. data/lib/osc/vnc/connview.rb +95 -0
  25. data/lib/osc/vnc/error.rb +6 -0
  26. data/lib/osc/vnc/listenable.rb +45 -0
  27. data/lib/osc/vnc/scriptview.rb +63 -0
  28. data/lib/osc/vnc/session.rb +116 -0
  29. data/lib/osc/vnc/version.rb +6 -0
  30. data/lib/osc/vnc.rb +23 -0
  31. data/osc-vnc.gemspec +26 -0
  32. data/templates/conn/awesim.mustache +1 -0
  33. data/templates/conn/jnlp.mustache +49 -0
  34. data/templates/conn/novnc.mustache +1 -0
  35. data/templates/conn/osxvnc.mustache +1 -0
  36. data/templates/conn/terminal.mustache +1 -0
  37. data/templates/conn/txt.mustache +4 -0
  38. data/templates/conn/vnc.mustache +1 -0
  39. data/templates/conn/yaml.mustache +6 -0
  40. data/templates/script/_port_helpers.mustache +28 -0
  41. data/templates/script/_setup_env.mustache +7 -0
  42. data/templates/script/_ssh_tunnel.mustache +28 -0
  43. data/templates/script/_start_vncserver.mustache +38 -0
  44. data/templates/script/_tcp_server.mustache +6 -0
  45. data/templates/script/server.mustache +46 -0
  46. data/templates/script/vnc.mustache +86 -0
  47. metadata +153 -0
@@ -0,0 +1,45 @@
1
+ require 'socket'
2
+
3
+
4
+ module OSC
5
+ module VNC
6
+ # Mixin that adds the ability to create and read from a TCP server.
7
+ module Listenable
8
+ # Generate a TCP server that listens on a random port.
9
+ #
10
+ # @return [TCPServer] ruby TCPServer object listening on random port
11
+ def create_listen
12
+ listen_host = Socket.gethostname
13
+ listen_port = _get_port
14
+ begin
15
+ server = TCPServer.new(listen_host, listen_port)
16
+ rescue Errno::EADDRINUSE
17
+ listen_port = _get_port
18
+ retry
19
+ end
20
+ server
21
+ end
22
+
23
+ # Read the data received by the TCP server.
24
+ #
25
+ # @param [Hash] args the arguments to read data received by TCP server with
26
+ # @option args [TCPServer] :server the TCP server that is currently listening
27
+ # @return [String] the contents of the data received by the server
28
+ def read_listen(args)
29
+ server = args[:server]
30
+ client = server.accept # wait for connection
31
+ client.read # read complete response
32
+ end
33
+
34
+
35
+ private
36
+
37
+ # Get random number form 40,000 to 50,000.
38
+ #
39
+ # @return [Fixnum] a random number from 40,000 to 50,000
40
+ def _get_port
41
+ rand(40000..50000)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,63 @@
1
+ require 'fileutils'
2
+ require 'mustache'
3
+ require 'yaml'
4
+
5
+ module OSC
6
+ module VNC
7
+ # Provides a view for the PBS batch script configured as a mustache
8
+ # template in templates/script/vnc.mustache. Extra options can be passed to
9
+ # this view and accessed directly in the mustache template.
10
+ class ScriptView < Mustache
11
+ self.template_path = SCRIPT_TEMPLATE_PATH
12
+
13
+ # @param type [Symbol] The script type defined in config/script.yml (:vnc or :server).
14
+ # @param cluster [String] The cluster the job will run on defined in config/script.yml.
15
+ # @param opts [Hash] The options used to construct PBS batch script view.
16
+ # @option opts [Symbol] :subtype The subtype (i.e., :default or :shared) outlined in config/script.yml.
17
+ def initialize(type, cluster, opts = {})
18
+ self.template_name = type
19
+
20
+ # Read in pre-configured options
21
+ script_cfg = YAML.load_file("#{CONFIG_PATH}/script.yml").fetch(type.to_s, {})
22
+ subtype_opts = script_cfg[opts[:subtype].to_s] || script_cfg['default']
23
+ cluster_opts = subtype_opts.fetch('cluster', {}).fetch(cluster, {})
24
+ context = subtype_opts.merge cluster_opts
25
+
26
+ @view_context = {}
27
+ context.each do |key, value|
28
+ @view_context[key.to_sym] = value
29
+ end
30
+ @view_context.merge! opts
31
+ @view_context[:cluster] = cluster
32
+ end
33
+
34
+ # Determine whether the script is valid or not
35
+ #
36
+ # @return [Boolean] Whether this is a valid script.
37
+ # @raise [InvalidPath] if { #xstartup } or { #outdir } do not correspond to actual file system locations
38
+ def valid?
39
+ raise InvalidPath, "xstartup script is not found" unless File.file?(xstartup)
40
+ raise InvalidPath, "output directory is a file" if File.file?(outdir)
41
+ FileUtils.mkdir_p(outdir)
42
+ end
43
+
44
+ # See if the method call exists as a key in @view_context.
45
+ #
46
+ # @param method_name the method name called
47
+ # @param arguments the arguments to the call
48
+ # @param block an optional block for the call
49
+ def method_missing(method_name, *arguments, &block)
50
+ @view_context.fetch(method_name) { super }
51
+ end
52
+
53
+ # Checks if the method responds to an instance method, or is able to
54
+ # proxy it to @view_context.
55
+ #
56
+ # @param method_name the method name to check
57
+ # @return [Boolean]
58
+ def respond_to_missing?(method_name, include_private = false)
59
+ @view_context.include?(method_name) || super
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,116 @@
1
+ require 'osc/vnc/listenable'
2
+
3
+ module OSC
4
+ module VNC
5
+ # Provides a way for developers to create and submit VNC sessions to the
6
+ # OSC batch systems. Also, developers are now able to submit any server
7
+ # session to the batch systems whether it is VNC or not following the same
8
+ # principles as a VNC session.
9
+ class Session
10
+ include OSC::VNC::Listenable
11
+
12
+ # @return [PBS::Job] The job object used.
13
+ attr_reader :job
14
+
15
+ # @return [ScriptView] The batch script used.
16
+ attr_reader :script
17
+
18
+ # @param job [PBS::Job] The job object used.
19
+ # @param script [ScriptView] The batch script used.
20
+ # @param opts [Hash] The options used to construct a session.
21
+ def initialize(job, script, opts = {})
22
+ @job = job
23
+ @script = script
24
+ end
25
+
26
+ # Submit the VNC job to the defined batch server.
27
+ #
28
+ # @param opts [Hash] The options used in job submission.
29
+ # @option opts [Hash] :headers The headers for the PBS job.
30
+ # @option opts [Hash] :resources The resources for the PBS job.
31
+ # @option opts [Hash] :envvars The environment variables for the PBS job.
32
+ # @return [Session] the session object
33
+ def submit(opts = {})
34
+ script.valid? # check if script is valid (can raise errors here)
35
+
36
+ h = opts.fetch(:headers, {})
37
+ r = opts.fetch(:resources, {})
38
+ e = opts.fetch(:envvars, {})
39
+
40
+ # Create tcp listen server if requested
41
+ listen_server = _create_listen_server(e) if script.tcp_server?
42
+
43
+ job.submit(
44
+ string: script.render,
45
+ headers: _get_headers(h),
46
+ resources: _get_resources(r),
47
+ envvars: _get_envvars(e),
48
+ qsub: true
49
+ )
50
+
51
+ _write_listen_conn_info(listen_server) if script.tcp_server?
52
+
53
+ self
54
+ end
55
+
56
+ # The connection information file.
57
+ #
58
+ # @return [String] path to connection information file for this session
59
+ def conn_file
60
+ "#{script.outdir}/#{job.id}.conn"
61
+ end
62
+
63
+
64
+ private
65
+
66
+ # The hash of PBS header attributes for the job.
67
+ def _get_headers(headers)
68
+ h = {
69
+ PBS::ATTR[:N] => "VNC_Job",
70
+ PBS::ATTR[:o] => "#{script.outdir}/$PBS_JOBID.output",
71
+ PBS::ATTR[:j] => "oe",
72
+ PBS::ATTR[:S] => "/bin/bash",
73
+ }.merge headers
74
+ h[PBS::ATTR[:N]] = "#{ENV['APP_TOKEN']}/#{h[PBS::ATTR[:N]]}" if ENV['APP_TOKEN']
75
+
76
+ # add first charged account group as default account
77
+ account = Process.groups.map {|g| Etc.getgrgid(g).name}.grep(/^P./).first
78
+ h[PBS::ATTR[:A]] ||= account if account
79
+
80
+ h
81
+ end
82
+
83
+ # The hash of PBS resources requested for the job.
84
+ def _get_resources(resources)
85
+ {
86
+ :nodes => "1:ppn=1:#{script.cluster}",
87
+ :walltime => "24:00:00",
88
+ }.merge resources
89
+ end
90
+
91
+ # The hash of environment variables passed to the job.
92
+ def _get_envvars(envvars)
93
+ {
94
+ }.merge envvars
95
+ end
96
+
97
+ # Create a tcp listen server and set appropriate environment variables.
98
+ # for batch script to phone home
99
+ def _create_listen_server(envvars)
100
+ listen_server = create_listen
101
+ _, port, host, _ = listen_server.addr(:hostname)
102
+ envvars.merge! LISTEN_HOST: host, LISTEN_PORT: port
103
+ listen_server
104
+ end
105
+
106
+ # Write connection information from a TCP listening server.
107
+ def _write_listen_conn_info(server)
108
+ # Wait until VNC conn info is created by PBS batch script
109
+ # Timeout after 60 seconds if no info is sent
110
+ Timeout::timeout(60) do
111
+ File.open(conn_file, 'w', 0600) { |f| f.puts read_listen(server: server) }
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,6 @@
1
+ module OSC
2
+ module VNC
3
+ # The current version of osc-vnc.
4
+ VERSION = "1.0.6"
5
+ end
6
+ end
data/lib/osc/vnc.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'pbs'
2
+
3
+ # The namespace used for OSC gems.
4
+ module OSC
5
+ # The main namespace for osc-vnc. Provides the ability to submit and read back
6
+ # the connection information for a VNC job on the OSC clusters.
7
+ module VNC
8
+ # Path to configuration yml files.
9
+ CONFIG_PATH = File.dirname(__FILE__) + "/../../config"
10
+
11
+ # Patch to PBS script template.
12
+ SCRIPT_TEMPLATE_PATH = File.dirname(__FILE__) + "/../../templates/script"
13
+
14
+ # Path to different connection information view templates.
15
+ CONN_TEMPLATE_PATH = File.dirname(__FILE__) + "/../../templates/conn"
16
+ end
17
+ end
18
+
19
+ require_relative 'vnc/version'
20
+ require_relative 'vnc/error'
21
+ require_relative 'vnc/session'
22
+ require_relative 'vnc/scriptview'
23
+ require_relative 'vnc/connview'
data/osc-vnc.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'osc/vnc/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "osc-vnc"
8
+ spec.version = OSC::VNC::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.authors = ["Jeremy Nicklas"]
11
+ spec.email = ["jnicklas@osc.edu"]
12
+ spec.summary = %q{Library to create VNC jobs with HPC resources (OSC specific)}
13
+ spec.description = %q{This library submits VNC jobs to the Oxymoron cluster as well as obtains the connection information required for a connection to take place with a VNC client. (OSC specific)}
14
+ spec.homepage = "https://github.com/OSC/osc-vnc"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_runtime_dependency "pbs", "~> 1.0"
23
+ spec.add_runtime_dependency "mustache", "~> 0.99", ">= 0.99.5"
24
+ spec.add_development_dependency "bundler", "~> 1.7"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ end
@@ -0,0 +1 @@
1
+ awesim://{{#password}}:{{password}}@{{/password}}{{host}}:{{port}}
@@ -0,0 +1,49 @@
1
+ {{^ssh_tunnel?}}
2
+ <?xml version="1.0" encoding="UTF-8"?>
3
+ <jnlp spec="1.0+" codebase="http://mirror.osc.edu/mirror" >
4
+ <information>
5
+ <title>TightVnc Viewer</title>
6
+ <vendor>GlavSoft LLC.</vendor>
7
+ <offline-allowed/>
8
+ </information>
9
+ <security>
10
+ <all-permissions/>
11
+ </security>
12
+ <resources>
13
+ <j2se version="1.6+"/>
14
+ <jar href="TightVncViewerSigned.jar" main="true"/>
15
+ </resources>
16
+ <application-desc main-class="com.tightvnc.vncviewer.VncViewer">
17
+ <argument>HOST</argument>
18
+ <argument>{{host}}</argument>
19
+ <argument>PORT</argument>
20
+ <argument>{{port}}</argument>
21
+ <argument>PASSWORD</argument>
22
+ <argument>{{password}}</argument>
23
+ </application-desc>
24
+ </jnlp>
25
+ {{/ssh_tunnel?}}
26
+ {{#ssh_tunnel?}}
27
+ <?xml version="1.0" encoding="UTF-8"?>
28
+ <jnlp spec="1.0+" codebase="http://mirror.osc.edu/mirror" >
29
+ <information>
30
+ <title>TightVnc Viewer</title>
31
+ <vendor>GlavSoft LLC.</vendor>
32
+ <offline-allowed/>
33
+ </information>
34
+ <security>
35
+ <all-permissions/>
36
+ </security>
37
+ <resources>
38
+ <j2se version="1.6+"/>
39
+ <jar href="tightvnc-jviewer.jar" main="true"/>
40
+ </resources>
41
+ <application-desc main-class="com.glavsoft.viewer.Viewer">
42
+ <argument>-host={{host}}</argument>
43
+ <argument>-port={{port}}</argument>
44
+ <argument>-password={{password}}</argument>
45
+ <argument>-sshhost={{sshhost}}</argument>
46
+ <argument>-sshuser={{sshuser}}</argument>
47
+ </application-desc>
48
+ </jnlp>
49
+ {{/ssh_tunnel?}}
@@ -0,0 +1 @@
1
+ /rnode/{{host}}/{{web_port}}/vnc_auto.html?password={{#view_only}}{{spassword}}{{/view_only}}{{^view_only}}{{password}}{{/view_only}}&path=rnode/{{host}}/{{web_port}}/websockify
@@ -0,0 +1 @@
1
+ ssh -f -N -L {{localport}}:{{host}}:{{port}} {{sshuser}}@{{sshhost}} && open vnc://:{{password}}@localhost:{{localport}}
@@ -0,0 +1 @@
1
+ ssh -L {{localport}}:{{host}}:{{port}} {{sshuser}}@{{sshhost}}
@@ -0,0 +1,4 @@
1
+ Host: {{host}}
2
+ Port: {{port}}
3
+ Pass: {{password}}
4
+ Display: {{display_port}}
@@ -0,0 +1 @@
1
+ vnc://:{{password}}@localhost:{{localport}}
@@ -0,0 +1,6 @@
1
+ host: {{host}}
2
+ port: {{port}}
3
+ pass: {{password}}
4
+ display: {{display_port}}
5
+ sshuser: {{sshuser}}
6
+ sshhost: {{sshhost}}
@@ -0,0 +1,28 @@
1
+ # Generate random integer in range [$1..$2)
2
+ function random () {
3
+ local MIN=$1
4
+ local MAX=$2
5
+ local RANGE=$((MAX - MIN))
6
+ local RAND=$(od -An -N4 -t uL /dev/urandom | tr -d " ")
7
+ local RAND_MAX=$((2**(4*8)))
8
+
9
+ local FLOAT=$(echo "$RANGE * ($RAND / $RAND_MAX) + $MIN" | bc -l)
10
+
11
+ echo $(echo "$FLOAT / 1" | bc)
12
+ }
13
+
14
+ # Check if port is used
15
+ function used_ports () {
16
+ local PORT=$1
17
+
18
+ echo $(netstat -lnt | awk -v port=$PORT '$6 == "LISTEN" && $4 ~ ":"port"$"' | wc -l)
19
+ }
20
+
21
+ # Get available port
22
+ function get_port () {
23
+ local PORT=$(random 2000 65535)
24
+ while [[ $(used_ports ${PORT}) -ne 0 ]]; do
25
+ PORT=$(random 2000 65535)
26
+ done
27
+ echo ${PORT}
28
+ }
@@ -0,0 +1,7 @@
1
+ export VNC_LOGFILE={{outdir}}/${PBS_JOBID}.log
2
+ {{#tcp_server?}}
3
+ export VNC_OUTFILE=$(mktemp)
4
+ {{/tcp_server?}}
5
+ {{^tcp_server?}}
6
+ export VNC_OUTFILE={{outdir}}/${PBS_JOBID}.conn
7
+ {{/tcp_server?}}
@@ -0,0 +1,28 @@
1
+ {{#ssh_tunnel?}}
2
+ HOST=$(hostname)
3
+ {{/ssh_tunnel?}}
4
+ {{^ssh_tunnel?}}
5
+ # Get correct host
6
+ #
7
+ # opt2647.ten.osc.edu => vis033.osc.edu
8
+ # opt2648.ten.osc.edu => vis034.osc.edu
9
+ # opt2649.ten.osc.edu => vis035.osc.edu
10
+ # opt2650.ten.osc.edu => vis036.osc.edu
11
+ # n0691.ten.osc.edu => oak-vis001.osc.edu
12
+ # n0692.ten.osc.edu => oak-vis002.osc.edu
13
+ #
14
+ # 1. we grep the output of /sbin/ip a s to 192.148.0.0/16 to get 192.148.248.70/24, getting the first match only to ignore 192.148.248.255
15
+ #
16
+ # 7: eth0.70@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
17
+ # inet 192.148.248.75/24 brd 192.148.248.255 scope global eth0.70
18
+ #
19
+ # 2. we use this as argument to dig i.e. dig +short -x 192.148.248.70
20
+ #
21
+ # vis033.osc.edu.
22
+ #
23
+ # 3. we get rid of the ending .
24
+ function public_hostname {
25
+ /sbin/ip a s to 192.148.0.0/16 | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -n1 | xargs dig +short -x | sed 's/\.$//'
26
+ }
27
+ HOST=$(public_hostname)
28
+ {{/ssh_tunnel?}}
@@ -0,0 +1,38 @@
1
+ # Start up vnc server and create output
2
+ # If two servers start simultaneously one will fail, loop until it succeeds
3
+ i=0
4
+ while [[ -z ${VNC_PID} && ${i} -lt 30 ]]; do
5
+ # Clean up any failed vnc sessions that didn't clean themselves up
6
+ vncserver -list | awk '/^:/{display[$1] = $2} END{for(key in display) { if( system( "[ ! -e /proc/" display[key] " ]" ) == 0 ) { system( "vncserver -kill " key ) } }}'
7
+ # Run the vncserver
8
+ VNC_OUT=$(vncserver \
9
+ -name {{name}} \
10
+ -geometry {{geom}} \
11
+ -dpi {{dpi}} \
12
+ -fp {{fonts}} \
13
+ -{{^otp?}}no{{/otp?}}otp \
14
+ {{#vncauth?}}-rfbauth ${VNC_PASSFILE}{{/vncauth?}}{{^vncauth?}}-novncauth{{/vncauth?}} \
15
+ -{{^pam?}}no{{/pam?}}pam \
16
+ -nohttpd \
17
+ -idletimeout {{idletimeout}} \
18
+ -log ${VNC_LOGFILE} \
19
+ -noxstartup \
20
+ {{{extra_args}}} 2>&1)
21
+ VNC_PID=$(pgrep -s 0 Xvnc) # Get process id
22
+ # VNC couldn't find display so died
23
+ if [[ -z ${VNC_PID} ]]; then
24
+ sleep 0.$(($RANDOM % 100))s # Sleep between 0-1 seconds
25
+ fi
26
+ # Sometimes VNC will hang if it fails to find working display
27
+ if [[ ! -z ${VNC_PID} && ${VNC_OUT} =~ "Fatal server error" ]]; then
28
+ kill -9 ${VNC_PID}
29
+ unset VNC_PID
30
+ fi
31
+ i=$((i+1)) # increment counter
32
+ done
33
+ echo "${VNC_OUT}"
34
+
35
+ # Make sure it is running otherwise exit with error code 1
36
+ if [[ -z ${VNC_PID} ]]; then
37
+ exit 1
38
+ fi
@@ -0,0 +1,6 @@
1
+ {{#tcp_server?}}
2
+ # Send connection information over a TCP connection
3
+ # The server information should have been passed as environment variables
4
+ nc ${LISTEN_HOST} ${LISTEN_PORT} < ${VNC_OUTFILE}
5
+ rm -f ${VNC_OUTFILE}
6
+ {{/tcp_server?}}
@@ -0,0 +1,46 @@
1
+ # Set some environment variables used by this script
2
+ {{> _setup_env}}
3
+
4
+ {{#xinit}}
5
+ # Port helpers
6
+ {{> _port_helpers}}
7
+
8
+ # Run developer supplied xinit script
9
+ source {{xinit}}
10
+ {{/xinit}}
11
+
12
+ # Function that creates a connection information file
13
+ function create_connfile {
14
+ echo "Host: ${HOST}" > ${VNC_OUTFILE}
15
+ echo "Port: ${HOST_PORT}" >> ${VNC_OUTFILE}
16
+ echo "Password: ${PASSWORD}" >> ${VNC_OUTFILE}
17
+ chmod 600 ${VNC_OUTFILE}
18
+ }
19
+
20
+ # Clean up script run when "vncserver" finishes or dies prematurely
21
+ # Note: must be defined after `module load`
22
+ function clean_up {
23
+ echo "Exiting..."
24
+ {{{xlogout}}}
25
+ }
26
+ trap clean_up TERM EXIT
27
+
28
+ # Create logfile
29
+ > ${VNC_LOGFILE}
30
+
31
+ # Run the xstartup script on proper vncserver display
32
+ {{xstartup}} >> ${VNC_LOGFILE} 2>&1 &
33
+ SCRIPT_PID=$(pgrep -s 0 -f {{xstartup}})
34
+
35
+ {{> _ssh_tunnel}}
36
+
37
+ # Create the connection file
38
+ create_connfile
39
+
40
+ {{> _tcp_server}}
41
+
42
+ # Wait for main process to finish
43
+ while [ -e /proc/${SCRIPT_PID} ]; do sleep 0.1; done
44
+
45
+ # Exit cleanly
46
+ exit 0
@@ -0,0 +1,86 @@
1
+ # Set some environment variables used by this script
2
+ {{> _setup_env}}
3
+ export VNC_PASSFILE={{outdir}}/${PBS_JOBID}.pass
4
+
5
+ # Use turbovnc
6
+ {{{load_turbovnc}}}
7
+
8
+ {{#vncauth?}}
9
+ # Allow the ability to dynamically change VNC password
10
+ function change_passwd {
11
+ # Generate password for VNC
12
+ PASSWORD=$(mkpasswd -s 0 -l 8) # passwords truncated to 8 letters
13
+ SPASSWORD=${SPASSWORD:-$(mkpasswd -s 0 -l 8)}
14
+ printf "${PASSWORD}\n${SPASSWORD}" | vncpasswd -f > ${VNC_PASSFILE}
15
+ chmod 600 ${VNC_PASSFILE}
16
+ }
17
+ change_passwd
18
+ {{/vncauth?}}
19
+
20
+ # Function that creates a connection information file
21
+ function create_connfile {
22
+ echo "Host: ${HOST}" > ${VNC_OUTFILE}
23
+ echo "Port: ${HOST_PORT}" >> ${VNC_OUTFILE}
24
+ echo "Password: ${PASSWORD}" >> ${VNC_OUTFILE}
25
+ echo "SPassword: ${SPASSWORD}" >> ${VNC_OUTFILE}
26
+ echo "Display_Port: ${DISPLAY_PORT}" >> ${VNC_OUTFILE}
27
+ echo "Web_Port: ${WEB_PORT}" >> ${VNC_OUTFILE}
28
+ chmod 600 ${VNC_OUTFILE}
29
+ }
30
+
31
+ # Clean up script run when "vncserver" finishes or dies prematurely
32
+ # Note: must be defined after `module load`
33
+ function clean_up {
34
+ echo "Exiting..."
35
+ vncserver -kill :${DISPLAY_PORT}
36
+ {{{xlogout}}}
37
+ }
38
+ trap clean_up TERM EXIT
39
+
40
+ {{> _start_vncserver}}
41
+
42
+ # Parse output for ports
43
+ DISPLAY_PORT=$(echo "${VNC_OUT}" | awk -F':' '/^Desktop/{print $NF}')
44
+ HOST_PORT=$((5900+DISPLAY_PORT))
45
+
46
+ {{#otp?}}
47
+ # Parse output for password
48
+ PASSWORD=$(echo "${VNC_OUT}" | awk '/^Full/{print $NF}')
49
+ {{/otp?}}
50
+
51
+ # Run the xstartup script on proper vncserver display
52
+ DISPLAY=:${DISPLAY_PORT} {{xstartup}} >> ${VNC_LOGFILE} 2>&1 &
53
+ SCRIPT_PID=$(pgrep -s 0 -f {{xstartup}})
54
+
55
+ {{> _ssh_tunnel}}
56
+
57
+ {{#novnc?}}
58
+ # Port helpers
59
+ {{> _port_helpers}}
60
+
61
+ # Launch noVNC on available port
62
+ export WEB_PORT=$(get_port)
63
+ {{{novnc_launcher}}} --vnc localhost:${HOST_PORT} --listen ${WEB_PORT} >> ${VNC_LOGFILE} 2>&1 &
64
+ {{/novnc?}}
65
+
66
+ {{#vncauth?}}
67
+ # Check for authenticated user connections to VNC server then change password
68
+ while read -r line; do
69
+ if [[ ${line} =~ "Full-control authentication enabled for" ]]; then
70
+ change_passwd
71
+ create_connfile
72
+ echo "Changing VNC password..." >> ${VNC_LOGFILE}
73
+ fi
74
+ done < <(tail -f ${VNC_LOGFILE}) &
75
+ {{/vncauth?}}
76
+
77
+ # Create the connection file
78
+ create_connfile
79
+
80
+ {{> _tcp_server}}
81
+
82
+ # Wait for main process to finish
83
+ while [ -e /proc/${VNC_PID} ]; do sleep 0.1; done
84
+
85
+ # Exit cleanly
86
+ exit 0