source: calamares/trunk/fuentes/src/modules/displaymanager/main.py @ 7538

Last change on this file since 7538 was 7538, checked in by kbut, 13 months ago

sync with github

File size: 25.5 KB
Line 
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3#
4# === This file is part of Calamares - <https://github.com/calamares> ===
5#
6#   Copyright 2014-2017, Philip Müller <philm@manjaro.org>
7#   Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
8#   Copyright 2014, Kevin Kofler <kevin.kofler@chello.at>
9#   Copyright 2017, Alf Gaida <agaida@siduction.org>
10#   Copyright 2017, Bernhard Landauer <oberon@manjaro.org>
11#   Copyright 2017, Adriaan de Groot <groot@kde.org>
12#
13#   Calamares is free software: you can redistribute it and/or modify
14#   it under the terms of the GNU General Public License as published by
15#   the Free Software Foundation, either version 3 of the License, or
16#   (at your option) any later version.
17#
18#   Calamares is distributed in the hope that it will be useful,
19#   but WITHOUT ANY WARRANTY; without even the implied warranty of
20#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21#   GNU General Public License for more details.
22#
23#   You should have received a copy of the GNU General Public License
24#   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
25
26import os
27import collections
28import re
29import libcalamares
30import configparser
31
32
33DesktopEnvironment = collections.namedtuple(
34    'DesktopEnvironment', ['executable', 'desktop_file']
35    )
36
37desktop_environments = [
38    DesktopEnvironment('/usr/bin/startkde', 'plasma'),  # KDE Plasma 5
39    DesktopEnvironment('/usr/bin/startkde', 'kde-plasma'),  # KDE Plasma 4
40    DesktopEnvironment('/usr/bin/gnome-session', 'gnome'),
41    DesktopEnvironment('/usr/bin/startxfce4', 'xfce'),
42    DesktopEnvironment('/usr/bin/cinnamon-session-cinnamon', 'cinnamon'),
43    DesktopEnvironment('/usr/bin/mate-session', 'mate'),
44    DesktopEnvironment('/usr/bin/enlightenment_start', 'enlightenment'),
45    DesktopEnvironment('/usr/bin/lxsession', 'LXDE'),
46    DesktopEnvironment('/usr/bin/startlxde', 'LXDE'),
47    DesktopEnvironment('/usr/bin/lxqt-session', 'lxqt'),
48    DesktopEnvironment('/usr/bin/pekwm', 'pekwm'),
49    DesktopEnvironment('/usr/bin/pantheon-session', 'pantheon'),
50    DesktopEnvironment('/usr/bin/budgie-session', 'budgie-session'),
51    DesktopEnvironment('/usr/bin/budgie-desktop', 'budgie-desktop'),
52    DesktopEnvironment('/usr/bin/i3', 'i3'),
53    DesktopEnvironment('/usr/bin/startdde', 'deepin'),
54    DesktopEnvironment('/usr/bin/openbox-session', 'openbox')
55]
56
57
58def find_desktop_environment(root_mount_point):
59    """
60    Checks which desktop environment is currently installed.
61
62    :param root_mount_point:
63    :return:
64    """
65    for desktop_environment in desktop_environments:
66        if (os.path.exists("{!s}{!s}".format(
67                    root_mount_point, desktop_environment.executable
68                    )
69                ) and os.path.exists(
70                    "{!s}/usr/share/xsessions/{!s}.desktop".format(
71                        root_mount_point, desktop_environment.desktop_file
72                    )
73                )):
74            return desktop_environment
75    return None
76
77
78def have_dm(dm_name, root_mount_point):
79    """
80    Checks if display manager is properly installed.
81
82    :param dm_name:
83    :param root_mount_point:
84    :return:
85    """
86    bin_path = "{!s}/usr/bin/{!s}".format(root_mount_point, dm_name)
87    sbin_path = "{!s}/usr/sbin/{!s}".format(root_mount_point, dm_name)
88    return (os.path.exists(bin_path)
89            or os.path.exists(sbin_path)
90            )
91
92
93def set_autologin(username,
94                  displaymanager,
95                  default_desktop_environment,
96                  root_mount_point):
97    """
98    Enables automatic login for the installed desktop managers.
99
100    :param username:
101    :param displaymanager: str
102        The displaymanager for which to configure autologin.
103    :param default_desktop_environment:
104    :param root_mount_point:
105    """
106    do_autologin = True
107
108    if username is None:
109        do_autologin = False
110
111    if "mdm" == displaymanager:
112        # Systems with MDM as Desktop Manager
113        mdm_conf_path = os.path.join(root_mount_point, "etc/mdm/custom.conf")
114
115        if os.path.exists(mdm_conf_path):
116            with open(mdm_conf_path, 'r') as mdm_conf:
117                text = mdm_conf.readlines()
118
119            with open(mdm_conf_path, 'w') as mdm_conf:
120                for line in text:
121                    if '[daemon]' in line:
122                        if do_autologin:
123                            line = (
124                                "[daemon]\n"
125                                "AutomaticLogin={!s}\n"
126                                "AutomaticLoginEnable=True\n".format(username)
127                                )
128                        else:
129                            line = (
130                                "[daemon]\n"
131                                "AutomaticLoginEnable=False\n"
132                                )
133
134                    mdm_conf.write(line)
135        else:
136            with open(mdm_conf_path, 'w') as mdm_conf:
137                mdm_conf.write(
138                    '# Calamares - Configure automatic login for user\n'
139                    )
140                mdm_conf.write('[daemon]\n')
141
142                if do_autologin:
143                    mdm_conf.write("AutomaticLogin={!s}\n".format(username))
144                    mdm_conf.write('AutomaticLoginEnable=True\n')
145                else:
146                    mdm_conf.write('AutomaticLoginEnable=False\n')
147
148    if "gdm" == displaymanager:
149        # Systems with GDM as Desktop Manager
150        gdm_conf_path = os.path.join(root_mount_point, "etc/gdm/custom.conf")
151
152        if os.path.exists(gdm_conf_path):
153            with open(gdm_conf_path, 'r') as gdm_conf:
154                text = gdm_conf.readlines()
155
156            with open(gdm_conf_path, 'w') as gdm_conf:
157                for line in text:
158                    if '[daemon]' in line:
159                        if do_autologin:
160                            line = (
161                                "[daemon]\n"
162                                "AutomaticLogin={!s}\n"
163                                "AutomaticLoginEnable=True\n".format(username)
164                                )
165                        else:
166                            line = "[daemon]\nAutomaticLoginEnable=False\n"
167
168                    gdm_conf.write(line)
169        else:
170            with open(gdm_conf_path, 'w') as gdm_conf:
171                gdm_conf.write(
172                    '# Calamares - Enable automatic login for user\n'
173                    )
174                gdm_conf.write('[daemon]\n')
175
176                if do_autologin:
177                    gdm_conf.write("AutomaticLogin={!s}\n".format(username))
178                    gdm_conf.write('AutomaticLoginEnable=True\n')
179                else:
180                    gdm_conf.write('AutomaticLoginEnable=False\n')
181
182        if (do_autologin):
183            accountservice_dir = "{!s}/var/lib/AccountsService/users".format(
184                    root_mount_point
185                    )
186            userfile_path = "{!s}/{!s}".format(accountservice_dir, username)
187            if os.path.exists(accountservice_dir):
188                with open(userfile_path, "w") as userfile:
189                    userfile.write("[User]\n")
190
191                    if default_desktop_environment is not None:
192                        userfile.write("XSession={!s}\n".format(
193                            default_desktop_environment.desktop_file))
194
195                    userfile.write("Icon=\n")
196
197    if "kdm" == displaymanager:
198        # Systems with KDM as Desktop Manager
199        kdm_conf_path = os.path.join(
200            root_mount_point, "usr/share/config/kdm/kdmrc"
201            )
202        # Check which path is in use: SUSE does something else.
203        # Also double-check the default setting. Pick the first
204        # one that exists in the target.
205        for candidate_kdmrc in (
206            "usr/share/config/kdm/kdmrc",
207            "usr/share/kde4/config/kdm/kdmrc",
208        ):
209            p = os.path.join(root_mount_point, candidate_kdmrc)
210            if os.path.exists(p):
211                kdm_conf_path = p
212                break
213        text = []
214
215        if os.path.exists(kdm_conf_path):
216            with open(kdm_conf_path, 'r') as kdm_conf:
217                text = kdm_conf.readlines()
218
219            with open(kdm_conf_path, 'w') as kdm_conf:
220                for line in text:
221                    if 'AutoLoginEnable=' in line:
222                        if do_autologin:
223                            line = 'AutoLoginEnable=true\n'
224                        else:
225                            line = 'AutoLoginEnable=false\n'
226
227                    if do_autologin and 'AutoLoginUser=' in line:
228                        line = "AutoLoginUser={!s}\n".format(username)
229
230                    kdm_conf.write(line)
231        else:
232            return (
233                "Cannot write KDM configuration file",
234                "KDM config file {!s} does not exist".format(kdm_conf_path)
235                )
236
237    if "lxdm" == displaymanager:
238        # Systems with LXDM as Desktop Manager
239        lxdm_conf_path = os.path.join(root_mount_point, "etc/lxdm/lxdm.conf")
240        text = []
241
242        if os.path.exists(lxdm_conf_path):
243            with open(lxdm_conf_path, 'r') as lxdm_conf:
244                text = lxdm_conf.readlines()
245
246            with open(lxdm_conf_path, 'w') as lxdm_conf:
247                for line in text:
248                    if 'autologin=' in line:
249                        if do_autologin:
250                            line = "autologin={!s}\n".format(username)
251                        else:
252                            line = "# autologin=\n"
253
254                    lxdm_conf.write(line)
255        else:
256            return (
257                "Cannot write LXDM configuration file",
258                "LXDM config file {!s} does not exist".format(lxdm_conf_path)
259                )
260
261    if "lightdm" == displaymanager:
262        # Systems with LightDM as Desktop Manager
263        # Ideally, we should use configparser for the ini conf file,
264        # but we just do a simple text replacement for now, as it
265        # worksforme(tm)
266        lightdm_conf_path = os.path.join(
267            root_mount_point, "etc/lightdm/lightdm.conf"
268            )
269        text = []
270
271        if os.path.exists(lightdm_conf_path):
272            with open(lightdm_conf_path, 'r') as lightdm_conf:
273                text = lightdm_conf.readlines()
274
275            with open(lightdm_conf_path, 'w') as lightdm_conf:
276                for line in text:
277                    if 'autologin-user=' in line:
278                        if do_autologin:
279                            line = "autologin-user={!s}\n".format(username)
280                        else:
281                            line = "#autologin-user=\n"
282
283                    lightdm_conf.write(line)
284        else:
285            try:
286                # Create a new lightdm.conf file; this is documented to be
287                # read last, after aeverything in lightdm.conf.d/
288                with open(lightdm_conf_path, 'w') as lightdm_conf:
289                    if do_autologin:
290                        lightdm_conf.write(
291                            "autologin-user={!s}\n".format(username))
292                    else:
293                        lightdm_conf.write(
294                            "#autologin-user=\n")
295            except FileNotFoundError:
296                return (
297                    "Cannot write LightDM configuration file",
298                    "LightDM config file {!s} does not exist".format(
299                        lightdm_conf_path
300                        )
301                    )
302
303    if "slim" == displaymanager:
304        # Systems with Slim as Desktop Manager
305        slim_conf_path = os.path.join(root_mount_point, "etc/slim.conf")
306        text = []
307
308        if os.path.exists(slim_conf_path):
309            with open(slim_conf_path, 'r') as slim_conf:
310                text = slim_conf.readlines()
311
312            with open(slim_conf_path, 'w') as slim_conf:
313                for line in text:
314                    if 'auto_login' in line:
315                        if do_autologin:
316                            line = 'auto_login yes\n'
317                        else:
318                            line = 'auto_login no\n'
319
320                    if do_autologin and 'default_user' in line:
321                        line = "default_user {!s}\n".format(username)
322
323                    slim_conf.write(line)
324        else:
325            return (
326                "Cannot write SLIM configuration file",
327                "SLIM config file {!s} does not exist".format(slim_conf_path)
328                )
329
330    if "sddm" == displaymanager:
331        # Systems with Sddm as Desktop Manager
332        sddm_conf_path = os.path.join(root_mount_point, "etc/sddm.conf")
333
334        sddm_config = configparser.ConfigParser(strict=False)
335        # Make everything case sensitive
336        sddm_config.optionxform = str
337
338        if os.path.isfile(sddm_conf_path):
339            sddm_config.read(sddm_conf_path)
340
341        if 'Autologin' not in sddm_config:
342            sddm_config.add_section('Autologin')
343
344        if do_autologin:
345            sddm_config.set('Autologin', 'User', username)
346        elif sddm_config.has_option('Autologin', 'User'):
347            sddm_config.remove_option('Autologin', 'User')
348
349        if default_desktop_environment is not None:
350            sddm_config.set(
351                'Autologin',
352                'Session',
353                default_desktop_environment.desktop_file
354                )
355
356        with open(sddm_conf_path, 'w') as sddm_config_file:
357            sddm_config.write(sddm_config_file, space_around_delimiters=False)
358
359    if "sysconfig" == displaymanager:
360        dmauto = "DISPLAYMANAGER_AUTOLOGIN"
361
362        os.system(
363            "sed -i -e 's|^{!s}=.*|{!s}=\"{!s}\"|' "
364            "{!s}/etc/sysconfig/displaymanager".format(
365                            dmauto, dmauto,
366                            username if do_autologin else "",
367                            root_mount_point
368                            )
369            )
370
371    return None
372
373
374def run():
375    """
376    Configure display managers.
377
378    We acquire a list of displaymanagers, either from config or (overridden)
379    from globalstorage. This module will try to set up (including autologin)
380    all the displaymanagers in the list, in that specific order. Most distros
381    will probably only ship one displaymanager.
382    If a displaymanager is in the list but not installed, a debugging message
383    is printed and the entry ignored.
384    """
385    if "displaymanagers" in libcalamares.job.configuration:
386        displaymanagers = libcalamares.job.configuration["displaymanagers"]
387
388    if libcalamares.globalstorage.contains("displayManagers"):
389        displaymanagers = libcalamares.globalstorage.value("displayManagers")
390
391    if displaymanagers is None:
392        return (
393            "No display managers selected for the displaymanager module.",
394            "The displaymanagers list is empty or undefined in both"
395            "globalstorage and displaymanager.conf."
396            )
397
398    username = libcalamares.globalstorage.value("autologinUser")
399    root_mount_point = libcalamares.globalstorage.value("rootMountPoint")
400
401    if "default_desktop_environment" in libcalamares.job.configuration:
402        entry = libcalamares.job.configuration["defaultDesktopEnvironment"]
403        default_desktop_environment = DesktopEnvironment(
404            entry["executable"], entry["desktopFile"]
405            )
406    else:
407        default_desktop_environment = find_desktop_environment(
408            root_mount_point
409            )
410
411    if "basicSetup" in libcalamares.job.configuration:
412        enable_basic_setup = libcalamares.job.configuration["basicSetup"]
413    else:
414        enable_basic_setup = False
415
416    # Setup slim
417    if "slim" in displaymanagers:
418        if not have_dm("slim", root_mount_point):
419            libcalamares.utils.debug("slim selected but not installed")
420            displaymanagers.remove("slim")
421
422    # Setup sddm
423    if "sddm" in displaymanagers:
424        if not have_dm("sddm", root_mount_point):
425            libcalamares.utils.debug("sddm selected but not installed")
426            displaymanagers.remove("sddm")
427
428    # setup lightdm
429    if "lightdm" in displaymanagers:
430        if have_dm("lightdm", root_mount_point):
431            lightdm_conf_path = os.path.join(
432                root_mount_point, "etc/lightdm/lightdm.conf"
433                )
434
435            if enable_basic_setup:
436                libcalamares.utils.target_env_call(
437                    ['mkdir', '-p', '/run/lightdm']
438                    )
439
440                if libcalamares.utils.target_env_call(
441                        ['getent', 'group', 'lightdm']
442                        ) != 0:
443                    libcalamares.utils.target_env_call(
444                        ['groupadd', '-g', '620', 'lightdm']
445                        )
446
447                if libcalamares.utils.target_env_call(
448                        ['getent', 'passwd', 'lightdm']
449                        ) != 0:
450                    libcalamares.utils.target_env_call(
451                        ['useradd', '-c',
452                            '"LightDM Display Manager"',
453                            '-u', '620',
454                            '-g', 'lightdm',
455                            '-d', '/var/run/lightdm',
456                            '-s', '/usr/bin/nologin',
457                            'lightdm'
458                         ]
459                        )
460
461                libcalamares.utils.target_env_call('passwd', '-l', 'lightdm')
462                libcalamares.utils.target_env_call(
463                    ['chown', '-R', 'lightdm:lightdm', '/run/lightdm']
464                    )
465                libcalamares.utils.target_env_call(
466                    ['chmod', '+r' '/etc/lightdm/lightdm.conf']
467                    )
468
469            if default_desktop_environment is not None:
470                os.system(
471                    "sed -i -e \"s/^.*user-session=.*/user-session={!s}/\" "
472                    "{!s}".format(
473                        default_desktop_environment.desktop_file,
474                        lightdm_conf_path
475                        )
476                    )
477
478            # configure lightdm-greeter
479            greeter_path = os.path.join(
480                root_mount_point, "usr/share/xgreeters"
481                )
482
483            if (os.path.exists(greeter_path)):
484                # configure first found lightdm-greeter
485                for entry in os.listdir(greeter_path):
486                    if entry.endswith('.desktop'):
487                        greeter = entry.split('.')[0]
488                        libcalamares.utils.debug(
489                            "found greeter {!s}".format(greeter)
490                            )
491                        os.system(
492                            "sed -i -e \"s/^.*greeter-session=.*"
493                            "/greeter-session={!s}/\" {!s}".format(
494                                greeter,
495                                lightdm_conf_path
496                                )
497                            )
498                        libcalamares.utils.debug(
499                            "{!s} configured as greeter.".format(greeter)
500                            )
501                        break
502                else:
503                    return ("No lightdm greeter installed.")
504        else:
505            libcalamares.utils.debug("lightdm selected but not installed")
506            displaymanagers.remove("lightdm")
507
508    # Setup gdm
509    if "gdm" in displaymanagers:
510        if have_dm("gdm", root_mount_point):
511            if enable_basic_setup:
512                if libcalamares.utils.target_env_call(
513                        ['getent', 'group', 'gdm']
514                        ) != 0:
515                    libcalamares.utils.target_env_call(
516                        ['groupadd', '-g', '120', 'gdm']
517                        )
518
519                if libcalamares.utils.target_env_call(
520                        ['getent', 'passwd', 'gdm']
521                        ) != 0:
522                    libcalamares.utils.target_env_call(
523                        ['useradd',
524                            '-c', '"Gnome Display Manager"',
525                            '-u', '120',
526                            '-g', 'gdm',
527                            '-d', '/var/lib/gdm',
528                            '-s', '/usr/bin/nologin',
529                            'gdm'
530                         ]
531                        )
532
533                libcalamares.utils.target_env_call(
534                    ['passwd', '-l', 'gdm']
535                    )
536                libcalamares.utils.target_env_call(
537                    ['chown', '-R', 'gdm:gdm', '/var/lib/gdm']
538                    )
539        else:
540            libcalamares.utils.debug("gdm selected but not installed")
541            displaymanagers.remove("gdm")
542
543    # Setup mdm
544    if "mdm" in displaymanagers:
545        if have_dm("mdm", root_mount_point):
546            if enable_basic_setup:
547                if libcalamares.utils.target_env_call(
548                         ['getent', 'group', 'mdm']
549                         ) != 0:
550                    libcalamares.utils.target_env_call(
551                        ['groupadd', '-g', '128', 'mdm']
552                        )
553
554                if libcalamares.utils.target_env_call(
555                        ['getent', 'passwd', 'mdm']
556                        ) != 0:
557                    libcalamares.utils.target_env_call(
558                        ['useradd',
559                            '-c', '"Linux Mint Display Manager"',
560                            '-u', '128',
561                            '-g', 'mdm',
562                            '-d', '/var/lib/mdm',
563                            '-s', '/usr/bin/nologin',
564                            'mdm'
565                         ]
566                        )
567
568                libcalamares.utils.target_env_call(
569                    ['passwd', '-l', 'mdm']
570                    )
571                libcalamares.utils.target_env_call(
572                    ['chown', 'root:mdm', '/var/lib/mdm']
573                    )
574                libcalamares.utils.target_env_call(
575                    ['chmod', '1770', '/var/lib/mdm']
576                    )
577
578            if default_desktop_environment is not None:
579                os.system(
580                    "sed -i \"s|default.desktop|{!s}.desktop|g\" "
581                    "{!s}/etc/mdm/custom.conf".format(
582                        default_desktop_environment.desktop_file,
583                        root_mount_point
584                        )
585                    )
586        else:
587            libcalamares.utils.debug("mdm selected but not installed")
588            displaymanagers.remove("mdm")
589
590    # Setup lxdm
591    if "lxdm" in displaymanagers:
592        if have_dm("lxdm", root_mount_point):
593            if enable_basic_setup:
594                if libcalamares.utils.target_env_call(
595                        ['getent', 'group', 'lxdm']
596                        ) != 0:
597                    libcalamares.utils.target_env_call(
598                        ['groupadd', '--system', 'lxdm']
599                        )
600
601                libcalamares.utils.target_env_call(
602                    ['chgrp', '-R', 'lxdm', '/var/lib/lxdm']
603                    )
604                libcalamares.utils.target_env_call(
605                    ['chgrp', 'lxdm', '/etc/lxdm/lxdm.conf']
606                    )
607                libcalamares.utils.target_env_call(
608                    ['chmod', '+r', '/etc/lxdm/lxdm.conf']
609                    )
610
611            if default_desktop_environment is not None:
612                os.system(
613                    "sed -i -e \"s|^.*session=.*|session={!s}|\" "
614                    "{!s}/etc/lxdm/lxdm.conf".format(
615                        default_desktop_environment.executable,
616                        root_mount_point
617                        )
618                    )
619        else:
620            libcalamares.utils.debug("lxdm selected but not installed")
621            displaymanagers.remove("lxdm")
622
623    # Setup kdm
624    if "kdm" in displaymanagers:
625        if have_dm("kdm", root_mount_point):
626            if enable_basic_setup:
627                if libcalamares.utils.target_env_call(
628                        ['getent', 'group', 'kdm']
629                        ) != 0:
630                    libcalamares.utils.target_env_call(
631                        ['groupadd', '-g', '135', 'kdm']
632                        )
633
634                if libcalamares.utils.target_env_call(
635                        ['getent', 'passwd', 'kdm']
636                        ) != 0:
637                    libcalamares.utils.target_env_call(
638                        ['useradd',
639                            '-u', '135',
640                            '-g', 'kdm',
641                            '-d', '/var/lib/kdm',
642                            '-s', '/bin/false',
643                            '-r',
644                            '-M',
645                            'kdm'
646                         ]
647                        )
648
649                libcalamares.utils.target_env_call(
650                    ['chown', '-R', '135:135', 'var/lib/kdm']
651                    )
652        else:
653            libcalamares.utils.debug("kdm selected but not installed")
654            displaymanagers.remove("kdm")
655
656    if username is not None:
657        libcalamares.utils.debug(
658            "Setting up autologin for user {!s}.".format(username)
659            )
660    else:
661        libcalamares.utils.debug("Unsetting autologin.")
662
663    libcalamares.globalstorage.insert("displayManagers", displaymanagers)
664
665    dm_setup_message = []
666    for dm in displaymanagers:
667        dm_message = set_autologin(
668                        username, dm,
669                        default_desktop_environment,
670                        root_mount_point
671                        )
672        if dm_message is not None:
673            dm_setup_message.append("{!s}: {!s}".format(*dm_message))
674
675    if ("sysconfigSetup" in libcalamares.job.configuration
676            and libcalamares.job.configuration["sysconfigSetup"]):
677        set_autologin(username, "sysconfig", None, root_mount_point)
678
679    if dm_setup_message:
680        return ("Display manager configuration was incomplete",
681                "\n".join(dm_setup_message))
Note: See TracBrowser for help on using the repository browser.