ubuntu-22.04.3-desktop-amd64/casper/filesystem/usr/bin/ubiquity-dm

885 lines
34 KiB
Python
Executable File

#!/usr/bin/python3
import errno
import getpass
import grp
import os
import pwd
import signal
import subprocess
import sys
import sysconfig
import traceback
import time
import debconf
import PAM
sys.path.insert(0, '/usr/lib/ubiquity')
from ubiquity import gsettings, osextras
from ubiquity.casper import get_casper
from ubiquity.debconfcommunicator import DebconfCommunicator
from ubiquity.misc import create_bool, utf8
logfile = None
def log(msg):
print('ubiquity-dm: ' + msg, file=logfile, flush=True)
def _pam_conv(auth, query_list, userData):
resp = []
for query, type in query_list:
if type == PAM.PAM_PROMPT_ECHO_ON:
val = input(query)
resp.append((val, 0))
elif type == PAM.PAM_PROMPT_ECHO_OFF:
val = getpass.getpass(query)
resp.append((val, 0))
elif type in (PAM.PAM_PROMPT_ERROR_MSG, PAM.PAM_PROMPT_TEXT_INFO):
print(query)
resp.append(('', 0))
else:
return None
return resp
def set_locale():
db = DebconfCommunicator('ubiquity', cloexec=True)
locale = ''
try:
locale = db.get('debian-installer/locale')
except debconf.DebconfError:
pass
db.shutdown()
if not locale:
return
with open('/etc/default/locale', 'w') as default_locale:
print('LANG="%s"' % locale, file=default_locale)
with open('/etc/environment') as environment:
environment_lines = environment.readlines()
with open('/etc/environment', 'w') as environment:
seen_lang = False
for line in environment_lines:
if line.startswith('LANG='):
print('LANG="%s"' % locale, file=environment)
seen_lang = True
else:
print(line.rstrip('\n'), file=environment)
if not seen_lang:
print('LANG="%s"' % locale, file=environment)
with open('/etc/locale.gen', 'w') as locale_gen:
print('%s UTF-8' % locale, file=locale_gen)
subprocess.call(['/usr/sbin/locale-gen', locale],
stdout=logfile, stderr=logfile)
def add_ubiquity_kdedir():
os.environ['KDEDIRS'] = '/usr/share/ubiquity/qt:' + \
os.environ.get('KDEDIRS', '')
class XStartupError(EnvironmentError):
pass
class MissingProgramError(EnvironmentError):
pass
class SignalWatcher:
def __init__(self, owner, program,
interface, object_path,
signal, expected):
self.owner = owner
self.program = program
self.connection = None
self.interface = interface
self.object_path = object_path
self.signal = signal
self.expected = expected
self.processes = []
from gi.repository import GLib, Gio
owner.drop_privileges()
self.loop = GLib.MainLoop()
Gio.bus_get(Gio.BusType.SESSION, None,
self.on_got_bus, None)
def signal_timeout(self, user_data):
log("SignalWatcher: signal timed out, continuing with ubiquity-dm")
self.loop.quit()
def on_got_bus(self, source, result, user_data):
try:
from gi.repository import GLib, Gio
self.connection = Gio.bus_get_finish(result)
self.connection.signal_subscribe(None, self.interface,
self.signal,
self.object_path, None,
Gio.DBusSignalFlags.NONE,
self.on_signal, None)
self.processes.append(subprocess.Popen(
[self.program],
stdin=None, stdout=logfile, stderr=logfile))
self.owner.regain_privileges()
GLib.timeout_add_seconds(5, self.signal_timeout, None)
except Exception:
log("failed to ensure xsettings plugin was started:")
log(traceback.format_exc())
self.loop.quit()
def on_signal(self, connection, sender, path, interface, signal, params,
user_data):
(plugin, ) = params
# log ('on_signal: got %s' % plugin)
if plugin == "xsettings":
self.loop.quit()
def run(self):
self.loop.run()
return self.processes
class DM:
def __init__(self, vt, display, default_username):
self.auth = PAM.pam()
self.vt = vt
self.display = display
self.server_started = False
self.username = get_casper('USERNAME', default_username)
try:
self.uid, self.gid = pwd.getpwnam(self.username)[2:4]
except KeyError:
import syslog
syslog.syslog('Could not find %s, falling back to root.' %
self.username)
self.username = 'root'
self.uid, self.gid = 0, 0
self.homedir = pwd.getpwnam(self.username)[5]
self.uid = int(self.uid)
self.gid = int(self.gid)
self.groups = []
for g in grp.getgrall():
if self.username in g[3] or g[0] == self.username:
self.groups.append(g[2])
# Look for a frontend module; we won't actually use it (yet), but
# this lets us find out which window manager etc. to launch. Be
# careful that importing this here will cause the underlying library
# to try to talk to the X server, which won't go well.
from importlib import util
frontend_names = ['gtk_ui', 'kde_ui']
self.frontend = None
for f in frontend_names:
if util.find_spec('ubiquity.frontend.%s' % f) is not None:
self.frontend = f
break
if self.frontend is None:
raise AttributeError('No frontend available; tried %s' %
', '.join(frontend_names))
db = DebconfCommunicator('ubiquity', cloexec=True)
try:
self.force_failsafe = create_bool(
db.get('ubiquity/force_failsafe_graphics'))
except debconf.DebconfError:
self.force_failsafe = False
db.shutdown()
def sigusr1_handler(self, signum, frame):
self.server_started = True
def active_vt(self):
import fcntl
import array
console = os.open('/dev/tty0', os.O_RDONLY | os.O_NOCTTY)
try:
VT_GETSTATE = 0x5603
vt_stat = array.array('H', [0, 0, 0])
fcntl.ioctl(console, VT_GETSTATE, vt_stat)
return vt_stat[0]
finally:
os.close(console)
def drop_privileges(self):
os.setgroups(self.groups)
os.setresgid(self.gid, self.gid, 0)
os.setresuid(self.uid, self.uid, 0)
def regain_privileges(self):
os.setresuid(0, 0, 0)
os.setresgid(0, 0, 0)
os.setgroups([])
def server_preexec(self):
signal.signal(signal.SIGUSR1, signal.SIG_IGN)
def run_hooks(self, hookdir):
if os.path.isdir(hookdir):
# Exclude hooks containing '.', so that *.dpkg-* et al are avoided.
hooks = [entry for entry in os.listdir(hookdir)
if '.' not in entry]
for hookentry in hooks:
hook = os.path.join(hookdir, hookentry)
subprocess.call(
hook, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges)
def pam_open_session(self):
self.auth.start('su')
self.auth.set_item(PAM.PAM_USER, self.username)
self.auth.set_item(PAM.PAM_CONV, _pam_conv)
self.auth.putenv('XDG_SESSION_CLASS=greeter')
self.auth.putenv('XDG_SEAT=seat0')
# at the time pam_open_session is called self.vt is the
# correct vt: either the one originally passed as cmd line
# arg or as determined by active_vt()
#
# self.vt is of the form str("vt10")
self.auth.putenv('XDG_VTNR=%s' % self.vt[2:])
self.auth.authenticate()
self.auth.open_session()
os.environ.update(
[i.split('=', 1) for i in self.auth.getenvlist()])
def pam_close_session(self):
if self.auth:
self.auth.close_session()
self.auth = None
def run(self, *program):
# Extract the program basename to see if we are in oem-config or
# ubiquity.
program_basename = os.path.basename(program[0])
extras = []
null = open('/dev/null', 'w')
log('starting')
signal.signal(signal.SIGUSR1, self.sigusr1_handler)
signal.signal(signal.SIGTTIN, signal.SIG_IGN)
signal.signal(signal.SIGTTOU, signal.SIG_IGN)
servercommand = ['X', '-br', '-ac', '-noreset', '-nolisten', 'tcp']
log('plymouth')
try:
plymouth_running = subprocess.call(['plymouth', '--ping']) == 0
except OSError:
plymouth_running = False
if plymouth_running:
subprocess.call(['plymouth', 'deactivate'])
if subprocess.call(['plymouth', '--has-active-vt']) == 0:
self.vt = 'vt%d' % self.active_vt()
servercommand.extend(['-background', 'none'])
else:
subprocess.call(['plymouth', 'quit'])
plymouth_running = False
servercommand.extend([self.vt, self.display])
log('start X {}'.format(servercommand))
for attempt in ('main', 'fbdev', 'vesa'):
command = list(servercommand)
if attempt == 'main' and self.force_failsafe:
continue
elif attempt != 'main':
# TODO cjwatson 2010-02-11: This is a bodge. The
# duplication is nasty, but fortunately bullet-proof X
# actually turns out not to be very complicated nowadays.
# Most of the complexity is in the fallback session, which I
# haven't attempted to integrate here, so you won't get
# things like interactive reconfiguration. I believe Evan
# is working on doing that, but is blocked on a couple of
# Upstart bugs; once all that's resolved, we should back
# this out.
if attempt == 'fbdev' and not os.path.exists('/dev/fb0'):
continue
xorg_conf_failsafe = '/etc/X11/xorg.conf.failsafe'
command.extend(['-config', xorg_conf_failsafe])
command.extend(['-logfile', '/var/log/Xorg.%s.log' % attempt])
with open(xorg_conf_failsafe, 'w') as xorg_conf_failsafe_file:
print('''\
Section "Device"
\tIdentifier "Configured Video Device"
\tDriver "%s"
EndSection
Section "Monitor"
\tIdentifier "Configured Monitor"
EndSection
Section "Screen"
\tIdentifier "Default Screen"
\tMonitor "Configured Monitor"
\tDevice "Configured Video Device"
EndSection
''' % attempt, file=xorg_conf_failsafe_file)
server = subprocess.Popen(
command, stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.server_preexec)
# Really we should select on a pipe or something, but it's not
# worth the effort for now.
try:
timeout = 60
while not self.server_started:
status = server.poll()
if type(status) is int and status != 0:
if plymouth_running:
subprocess.call(['plymouth', 'quit'])
raise XStartupError('X server exited with return '
'code ' + str(status))
if timeout == 0:
if plymouth_running:
subprocess.call(['plymouth', 'quit'])
raise XStartupError('X server failed to start after 60'
' seconds')
time.sleep(1)
timeout -= 1
if plymouth_running:
subprocess.call(['plymouth', 'quit', '--retain-splash'])
except XStartupError:
if attempt == 'vesa':
raise
if self.server_started:
break
log('set vars')
os.environ['DISPLAY'] = self.display
os.environ['HOME'] = self.homedir
# Give ubiquity a UID and GID that it can drop privileges to.
os.environ['PKEXEC_UID'] = str(self.uid)
os.environ['GVFS_DISABLE_FUSE'] = '1'
log('pam_open_session')
self.pam_open_session()
# run simple, custom scripts during install time
if program_basename == 'ubiquity':
log('dm-scripts')
self.run_hooks('/usr/lib/ubiquity/dm-scripts/install')
# run simple, custom scripts during oem-config
if program_basename == 'oem-config-wrapper':
log('oem dm-scripts')
self.run_hooks('/usr/lib/ubiquity/dm-scripts/oem')
# Session bus, apparently needed by most interfaces now
if ('DBUS_SESSION_BUS_ADDRESS' not in os.environ and
osextras.find_on_path('dbus-launch')):
log('dbus')
dbus_subp = subprocess.Popen(
['dbus-launch', '--exit-with-session'],
stdin=null, stdout=subprocess.PIPE, stderr=logfile,
preexec_fn=self.drop_privileges, universal_newlines=True)
for line in dbus_subp.stdout:
try:
name, value = line.rstrip('\n').split('=', 1)
os.environ[name] = value
except ValueError:
pass
dbus_subp.stdout.close()
dbus_subp.wait()
# dconf writer
if os.path.exists("/usr/lib/dconf/dconf-service"):
log('dconf-service')
extras.append(subprocess.Popen(
['/usr/lib/dconf/dconf-service'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
if osextras.find_on_path("dbus-update-activation-environment"):
subprocess.Popen(
[
"dbus-update-activation-environment",
"--verbose",
"--systemd",
"DISPLAY",
],
stdin=null,
stdout=logfile,
stderr=logfile,
preexec_fn=self.drop_privileges,
)
# Accessibility infrastructure
proc_cmdline = []
with open('/proc/cmdline', 'r') as fp:
proc_cmdline = fp.readline().split()
log('start frontend {}'.format(self.frontend))
if self.frontend == 'gtk_ui':
# Set a desktop wallpaper.
visual_a11y = 'access=v' in proc_cmdline
background_image = None
for background in (
'/usr/share/xfce4/backdrops/xubuntu-wallpaper.png',
'/usr/share/backgrounds/'
'ubuntustudio/ubuntustudio-default.png',
'/usr/share/lubuntu/wallpapers/'
'lubuntu-default-wallpaper.png'):
exists = os.access(background, os.R_OK)
if exists:
background_image = background
break
accessibility = False
if gsettings._gsettings_exists():
accessibility = gsettings.get(
'org.gnome.desktop.interface', 'toolkit-accessibility',
self.username)
# Set gsettings keys
gsettings_keys = [
('org.gnome.desktop.lockdown', 'disable-lock-screen',
'true'),
('org.gnome.desktop.lockdown', 'disable-user-switching',
'true'),
('org.gnome.settings-daemon.plugins.background', 'active',
'true'),
('org.gnome.desktop.background', 'draw-background',
'true'),
('org.gnome.desktop.background', 'show-desktop-icons',
'false'),
('org.gnome.metacity', 'compositing-manager',
'true'),
('org.gnome.desktop.wm.preferences', 'num-workspaces',
'1'),
]
# Setting a wallpaper image, or solid color.
if visual_a11y:
gsettings_keys.append(
('org.gnome.desktop.background', 'picture-options',
'none'))
gsettings_keys.append(
('org.gnome.desktop.background', 'picture-uri',
"''"))
if osextras.find_on_path('marco'):
gsettings_keys = [
('org.mate.lockdown', 'disable-lock-screen',
'true'),
('org.mate.lockdown', 'disable-user-switching',
'true'),
('org.mate.SettingsDaemon.plugins.background',
'active', 'true'),
('org.mate.background', 'draw-background',
'true'),
('org.mate.background', 'show-desktop-icons',
'false'),
('org.mate.Marco.general', 'compositing-manager',
'true'),
('org.mate.Marco.general', 'num-workspaces',
'1'),
]
# Setting a wallpaper image, or solid color.
if visual_a11y:
gsettings_keys.append(
('org.mate.background', 'picture-options',
'none'))
gsettings_keys.append(
('org.mate.background', 'picture-filename',
"''"))
if (osextras.find_on_path('gnome-shell') or
osextras.find_on_path('budgie-wm')):
gsettings_keys.append(
('org.gnome.settings-daemon.plugins.background',
'active', 'false'))
gsettings_keys.remove(
('org.gnome.desktop.wm.preferences', 'num-workspaces',
'1'))
os.environ['XDG_SESSION_TYPE'] = 'x11'
if (osextras.find_on_path('gnome-shell')):
# set this environment variable since we have
# session-specific GSettings overrides for Ubuntu/Shell,
# like the theme.
os.environ['XDG_CURRENT_DESKTOP'] = 'ubuntu:GNOME'
if (osextras.find_on_path(
'dbus-update-activation-environment')):
subprocess.Popen(
['dbus-update-activation-environment',
'--verbose', '--systemd', 'XDG_CURRENT_DESKTOP'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges)
if (osextras.find_on_path('budgie-wm')):
gsettings_keys.append(
('org.gnome.desktop.interface', 'icon-theme',
"'ubuntu-mono-dark'"))
os.environ['XDG_CURRENT_DESKTOP'] = 'Budgie'
for gs_schema, gs_key, gs_value in gsettings_keys:
subprocess.call(
['gsettings', 'set', gs_schema, gs_key, gs_value],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges)
msd = '/usr/bin/mate-settings-daemon'
usd = '/usr/lib/unity-settings-daemon/unity-settings-daemon'
gsd = ['/usr/libexec/gsd-a11y-keyboard',
'/usr/libexec/gsd-a11y-settings',
'/usr/libexec/gsd-clipboard',
'/usr/libexec/gsd-keyboard',
'/usr/libexec/gsd-media-keys',
'/usr/libexec/gsd-power',
'/usr/libexec/gsd-xsettings']
if osextras.find_on_path(msd):
extras.append(subprocess.Popen(
[msd], stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
elif (osextras.find_on_path(usd)):
# Wait until xsettings plugin is activated
xsettings = SignalWatcher(self, usd,
"org.gnome.SettingsDaemon",
"/org/gnome/SettingsDaemon",
"PluginActivated",
"xsettings")
# the SignalWatcher will run until the signal is seen...
extras.extend(xsettings.run())
# At this point we're sure the usd xsettings plugin is
# available, we can continue setting up the session.
elif (osextras.find_on_path('gnome-shell') or
osextras.find_on_path('budgie-wm')):
for gsdbinary in gsd:
if os.path.exists(gsdbinary):
extras.append(subprocess.Popen(
[gsdbinary],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
elif background_image and osextras.find_on_path('feh'):
subprocess.call(
['feh', '--bg-fill', background_image],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges)
if (accessibility or 'maybe-ubiquity' in proc_cmdline or
'only-ubiquity' in proc_cmdline or
program_basename == 'oem-config-wrapper'):
launcher = '/usr/lib/at-spi2-core/at-spi-bus-launcher'
if os.path.exists(launcher):
extras.append(subprocess.Popen(
[launcher, '--launch-immediately'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
try:
os.environ['GTK_MODULES'] += os.pathsep + 'gail'
except KeyError:
os.environ['GTK_MODULES'] = 'gail'
if osextras.find_on_path('gnome-shell'):
wm_cmd = ['gnome-shell', '--sm-disable', '--mode=ubiquity']
elif osextras.find_on_path('budgie-wm'):
wm_cmd = ['budgie-wm', '--sm-disable']
elif osextras.find_on_path('marco'):
wm_cmd = ['marco', '--sm-disable']
elif osextras.find_on_path('metacity'):
wm_cmd = ['metacity', '--sm-disable']
elif osextras.find_on_path('xfwm4'):
wm_cmd = ['xfwm4', '--compositor=off', '--sm-client-disable']
elif osextras.find_on_path('matchbox-window-manager'):
wm_cmd = ['matchbox-window-manager']
elif osextras.find_on_path('openbox-lubuntu'):
wm_cmd = ['openbox-lubuntu']
elif osextras.find_on_path('openbox'):
wm_cmd = ['openbox']
elif osextras.find_on_path('compiz'):
wm_cmd = ['compiz', '--sm-disable', 'decor', 'resize', 'place',
'move']
else:
raise MissingProgramError(
'No window manager found (tried '
'gnome-shell, budgie-wm, marco, metacity, xfwm4, '
'matchbox-window-manager, openbox-lubuntu, '
'openbox, compiz)')
wm = subprocess.Popen(
wm_cmd, stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges)
if osextras.find_on_path('xfsettingsd'):
extras.append(subprocess.Popen(
['xprop', '-root', '-format', '_NET_NUMBER_OF_DESKTOPS',
'32c', '-set', '_NET_NUMBER_OF_DESKTOPS', '1'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
extras.append(subprocess.Popen(
['xfsettingsd', '--sm-client-disable'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
if osextras.find_on_path('lxsession'):
extras.append(subprocess.Popen(
['lxsession', '-s', 'Lubuntu', '-e', 'LXDE', '-a'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
if os.path.exists('/usr/lib/ubiquity/panel'):
if ("openbox-lubuntu" not in wm_cmd and
"openbox" not in wm_cmd and
"gnome-shell" not in wm_cmd and
"xfwm4" not in wm_cmd):
multiarchdir = os.path.split(
sysconfig.get_config_var('multiarchsubdir'))[-1]
indicators = list(filter(os.path.isfile, [
os.path.join('/usr/lib', multiarchdir, i) for i in (
'indicator-application/'
'indicator-application-service',
'indicator-session/indicator-session-service',
'indicator-sound/indicator-sound-service',
'indicator-bluetooth/indicator-bluetooth-service',
'indicator-keyboard/indicator-keyboard-service',
'indicator-keyboard-service',
'indicator-power/indicator-power-service',
)]))
extras.append(subprocess.Popen(
['/usr/lib/ubiquity/panel'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
for indicator in indicators:
extras.append(subprocess.Popen(
[indicator],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
if (osextras.find_on_path('nm-applet') and
"gnome-shell" not in wm_cmd):
extras.append(subprocess.Popen(
['nm-applet'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
if (osextras.find_on_path('ibus-daemon') and
"gnome-shell" not in wm_cmd):
extras.append(subprocess.Popen(
['ibus-daemon'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
# Simply start bluetooth-applet, ubiquity-bluetooth-agent will
# override it from casper to make sure it also covers the regular
# live session
if osextras.find_on_path('bluetooth-applet'):
extras.append(subprocess.Popen(
['bluetooth-applet'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
# Accessibility tools
if accessibility:
# FIXME: launch onboard, when touch screen detected
if 'access=m2' in proc_cmdline:
if osextras.find_on_path('onboard'):
extras.append(subprocess.Popen(
['onboard'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
else:
if osextras.find_on_path('orca'):
time.sleep(15)
extras.append(subprocess.Popen(
['orca'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
elif self.frontend == 'kde_ui':
# Force Qt5 KDE theming to load for kwin and friends.
os.environ["QT_QPA_PLATFORMTHEME"] = "kde"
if 'access=v1' not in proc_cmdline:
log('paint background')
path = \
'/usr/share/wallpapers/Next/contents/images/2560x1600.jpg'
extras.append(subprocess.Popen(
['ubiquity-qtsetbg', path],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges))
log("add_ubiquity_kdedir")
add_ubiquity_kdedir()
log('start kwin')
if osextras.find_on_path('kwin'):
wm_cmd = ['kwin']
elif osextras.find_on_path('kwin_x11'):
wm_cmd = ['kwin_x11']
wm = subprocess.Popen(
wm_cmd, stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges)
log('start greeter')
greeter = subprocess.Popen(
program, stdin=null, stdout=logfile, stderr=logfile)
ret = greeter.wait()
log('greeter exited with code {}'.format(ret))
reboot = False
if ret != 0:
db = DebconfCommunicator('ubiquity', cloexec=True)
try:
error_cmd = db.get('ubiquity/failure_command')
if error_cmd:
subprocess.call(['sh', '-c', error_cmd])
except debconf.DebconfError:
pass
reboot = False
try:
if '--automatic' in program:
reboot = db.get('ubiquity/reboot_on_failure') == 'true'
except debconf.DebconfError:
pass
if reboot:
question = 'ubiquity/install_failed_reboot'
else:
question = 'ubiquity/install_failed'
title = ''
message = ''
try:
title = utf8(db.metaget(question, 'description'),
errors='replace')
message = utf8(db.metaget(question, 'extended_description'),
errors='replace')
except debconf.DebconfError:
pass
db.shutdown()
if title and message:
if self.frontend == 'gtk_ui':
cmd = ['zenity', '--error', '--title=%s' % title,
'--text=%s' % message]
subprocess.call(cmd)
elif self.frontend == 'kde_ui':
cmd = ['kdialog', '--title=%s' % title,
'--msgbox=%s' % message]
subprocess.call(cmd)
else:
# Not ideal, but if we cannot let the user know what's
# going on, it's best to drop them into a desktop and let
# them figure it out.
reboot = False
# Revert gnome-settings to default, for dropping to desktop
if self.frontend == 'gtk_ui' and gsettings._gsettings_exists():
for gs_schema, gs_key, gs_value in gsettings_keys:
subprocess.call(
['gsettings', 'reset', gs_schema, gs_key],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges)
def kill_if_exists(pid, signum):
try:
os.kill(pid, signum)
except OSError as e:
if e.errno != errno.ESRCH:
raise
def sigalrm_handler(signum, frame):
kill_if_exists(wm.pid, signal.SIGKILL)
for extra in extras:
kill_if_exists(extra.pid, signal.SIGKILL)
kill_if_exists(wm.pid, signal.SIGTERM)
for extra in extras:
kill_if_exists(extra.pid, signal.SIGTERM)
signal.signal(signal.SIGALRM, sigalrm_handler)
signal.alarm(1) # low patience with WMs failing to exit on demand
processes = set(extras)
processes.add(wm)
while processes:
done = set()
for process in processes:
try:
process.wait()
done.add(process)
except OSError as e:
if e.errno == errno.EINTR:
continue
raise
processes -= done
signal.alarm(0)
# Clear the console so we don't see boot-time messages on switch
try:
with open('/dev/tty' + self.vt[2:], 'r+') as vthandle:
subprocess.call(['clear'], stdin=vthandle, stdout=vthandle)
except IOError:
pass
kill_if_exists(server.pid, signal.SIGTERM)
server.wait()
null.close()
if reboot:
subprocess.Popen(['reboot'])
if ret is not None and ret >= 0:
return ret
else:
return 1
def run(vt, display, username):
try:
dm = DM(vt, display, username)
except XStartupError:
log("XStartupError")
return 1
ret = dm.run(*sys.argv[4:])
if ret == 0:
log("set_locale")
set_locale()
dm.pam_close_session()
return ret
def main():
global logfile
if len(sys.argv) < 4:
sys.stderr.write('Usage: %s <vt[1-N]> <:[0-N]> <username> <program> '
'[<arguments>]\n' % sys.argv[0])
return 1
vt, display, username = sys.argv[1:4]
try:
os.makedirs('/var/log/installer')
except OSError as e:
# be happy if someone already created the path
if e.errno != errno.EEXIST:
raise
logfile = open('/var/log/installer/dm', 'w')
try:
ret = run(vt, display, username)
log('Exiting with code {}'.format(ret))
except Exception:
log('Failed with an exception:')
log(traceback.format_exc())
return 1
if __name__ == '__main__':
sys.exit(main())