zone-vnc-console revision 3809
2810N/A#!/usr/bin/python2.6
2810N/A
2810N/Aimport errno
2810N/Aimport os
2810N/Aimport pwd
2810N/Aimport smf_include
2810N/Aimport subprocess
2810N/Aimport sys
2810N/A
2810N/Afrom subprocess import CalledProcessError, check_call, Popen
2810N/Afrom tempfile import mkstemp
2810N/A
2810N/ASVCCFG = "/usr/sbin/svccfg"
2810N/ASVCPROP = "/usr/bin/svcprop"
2810N/AVNCSERVER = "/usr/bin/vncserver"
2810N/AXSTARTUPHDR = "# WARNING: THIS FILE GENERATED BY SMF.\n" + \
2810N/A "# DO NOT EDIT THIS FILE. EDITS WILL BE LOST.\n"
2810N/AXTERM = "/usr/bin/xterm"
2810N/A# Monospsce font, point size 15, white foreground on black background"
2810N/AXTERMOPTS = ' -fa Monospace -fs 15 -fg white -bg black'
2810N/A# Enclose command in comments to prevent xterm consuming zlogin opts
2810N/AZLOGINOPTS = ' -e "/usr/bin/pfexec /usr/sbin/zlogin -C -E $ZONENAME"\n'
2810N/AXSTARTUP = XSTARTUPHDR + XTERM + XTERMOPTS + ZLOGINOPTS
2810N/A
2810N/A
2810N/Adef start():
2810N/A check_vncserver()
2810N/A homedir = os.environ.get('HOME')
2810N/A if not homedir:
2810N/A homedir = pwd.getpwuid(os.getuid()).pw_dir
2810N/A os.putenv("HOME", homedir)
2810N/A set_xstartup(homedir)
2810N/A
2810N/A try:
2810N/A fmri = os.environ['SMF_FMRI']
2810N/A zonename = fmri.rsplit(':', 1)[1]
2810N/A os.putenv("ZONENAME", zonename)
2810N/A desktop_name = zonename + ' console'
2810N/A # NOTE: 'geometry' below is that which matches the size of standard
2810N/A # 80 character undecorated xterm window using font style specified in
2810N/A # XTERMOPTS. Update this geometry whenever XTERMOPTS are changed.
2810N/A # Avoids exposing X root window within noVNC canvas widget.
2810N/A cmd = [VNCSERVER, "-name", desktop_name, "-SecurityTypes=None",
2810N/A "-geometry", "964x580", "-localhost", "-autokill"]
2810N/A vnc = Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
2810N/A env=None)
2810N/A out, err = vnc.communicate()
2810N/A vncret = vnc.wait()
2810N/A if vncret != 0:
2810N/A print "Error starting VNC server: " + err
2810N/A return smf_include.SMF_EXIT_ERR_FATAL
2810N/A except Exception as e:
2810N/A print e
2810N/A return smf_include.SMF_EXIT_ERR_FATAL
2810N/A
2810N/A output = err.splitlines()
2810N/A for line in output:
2810N/A if line.startswith("New '%s' desktop is" % desktop_name):
2810N/A display = line.rpartition(' ')[2]
2810N/A host, display_num = display.split(':', 1)
2810N/A # set host prop
2810N/A port = 5900 + int(display_num)
2810N/A print "VNC port: %d" % port
2810N/A # set port num prop
2810N/A cmd = [SVCCFG, '-s', fmri, 'setprop', 'vnc/port', '=', 'integer:',
2810N/A str(port)]
2810N/A
2810N/A svccfg = subprocess.Popen(cmd, stdout=subprocess.PIPE,
2810N/A stderr=subprocess.PIPE)
2810N/A out, err = svccfg.communicate()
2810N/A retcode = svccfg.wait()
if retcode != 0:
print "Error updating 'vnc/port' property: " + err
return smf_include.SMF_EXIT_ERR_FATAL
return smf_include.SMF_EXIT_OK
def stop():
try:
# first kill the SMF contract
check_call(["/usr/bin/pkill", "-c", sys.argv[2]])
except CalledProcessError as cpe:
# 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
return smf_include.SMF_EXIT_ERR_FATAL
try:
fmri = os.environ['SMF_FMRI']
# reset port num prop to initial zero value
cmd = [SVCCFG, '-s', fmri, 'setprop', 'vnc/port', '=', 'integer:',
'0']
svccfg = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,)
out, err = svccfg.communicate()
retcode = svccfg.wait()
if retcode != 0:
print "Error resetting 'vnc/port' property: " + err
return smf_include.SMF_EXIT_ERR_FATAL
except Exception as e:
print e
return smf_include.SMF_EXIT_ERR_FATAL
def check_vncserver():
if not os.path.exists(VNCSERVER):
print("VNC console service not available on this compute node. "
"%s is missing. Run 'pkg install x11/server/xvnc'"
% VNCSERVER)
return smf_include.SMF_EXIT_ERR_FATAL
if not os.path.exists(XTERM):
print("VNC console service not available on this compute node. "
"%s is missing. Run 'pkg install terminal/xterm'"
% XTERM)
return smf_include.SMF_EXIT_ERR_FATAL
def set_xstartup(homedir):
vncdir = os.path.join(homedir, '.vnc')
xstartup_path = os.path.join(vncdir, 'xstartup')
try:
os.mkdir(vncdir)
except OSError as ose:
if ose.errno != errno.EEXIST:
raise
# Always clobber xstartup
# stemp tuple = [fd, path]
stemp = mkstemp(dir=vncdir)
os.write(stemp[0], XSTARTUP)
os.close(stemp[0])
os.chmod(stemp[1], 0700)
os.rename(stemp[1], xstartup_path)
if __name__ == "__main__":
os.putenv("LC_ALL", "C")
smf_include.smf_main()