Skip to content

Commit

Permalink
fix: use login1 dbus API, fix systemd-run (ublue-os#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
gerblesh authored and KyleGospo committed Oct 27, 2024
1 parent 3516f12 commit e3540d7
Show file tree
Hide file tree
Showing 5 changed files with 379 additions and 58 deletions.
40 changes: 18 additions & 22 deletions src/ublue_update/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from ublue_update.update_inhibitors.hardware import check_hardware_inhibitors
from ublue_update.update_inhibitors.custom import check_custom_inhibitors
from ublue_update.config import cfg
from ublue_update.session import get_xdg_runtime_dir, get_active_sessions
from ublue_update.session import get_active_users
from ublue_update.filelock import acquire_lock, release_lock


Expand All @@ -33,7 +33,7 @@ def notify(title: str, body: str, actions: list = [], urgency: str = "normal"):
if process_uid == 0:
users = []
try:
users = get_active_sessions()
users = get_active_users()
except KeyError as e:
log.error("failed to get active logind session info", e)
for user in users:
Expand All @@ -43,11 +43,12 @@ def notify(title: str, body: str, actions: list = [], urgency: str = "normal"):
log.error(f"failed to get xdg_runtime_dir for user: {user['Name']}", e)
return
user_args = [
"/usr/bin/sudo",
"-u",
f"{user['Name']}",
"DISPLAY=:0",
f"DBUS_SESSION_BUS_ADDRESS=unix:path={xdg_runtime_dir}/bus",
"/usr/bin/systemd-run",
"--user",
"--machine",
f"{user[1]}@", # magic number, corresponds to user name in ListUsers (see session.py)
"--pipe",
"--quiet",
]
user_args += args
out = subprocess.run(user_args, capture_output=True)
Expand Down Expand Up @@ -108,7 +109,7 @@ def run_updates(system, system_update_available):
)
users = []
try:
users = get_active_sessions()
users = get_active_users()
except KeyError as e:
log.error("failed to get active logind session info", e)

Expand All @@ -133,23 +134,18 @@ def run_updates(system, system_update_available):

"""Users"""
for user in users:
try:
xdg_runtime_dir = get_xdg_runtime_dir(user["User"])
except KeyError as e:
log.error(f"failed to get xdg_runtime_dir for user: {user['Name']}", e)
break
log.info(
f"""Running update for user: '{user['Name']}'"""
)

f"""Running update for user: '{user[1]}'"""
) # magic number, corresponds to username (see session.py)
out = subprocess.run(
[
"/usr/bin/sudo",
"-u",
f"{user['Name']}",
"DISPLAY=:0",
f"XDG_RUNTIME_DIR={xdg_runtime_dir}",
f"DBUS_SESSION_BUS_ADDRESS=unix:path={xdg_runtime_dir}/bus",
"/usr/bin/systemd-run",
"--setenv=TOPGRADE_SKIP_BRKC_NOTIFY=true",
"--user",
"--machine",
f"{user[1]}@",
"--pipe",
"--quiet",
"/usr/bin/topgrade",
"--config",
"/usr/share/ublue-update/topgrade-user.toml",
Expand Down
51 changes: 16 additions & 35 deletions src/ublue_update/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,22 @@
import json


def get_xdg_runtime_dir(uid):
def get_active_users():
out = subprocess.run(
["/usr/bin/loginctl", "show-user", f"{uid}"],
[
"/usr/bin/busctl",
"--system",
"-j",
"call",
"org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"ListUsers",
],
capture_output=True,
)
loginctl_output = {
line.split("=")[0]: line.split("=")[-1]
for line in out.stdout.decode("utf-8").splitlines()
}
return loginctl_output["RuntimePath"]


def get_active_sessions():
out = subprocess.run(
["/usr/bin/loginctl", "list-sessions", "--output=json"],
capture_output=True,
)
sessions = json.loads(out.stdout.decode("utf-8"))
session_properties = []
active_sessions = []
for session in sessions:
args = [
"/usr/bin/loginctl",
"show-session",
f"{session['session']}",
]
out = subprocess.run(args, capture_output=True)
if out.returncode == 0:
loginctl_output = {
line.split("=")[0]: line.split("=")[-1]
for line in out.stdout.decode("utf-8").splitlines()
}
session_properties.append(loginctl_output)
for session_info in session_properties:
graphical = session_info["Type"] == "x11" or session_info["Type"] == "wayland"
if graphical and session_info["Active"] == "yes":
active_sessions.append(session_info)
return active_sessions
# https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.login1.html
# ListUsers() returns an array of all currently logged in users. The structures in the array consist of the following fields: user id, user name, user object path.
users = json.loads(out.stdout.decode("utf-8"))
# sample output: {'type': 'a(uso)', 'data': [[[1000, 'user', '/org/freedesktop/login1/user/_1000']]]
return users["data"][0]
Loading

0 comments on commit e3540d7

Please sign in to comment.