Як дозволити додатку SDL (не працює як root) використовувати консоль


14

Я хочу використовувати програму на основі SDL для відображення графіки на консолі, не входячи з консолі та не запускаючи програму як корінь. Наприклад, я хочу мати змогу запустити його через ssh. Цільова ОС - це розп.

Ось короткий приклад python для ілюстрації проблеми:

import os, pygame
os.environ['SDL_VIDEODRIVER'] = 'fbcon'
pygame.init()
s = pygame.display.set_mode()
print "Success"

Це працює (працює до завершення, не викидає винятків), якщо я запускаю його з консолі, і він працює через ssh, якщо я запускаю його як root.

Я перевірив, чи є мій користувач у групах аудіо та відео.

Я використовував strace, щоб побачити, чим відрізняється запуск його від консолі (який працює), запуск його як root через ssh (також працює), і запуск його як звичайний користувач через ssh (не працює).

Перша відмінність полягала в тому, що мій користувач не мав дозволу на доступ / dev / tty0. Я створив нову групу (tty0), помістив свого користувача в цю групу і додав правило udev, щоб надати цій групі доступ до / dev / tty0.

Вихід напруги розходиться при цьому виклику йоктлу - тут виявляється збій; ioctl повертає 0, коли програма запускається з консолі або запускається з ssh як root:

open("/dev/tty", O_RDWR)                = 4
ioctl(4, VT_GETSTATE, 0xbeaa01f8)       = -1 EINVAL (Invalid argument)

(Адреси також відрізняються, але це не важливо.)

Зважаючи на те, що моя програма працює, коли вона працює як root, я думаю, що це означає, що у мене є проблема з дозволом. Як я можу дати користувачеві необхідні дозволи для того, щоб мати змогу запускати цю програму без входу в консоль (і без запуску як root)?


Які права власності / дозволи на вашому пристрої framebuffer?
Бандрамі

Також / dev / tty зазвичай вимагає членства в консольній групі для запису.
Бандрамі

ajclarkson.co.uk/blog/pygame-no-root виглядає як рішення.
Arthur2e5

Відповіді:


3

Моя мета була такою ж, як у оригінального плаката, але з однією різницею: мені потрібно було запустити SDL-додаток як системний демон. Моя машина Linux - це Raspberry Pi 3, а операційна система - Raspbian Jessie. Жодна клавіатура чи миша не підключені до RPi. Я підключаюся до нього за допомогою SSH. Мій додаток SDL - це фактично додаток на основі Pygame . Я встановив pygame / SDL для використання драйвера фреймбуфера "fbcon" через змінну середовища SDL_VIDEODRIVER. Мій systemd --versionвихід:

systemd 215 + PAM + AUDIT + SELINUX + IMA + SYSVINIT + LIBCRYPTSETUP + GCRYPT + ACL + XZ -SECCOMP -APPARMOR

Моя версія пакета pygame така: ( aptitude show python-pygame):

1.9.2 ~ pre ~ r3348-2 ~ bpo8 + rpi1

Моя версія libSDL 1.2 така: ( aptitude show libsdl1.2debian- назва вашого пакета машини може бути різною):

1.2.15-10 + rpi1

Рецепт

  1. Налаштуйте дозволи для файлів / dev / tty та / dev / fb0, як описано у відповіді UDude. Я виявив, що в програмі Raspbian Jessie / dev / console зміни дозволу не потрібні.
  2. Додайте ці рядки до розділу [Сервіс] у файлі .service вашого демона:

    User=pi #Your limited user name goes here
    StandardInput=tty
    StandardOutput=tty
    TTYPath=/dev/tty2   # I also tried /dev/tty1 and that didn't work for me
    

    Якщо хтось зацікавлений, ось повний файл pyscopefb.service, який я використав:

    [Unit]
    Description=Pyscopefb test service 
    Wants=network-online.target
    After=rsyslog.service
    After=network-online.target
    
    [Service]
    Restart=no
    ExecStart=/home/pi/Soft/Test/pygame/pyscopefb
    ExecStop=/bin/kill -INT $MAINPID
    OOMScoreAdjust=-100
    TimeoutStopSec=10s
    User=pi
    WorkingDirectory=/home/pi/Soft/Test/pygame
    StandardInput=tty
    StandardOutput=tty
    TTYPath=/dev/tty2
    
    [Install]
    WantedBy=multi-user.target
    
  3. Випустіть ці команди в командному рядку (я припускаю, що файл pyscopefb.service вже розміщений у правильному місці, де systemd може його знайти):

    sudo systemctl daemon-reload
    sudo systemctl start pyscopefb
    

