#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import pwd
import time
XSTARTUPHDR = "# WARNING: THIS FILE GENERATED BY SMF.\n" + \
"# DO NOT EDIT THIS FILE. EDITS WILL BE LOST.\n"
XRESOURCES = "[[ -f ~/.Xresources ]] && /usr/bin/xrdb -merge ~/.Xresources\n"
# Borderless, Monospsce font, point size 14, white foreground on black
# background are reasonable defaults.
XTERMOPTS = ' -b 0 -fa Monospace -fs 14 -fg white -bg black -title ' + \
'"Zone Console: $ZONENAME"'
# Port ranges allocated for VNC and X11 sockets.
VNCPORT_START = 5900
VNCPORT_END = 5999
X11PORT_START = 6000
# Enclose command in comments to prevent xterm consuming zlogin opts
# This is meant to be an on-demand service.
# Determine if nova-compute requested enablement of this instance.
# Exit with SMF_EXIT_TEMP_DISABLE if not true.
if retcode != 0:
print "Error reading 'vnc/nova-enabled' property: " + err
"nova_enabled",
"nova-compute starts this service on demand")
try:
try:
# NOTE: 'geometry' is that which matches the size of standard
# 80 character undecorated xterm window using font style specified
# in XTERMOPTS. The geometry doesn't matter too much because the
# display will be resized using xrandr once the xterm geometry is
# established.
display = ":%d" % n
"-SecurityTypes=None", "-geometry", "964x580",
vncport = VNCPORT_START + n
x11port = X11PORT_START + n
if vncret != 0:
print "Error starting VNC server: " + err
print e
# set SMF instance port num prop
if retcode != 0:
return smf_include.SMF_EXIT_OK
def stop():
try:
# first kill the SMF contract
# 1 is returncode if no SMF contract processes were matched,
# meaning they have already terminated.
if cpe.returncode != 1:
print "failed to kill the SMF contract: %s" % cpe
try:
# reset port num prop to initial zero value
'0']
if retcode != 0:
print e
print("VNC console service not available on this compute node. "
% VNCSERVER)
print("VNC console service not available on this compute node. "
% XTERM)
try:
if ose.errno != errno.EEXIST:
# Always clobber xstartup
# stemp tuple = [fd, path]
os.rename(stemp[1], xstartup_path)
""" Try to determine xterm window geometry and resize the Xvnc display
to match using XRANDR. Treat failure as non-fatal since an
incorrectly sized console is arguably better than none.
"""
Returns: tuple of window [width, height]
Raises:
UninitializedWindowError if window not yet initialized
"""
if retcode != 0:
print "Error finding console xwindow info: " + err
# Window is not mapped yet.
else:
else:
# What, no width and height???
print "No window geometry info returned by " + XWINFINFO
retries = 10
sleep = 1
uninit_count = 0
unmap_count = 0
width = 0
height = 0
try:
break
if uninit_count < retries:
print "xterm window not initialized yet. Retrying in %ds" \
% sleep
uninit_count += 1
continue
else:
print "xterm window is taking too long to initialize"
break
if unmap_count < retries:
print "Discovered xterm not mapped yet. Retrying in %ds" \
% sleep
unmap_count += 1
continue
else:
print "Discovered xterm window is taking too long to map"
break
else:
print "Too many failed attempts to discover xterm window geometry"
return
# Generate a mode line for width and height, with a refresh of 60.0Hz
if retcode != 0:
print "Error creating new modeline for VNC display: " + err
return
print "New optimal modeline for Xvnc server: " + modeline
break
# Create a new mode for the Xvnc server using the modeline generated by gtf
if retcode != 0:
print "Error creating new xrandr modeline for VNC display: " + err
return
# Add the new mode to the default display output
if retcode != 0:
print "Error adding new xrandr modeline for VNC display: " + err
return
# Activate the new mode on the default display output
if retcode != 0:
print "Error setting new xrandr modeline for VNC display: " + err
return
"""Ensures instance exclusive use of VNC, X11 service ports
and related resources.
Generator yields an integer of the port relative to port_start to use.
eg. 32: VNC port 5932, X11 port 6032, X11 display :32
lockfile is port specific and prevents multiple instances from
attempting to use the same port number during SMF start method
execution.
Socket binding on address:port establishes that the port is not
already in use by another Xvnc process
"""
vncport = port_start + n
x11port = X11PORT_START + n
try:
# Acquire port file lock first to lock out other instances trying
# to come online in parallel. They will grab the next available
# port lock.
try:
try:
# Ensure the standard X11 locking files are not present
# /tmp/.X<n>-lock
xfiles = ['/tmp/.X%d-lock' % n,
if os.path.exists(xfile):
print ("Warning: X11 display :{0} is taken because of "
"{1}\nRemove this file if there is no X "
continue
yield n
break
print "Port %d already reserved, skipping" % vncport
if __name__ == "__main__":