Allow drop-in for sudo, such as doas

This commit is contained in:
Richard Neumann 2021-05-14 21:08:01 +02:00
parent 6f3f4a2764
commit d24cc31b04
2 changed files with 34 additions and 26 deletions

View file

@ -5,15 +5,20 @@ Allow users to toggle a convertible laptop between laptop and tablet mode.
## Configuration ## Configuration
The devices to be deactivated in either *tablet* or *laptop* mode must be specified in `/etc/tablet-mode.json`. The devices to be deactivated in either *tablet* or *laptop* mode must be specified in `/etc/tablet-mode.json`.
Optionally you can specify whether desktop notifications shall be send when changing the mode using the *notify* flag. You can specify whether desktop notifications shall be send when changing the mode using the `notify` flag.
If specified, you can override `sudo` to provide another program that accepts commands to be run as root without a password
by the current user to elevate privileges, such as *doas*.
{ ```json
"tablet": [ {
"/dev/input/by-path/platform-i8042-serio-0-event-kbd", "tablet": [
"/dev/input/by-path/platform-i8042-serio-1-event-mouse" "/dev/input/by-path/platform-i8042-serio-0-event-kbd",
], "/dev/input/by-path/platform-i8042-serio-1-event-mouse"
"notify": false ],
} "notify": false,
"sudo": "/usr/bin/doas"
}
```
## Usage ## Usage

View file

@ -15,6 +15,7 @@ from tabletmode.config import load_config
DESCRIPTION = 'Sets or toggles the system mode.' DESCRIPTION = 'Sets or toggles the system mode.'
LAPTOP_MODE_SERVICE = 'laptop-mode.service' LAPTOP_MODE_SERVICE = 'laptop-mode.service'
TABLET_MODE_SERVICE = 'tablet-mode.service' TABLET_MODE_SERVICE = 'tablet-mode.service'
SUDO = '/usr/bin/sudo'
def get_args() -> Namespace: def get_args() -> Namespace:
@ -32,10 +33,11 @@ def get_args() -> Namespace:
return parser.parse_args() return parser.parse_args()
def systemctl(action: str, unit: str, *, root: bool = False) -> bool: def systemctl(action: str, unit: str, *, root: bool = False,
sudo: str = SUDO) -> bool:
"""Runs systemctl.""" """Runs systemctl."""
command = ['/usr/bin/sudo'] if root else [] command = [sudo] if root else []
command += ['systemctl', action, unit] command += ['systemctl', action, unit]
try: try:
@ -69,43 +71,43 @@ def notify_tablet_mode() -> CompletedProcess:
return notify_send('Tablet mode.', 'The system is now in tablet mode.') return notify_send('Tablet mode.', 'The system is now in tablet mode.')
def default_mode(notify: bool = False) -> None: def default_mode(notify: bool = False, *, sudo: str = SUDO) -> None:
"""Restores all blocked input devices.""" """Restores all blocked input devices."""
systemctl('stop', LAPTOP_MODE_SERVICE, root=True) systemctl('stop', LAPTOP_MODE_SERVICE, root=True, sudo=sudo)
systemctl('stop', TABLET_MODE_SERVICE, root=True) systemctl('stop', TABLET_MODE_SERVICE, root=True, sudo=sudo)
if notify: if notify:
notify_send('Default mode.', 'The system is now in default mode.') notify_send('Default mode.', 'The system is now in default mode.')
def laptop_mode(notify: bool = False) -> None: def laptop_mode(notify: bool = False, *, sudo: str = SUDO) -> None:
"""Starts the laptop mode.""" """Starts the laptop mode."""
systemctl('stop', TABLET_MODE_SERVICE, root=True) systemctl('stop', TABLET_MODE_SERVICE, root=True, sudo=sudo)
systemctl('start', LAPTOP_MODE_SERVICE, root=True) systemctl('start', LAPTOP_MODE_SERVICE, root=True, sudo=sudo)
if notify: if notify:
notify_laptop_mode() notify_laptop_mode()
def tablet_mode(notify: bool = False) -> None: def tablet_mode(notify: bool = False, *, sudo: str = SUDO) -> None:
"""Starts the tablet mode.""" """Starts the tablet mode."""
systemctl('stop', LAPTOP_MODE_SERVICE, root=True) systemctl('stop', LAPTOP_MODE_SERVICE, root=True, sudo=sudo)
systemctl('start', TABLET_MODE_SERVICE, root=True) systemctl('start', TABLET_MODE_SERVICE, root=True, sudo=sudo)
if notify: if notify:
notify_tablet_mode() notify_tablet_mode()
def toggle_mode(notify: bool = False) -> None: def toggle_mode(notify: bool = False, *, sudo: str = SUDO) -> None:
"""Toggles between laptop and tablet mode.""" """Toggles between laptop and tablet mode."""
if systemctl('status', TABLET_MODE_SERVICE): if systemctl('status', TABLET_MODE_SERVICE):
laptop_mode(notify=notify) laptop_mode(notify=notify, sudo=sudo)
else: else:
tablet_mode(notify=notify) tablet_mode(notify=notify, sudo=sudo)
def main() -> None: def main() -> None:
@ -114,14 +116,15 @@ def main() -> None:
args = get_args() args = get_args()
config = load_config() config = load_config()
notify = config.get('notify', False) or args.notify notify = config.get('notify', False) or args.notify
sudo = config.get('sudo', SUDO)
if args.mode == 'toggle': if args.mode == 'toggle':
toggle_mode(notify=notify) toggle_mode(notify=notify, sudo=sudo)
elif args.mode == 'default': elif args.mode == 'default':
default_mode(notify=notify) default_mode(notify=notify, sudo=sudo)
elif args.mode == 'laptop': elif args.mode == 'laptop':
laptop_mode(notify=notify) laptop_mode(notify=notify, sudo=sudo)
elif args.mode == 'tablet': elif args.mode == 'tablet':
tablet_mode(notify=notify) tablet_mode(notify=notify, sudo=sudo)
else: else:
print('Must specify a mode.', file=stderr, flush=True) print('Must specify a mode.', file=stderr, flush=True)