Це працює для мене. Зверніть увагу: я не перевіряв, чи програма pygame здатна приймати події клавіатури та миші чи ні.

Бонус

Мені також довелося вирішити ще дві проблеми, які також можуть зацікавити

  1. У нижній частині екрана блимав текстовий курсор із графікою кадрів. Щоб вирішити це питання, я додав у свою програму наступний код Python, який працює в моєму додатку до ініціалізації Pygame / SDL:

    def _disable_text_cursor_blinking(self):
        command_to_run = ["/usr/bin/sudo", "sh", "-c", "echo 0 > /sys/class/graphics/fbcon/cursor_blink"]
        try:
            output = subprocess32.check_output(command_to_run, universal_newlines = True)
            self._log.info("_disable_text_cursor_blinking succeeded! Output was:\n{output}", output = output)
        except subprocess32.CalledProcessError:
            self._log.failure("_disable_text_cursor_blinking failed!")
            raise
    
  2. Приблизно через 10 хвилин екран, підключений до виходу HDMI Raspberry Pi, став чорним (але не вимкнений), і моя графіка не відображалася, хоча Pygame не повідомив про помилки. Це виявилося функцією економії енергії. Щоб відключити це, я додав наступний код Python, який також працює перед ініціалізацією Pygame / SDL:

    def _disable_screen_blanking(self):
        command_to_run = ["/usr/bin/setterm", "--blank", "0"]
        try:
            output = subprocess32.check_output(command_to_run, universal_newlines = True)
            self._log.info("_disable_screen_blanking succeeded! Output was:\n{output}", output = output)
        except subprocess32.CalledProcessError:
            self._log.failure("_disable_screen_blanking failed!")
            raise
    

1
Це було надзвичайно корисно для мене, щоб досягти запуску пігменти без підключення клавіатури до мого Pi, тому дякую! Я хотів би зазначити, що мені здалося досить простим запустити пігаму /dev/tty7і видати питання, ExecStartPre=/bin/chvt 7щоб уникнути курсору, і він має бонус за те, що він не стикається з agetty, який працює за замовчуванням на tty1 – tty6.
dctucker

2

Хоча ви ставите запитання дещо неоднозначним (що мається на увазі під консоллю), я спробую відповісти на найбільш поширені випадки: / dev / console, / dev / tty, / dev / fb0 ... адаптуйте це до потрібних вам пристроїв. Ми припускаємо, що ім’я користувача "myuser."

Погляньте на дозволи пристрою (це ubuntu 15.04)

odroid@mbrxu3:~/projects/sc$ ls -l /dev/console
crw------- 1 root root 5, 1 Oct  23  17:49 /dev/console

odroid@mbrxu3:~/projects/sc$ ls -l /dev/tty
crw-rw-rw- 1 root tty 5, 0 Oct 24 17:50 /dev/tty

odroid@mbrxu3:~/projects/sc$ ls -l /dev/fb0 
crw-rw---- 1 root video 29, 0 Jan  1  2000 /dev/fb0

Вжити заходів

/ dev / console

група "root", але доступ до групи не дозволений. Мені не подобається просто додавати дозволи до кореневої групи, тому замість цього я створюю групу і chgrp файл та змінюю дозволи

$ sudo addgroup --system console
$ sudo chgrp console /dev/console
$ sudo chmod g+rw /dev/console
$ sudo usermod -a -G console <myuser>     <==== replace <myuser>

/ dev / tty

$ sudo usermod -a -G tty <myuser>

/ dev / fb0

$ sudo usermod -a -G video <myuser> 

Ви можете скористатися командою usermod, щоб додати свого користувача до всіх перерахованих вище груп, якщо це - ваша потреба.


-1

З мого недавнього досвіду, окрім надання дозволу на ваш tty-пристрій (як згадувалося раніше), вам потрібно зробити ще 2 додаткові речі:

  • надання можливості cap_sys_tty_config для виконуваного файлу. Якщо ви використовуєте програму python, ви можете робити це як setcap cap_sys_tty_config+eip /usr/bin/python3.5(замінити шлях для python вашим). Звичайно, врахуйте, що ви надаєте цю можливість для будь-якого сценарію python.
  • запуск процесу в новому віртуальному терміналі, наприклад, з використанням openvt: openvt ./your_script.py
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.