zone-vnc-console revision 4626
c30ef289fe64ac7fedc44cfcc6b439f0f8458b4cgregames# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
ab8c0315521735c73ce16c8072f91e17c406ca5bnd# Licensed under the Apache License, Version 2.0 (the "License"); you may
ab8c0315521735c73ce16c8072f91e17c406ca5bnd# not use this file except in compliance with the License. You may obtain
ab8c0315521735c73ce16c8072f91e17c406ca5bnd# a copy of the License at
b9e99e0d3154bbebe3e1b8d11d6c15bde79510a5nd# Unless required by applicable law or agreed to in writing, software
ea5f8cfbb7ef1d19318f6994c26dd73c38ffd8ddjerenkrantz# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
ea5f8cfbb7ef1d19318f6994c26dd73c38ffd8ddjerenkrantz# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
ea5f8cfbb7ef1d19318f6994c26dd73c38ffd8ddjerenkrantz# License for the specific language governing permissions and limitations
4567cfc6a65328bd3e8dd2b758ca926b389c7058brianp# under the License.
f5610d5460e701dd3f3514395867a6b5241fda81bnicholesXSTARTUPHDR = "# WARNING: THIS FILE GENERATED BY SMF.\n" + \
c30ef289fe64ac7fedc44cfcc6b439f0f8458b4cgregames "# DO NOT EDIT THIS FILE. EDITS WILL BE LOST.\n"
c30ef289fe64ac7fedc44cfcc6b439f0f8458b4cgregamesXRESOURCES = "[[ -f ~/.Xresources ]] && /usr/bin/xrdb -merge ~/.Xresources\n"
c30ef289fe64ac7fedc44cfcc6b439f0f8458b4cgregames# Borderless, Monospsce font, point size 14, white foreground on black
c30ef289fe64ac7fedc44cfcc6b439f0f8458b4cgregames# background are reasonable defaults.
2f408250e9111c4b85b2b4b9b8836e83987efdefstoddardXTERMOPTS = ' -b 0 -fa Monospace -fs 14 -fg white -bg black -title ' + \
2f408250e9111c4b85b2b4b9b8836e83987efdefstoddard '"Zone Console: $ZONENAME"'
d5b7ba26785d7494166d48876362ba30ff30b98awrowe# Port ranges allocated for VNC and X11 sockets.
c1bf42dc465137de1fdb8f3d9d1c3e4d2db5c003brianp# Enclose command in comments to prevent xterm consuming zlogin opts
6646a289c2d4778c8cd43d62b5a1cc966a356f85jerenkrantzZLOGINOPTS = ' -e "/usr/bin/pfexec /usr/sbin/zlogin -C -E $ZONENAME"\n'
6646a289c2d4778c8cd43d62b5a1cc966a356f85jerenkrantzXSTARTUP = XSTARTUPHDR + XRESOURCES + XTERM + XTERMOPTS + ZLOGINOPTS
ad451e2e428a069086d1c18c9e3372f8846ec617wrowe # This is meant to be an on-demand service.
ad451e2e428a069086d1c18c9e3372f8846ec617wrowe # Determine if nova-compute requested enablement of this instance.
367cefc17f8dcfe65651c9c16cb3151589c6cecetrawick # Exit with SMF_EXIT_TEMP_DISABLE if not true.
47d4dfaca60aff6d3c7e591bf593b3961cafcdefminfrin svcprop = subprocess.Popen(cmd, stdout=subprocess.PIPE,
c206205e2475a7a4a192eaa7190a9894f01f0631minfrin print "Error reading 'vnc/nova-enabled' property: " + err
ad877cddc14be8c8171938ba61338c6c7b896bbdtrawick vnc_listenip = novacfg.get("DEFAULT", "vncserver_listen")
367cefc17f8dcfe65651c9c16cb3151589c6cecetrawick with lock_available_port(vnc_listenip, VNCPORT_START, VNCPORT_END,
f49cf8ce86a01c90d5d843fc27e19d2802dd0f77wrowe # NOTE: 'geometry' is that which matches the size of standard
f49cf8ce86a01c90d5d843fc27e19d2802dd0f77wrowe # 80 character undecorated xterm window using font style specified
f49cf8ce86a01c90d5d843fc27e19d2802dd0f77wrowe # in XTERMOPTS. The geometry doesn't matter too much because the
f49cf8ce86a01c90d5d843fc27e19d2802dd0f77wrowe # display will be resized using xrandr once the xterm geometry is
f49cf8ce86a01c90d5d843fc27e19d2802dd0f77wrowe # established.
52435ceaabd1670b2c3a062acc191159a64fb7a1wrowe print "Using X11 server port: %d, display %s" % (x11port, display)
ad451e2e428a069086d1c18c9e3372f8846ec617wrowe # set SMF instance port num prop
ad451e2e428a069086d1c18c9e3372f8846ec617wrowe cmd = [SVCCFG, '-s', fmri, 'setprop', 'vnc/port', '=', 'integer:',
ad451e2e428a069086d1c18c9e3372f8846ec617wrowe svccfg = subprocess.Popen(cmd, stdout=subprocess.PIPE,
c998c5be82bf2b41f8fc27de9376ba10651c74bcrederpj # first kill the SMF contract
58eb8d7cca552570577aa8b636349a695ff193datrawick subprocess.check_call(["/usr/bin/pkill", "-c", sys.argv[2]])
58eb8d7cca552570577aa8b636349a695ff193datrawick # 1 is returncode if no SMF contract processes were matched,
58eb8d7cca552570577aa8b636349a695ff193datrawick # meaning they have already terminated.
480f2a1b2fb27a8284e66e60a5bbaee6bc1ccb04trawick # reset port num prop to initial zero value
480f2a1b2fb27a8284e66e60a5bbaee6bc1ccb04trawick cmd = [SVCCFG, '-s', fmri, 'setprop', 'vnc/port', '=', 'integer:',
acc9093ae1f3c97acc635bd5b2c7c0969da21183trawick svccfg = subprocess.Popen(cmd, stdout=subprocess.PIPE,
f08574f1098defdf1dc7e7f18a1e3664ee157150rederpj print("VNC console service not available on this compute node. "
f08574f1098defdf1dc7e7f18a1e3664ee157150rederpj print("VNC console service not available on this compute node. "
2213cc395cb461faf7bfeb187ebb61d97cd457efjerenkrantz # Always clobber xstartup
854c7bc4128fa2ad9fdfe0fc307d5ef30bcb5bb9wrowe # stemp tuple = [fd, path]
854c7bc4128fa2ad9fdfe0fc307d5ef30bcb5bb9wrowe """ Try to determine xterm window geometry and resize the Xvnc display
854c7bc4128fa2ad9fdfe0fc307d5ef30bcb5bb9wrowe to match using XRANDR. Treat failure as non-fatal since an
854c7bc4128fa2ad9fdfe0fc307d5ef30bcb5bb9wrowe incorrectly sized console is arguably better than none.
75f8e1cae5ca3a16a7400cdddf604815ab06b5a8rederpj """ Find the xterm xwindow by name/title and extract its geometry
75f8e1cae5ca3a16a7400cdddf604815ab06b5a8rederpj Returns: tuple of window [width, height]
7f481efe04fdc4da7a447c14be62c155cbe00ddbbrianp UninitializedWindowError if window not yet initialized
7f481efe04fdc4da7a447c14be62c155cbe00ddbbrianp UnmappedWindowError if window is not viewable/mapped
9ed34e5219ab3506ccfd2ca58751ce4c81b263a8rederpj cmd = [XWININFO, '-d', display, '-name', windowname]
9ed34e5219ab3506ccfd2ca58751ce4c81b263a8rederpj xwininfo = subprocess.Popen(cmd, stdout=subprocess.PIPE,
23b36269d124e7a6aaa5221891f7ae2ef3eeb158jerenkrantz print "Error finding console xwindow info: " + err
306bd64cf6568149964abdf8ca748a617ed98500gregames # Window is not mapped yet.
766c20b0366e1d0e359e0d9a834669e19a4db3d9trawick # What, no width and height???
766c20b0366e1d0e359e0d9a834669e19a4db3d9trawick print "No window geometry info returned by " + XWINFINFO
1f279dc92a60df9f61bf58468162aab0eef072e4brianp while uninit_count < retries and unmap_count < retries:
2fd0edbd8b2f47a8458322bedd3b82f825faf336trawick print "Discovered xterm geometry: %d x %d" % (width, height)
39021cf8b495cdb94013ca73531ccb32658fb793rederpj print "xterm window not initialized yet. Retrying in %ds" \
39021cf8b495cdb94013ca73531ccb32658fb793rederpj print "xterm window is taking too long to initialize"
fa16f10bc02e46bc5a6c2c2c6371926cd1dbe2edwrowe print "Discovered xterm not mapped yet. Retrying in %ds" \
fa16f10bc02e46bc5a6c2c2c6371926cd1dbe2edwrowe print "Discovered xterm window is taking too long to map"
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim print "Too many failed attempts to discover xterm window geometry"
7b979864a91b52ecebca11d0a9a22e09349e59baminfrin # Generate a mode line for width and height, with a refresh of 60.0Hz
7b0a3bcc0e689305df49f7d4da7abc35aa891862brianp print "Error creating new modeline for VNC display: " + err
a6f48cc01ab8f5377e570c61826dcdfc36741936trawick print "New optimal modeline for Xvnc server: " + modeline
5bd562b1d7da51cb5715899d32bb4c79c54459b0wrowe # Create a new mode for the Xvnc server using the modeline generated by gtf
1c06e98017400874d5ff6ad79f13145ec4589225striker newmode = subprocess.Popen(cmd, stdout=subprocess.PIPE,
99a041314eb3db0b0cca325c9c40d0a6c5fdf04fwrowe print "Error creating new xrandr modeline for VNC display: " + err
99a041314eb3db0b0cca325c9c40d0a6c5fdf04fwrowe # Add the new mode to the default display output
99a041314eb3db0b0cca325c9c40d0a6c5fdf04fwrowe cmd = [XRANDR, '-d', display, '--addmode', 'default', modename]
6e119e632566d69798ce6cf4e714ed374b72914frederpj addmode = subprocess.Popen(cmd, stdout=subprocess.PIPE,
bd120542ebe7e09cdbada5daf4924f4690e5ece3trawick print "Error adding new xrandr modeline for VNC display: " + err
bd120542ebe7e09cdbada5daf4924f4690e5ece3trawick # Activate the new mode on the default display output
bd120542ebe7e09cdbada5daf4924f4690e5ece3trawick cmd = [XRANDR, '-d', display, '--output', 'default', '--mode', modename]
68d439bc0482b2e41053480f748edc2574c2ea7btrawick addmode = subprocess.Popen(cmd, stdout=subprocess.PIPE,
dddbde8480d265d06c84f2281f01e00f8ef52e94mjc print "Error setting new xrandr modeline for VNC display: " + err
e06675c51d084791089d79c3ac18aeae8dd465fcrbbdef lock_available_port(address, port_start, port_end, lockdir):
e06675c51d084791089d79c3ac18aeae8dd465fcrbb """Ensures instance exclusive use of VNC, X11 service ports
481c1206b6065a8f37ab75ca1fc26c947cb37852ianh and related resources.
481c1206b6065a8f37ab75ca1fc26c947cb37852ianh Generator yields an integer of the port relative to port_start to use.
481c1206b6065a8f37ab75ca1fc26c947cb37852ianh eg. 32: VNC port 5932, X11 port 6032, X11 display :32
a964f7434f5c7f512a5fa0d0178260ccb74c84berbb lockfile is port specific and prevents multiple instances from
a964f7434f5c7f512a5fa0d0178260ccb74c84berbb attempting to use the same port number during SMF start method
a964f7434f5c7f512a5fa0d0178260ccb74c84berbb execution.
a964f7434f5c7f512a5fa0d0178260ccb74c84berbb Socket binding on address:port establishes that the port is not
6a7877447bcb8e6ff848d72f82f184c404ef4c0bminfrin already in use by another Xvnc process
9335cbd541cca1ca6038af329bbd1645310aabccminfrin lockfile = os.path.join(lockdir, '.port-%d.lock' % vncport)
9335cbd541cca1ca6038af329bbd1645310aabccminfrin # Acquire port file lock first to lock out other instances trying
9335cbd541cca1ca6038af329bbd1645310aabccminfrin # to come online in parallel. They will grab the next available
9335cbd541cca1ca6038af329bbd1645310aabccminfrin # port lock.
e156db58351d1c040bc72430f3eb072cb6ae7107brianp # Check the VNC/RFB and X11 ports.
1c06e98017400874d5ff6ad79f13145ec4589225striker sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
7639aa8b39e0d9dbd096f9cc3379bcd3d5e4003bstriker # Ensure the standard X11 locking files are not present
8dc5aa056a586ffa920a6ecd5c31048702371ea6brianp # /tmp/.X<n>-lock
4c9d27bfdfea41b388dc705f7cc2b49318ab5344jim '/tmp/X11-unix/X%d' % n]
e8e8ab3cbc3d90f15eb78e094c381a6e908fd6efjerenkrantz print ("Warning: X11 display :{0} is taken because of "
7e31ef4870c7ef94838585004405e8854fefcc51ianh # Yay, we found a free VNC/X11 port pair.
bd496a3a7752a55c849e62ed00cacc492d4f6d3erederpj print "Port %d already reserved, skipping" % vncport