Skip to content

Commit 645d181

Browse files
author
Korney Gedert
committed
Implement apt1_runner
1 parent 63e5ffc commit 645d181

4 files changed

Lines changed: 163 additions & 0 deletions

File tree

gpoa/apt1_runner

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#!/usr/bin/python3
2+
#
3+
# GPOA - GPO Applier for Linux
4+
#
5+
# Copyright (C) 2025 BaseALT Ltd.
6+
#
7+
# This program is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU General Public License as published by
9+
# the Free Software Foundation, either version 3 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# This program is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU General Public License
18+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
20+
import rpm
21+
from gpoa.storage import registry_factory
22+
from util.util import get_uid_by_username, string_to_literal_eval
23+
import logging
24+
from util.logging import log
25+
import argparse
26+
import gettext
27+
import locale
28+
29+
import dbus
30+
import dbus.mainloop.glib
31+
32+
33+
def is_rpm_installed(rpm_name):
34+
"""
35+
Check if the package named 'rpm_name' is installed
36+
"""
37+
ts = rpm.TransactionSet()
38+
pm = ts.dbMatch('name', rpm_name)
39+
if pm.count() > 0:
40+
return True
41+
42+
return False
43+
44+
45+
def is_rpm_notinstalled(rpm_name):
46+
"""
47+
Check if the package named 'rpm_name' is not installed
48+
"""
49+
return not is_rpm_installed(rpm_name)
50+
51+
52+
def remove_suffix(item):
53+
return '-' + str(item)
54+
55+
56+
class Apt_applier:
57+
def __init__(self, user=None):
58+
"""
59+
Initialize the DBus client for org.altlinux.alterator.apt1
60+
61+
Throws:
62+
dbus.exceptions.DBusException on error while connecting to the DBus
63+
"""
64+
dbus_interface = 'org.altlinux.alterator.apt1'
65+
bus_name = 'org.altlinux.alterator'
66+
object_path = '/org/altlinux/alterator/apt'
67+
68+
apt_obj = dbus.SystemBus().get_object(bus_name, object_path)
69+
self.apt_iface = dbus.Interface(apt_obj, dbus_interface)
70+
71+
install_key_name = 'Install'
72+
remove_key_name = 'Remove'
73+
hklm_branch = 'Software/BaseALT/Policies/Packages'
74+
self.storage = registry_factory()
75+
if user:
76+
uid = get_uid_by_username(user)
77+
dict_dconf_db = self.storage.get_dictionary_from_dconf_file_db(uid)
78+
else:
79+
dict_dconf_db = self.storage.get_dictionary_from_dconf_file_db()
80+
dict_packages = dict_dconf_db.get(hklm_branch, {})
81+
82+
self.remove_packages = set(map(str.strip, string_to_literal_eval(dict_packages.get(remove_key_name, []))))
83+
self.install_packages = map(str.strip, string_to_literal_eval(dict_packages.get(install_key_name, [])))
84+
self.install_packages = set(
85+
filter(is_rpm_notinstalled, [item for item in self.install_packages if item not in self.remove_packages]))
86+
self.remove_packages = filter(is_rpm_installed, self.remove_packages)
87+
88+
def apply(self):
89+
"""
90+
Call the ApplyAsync method for current packages policy
91+
Throws:
92+
dbus.exceptions.DBusException on error while connecting to the DBus
93+
Returns:
94+
response
95+
"""
96+
log('D235')
97+
98+
log('D148', {'names': self.install_packages})
99+
log('D149', {'names': self.remove_packages})
100+
response = self.apt_iface.ApplyAsync("' '",
101+
"'" + " ".join(map(str, self.install_packages)) + " ".join(
102+
map(remove_suffix, self.remove_packages)) + "'")
103+
if response != 0:
104+
remove_packages = filter(is_rpm_installed, self.remove_packages)
105+
install_packages = filter(is_rpm_notinstalled, self.install_packages)
106+
for package in remove_packages:
107+
if self.apt_iface.ApplyAsync("' '", remove_suffix(package)) != 0:
108+
log('E58', {'name': package})
109+
for package in install_packages:
110+
if self.apt_iface.ApplyAsync("' '", package) != 0:
111+
log('E57', {'name': package})
112+
113+
return response
114+
115+
def update(self):
116+
"""
117+
Call the UpdateAsync method
118+
Throws:
119+
dbus.exceptions.DBusException on error while connecting to the DBus
120+
Returns:
121+
response
122+
"""
123+
response = self.apt_iface.UpdateAsync()
124+
log('D143')
125+
# TODO: Write output into log
126+
return response
127+
128+
129+
if __name__ == '__main__':
130+
locale.bindtextdomain('gpoa', '/usr/lib/python3/site-packages/gpoa/locale')
131+
gettext.bindtextdomain('gpoa', '/usr/lib/python3/site-packages/gpoa/locale')
132+
gettext.textdomain('gpoa')
133+
logger = logging.getLogger()
134+
parser = argparse.ArgumentParser(description='Package applier')
135+
parser.add_argument('--user', type=str, help='user', nargs='?', default=None)
136+
parser.add_argument('--loglevel', type=int, help='loglevel', nargs='?', default=30)
137+
138+
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
139+
140+
args = parser.parse_args()
141+
logger.setLevel(args.loglevel)
142+
143+
try:
144+
if args.user:
145+
applier = Apt_applier(args.user)
146+
else:
147+
applier = Apt_applier()
148+
except dbus.exceptions.DBusException as e:
149+
exit(1)
150+
151+
try:
152+
if applier.apply() != 0:
153+
exit(1)
154+
except dbus.exceptions.DBusException as exc:
155+
exit(1)

gpoa/locale/ru_RU/LC_MESSAGES/gpoa.po

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,9 @@ msgstr "Расчет времени с момента первого входа
958958
msgid "No logins found after password change"
959959
msgstr "Не найдены входы после изменения пароля"
960960

961+
msgid "Running apt1_runner to install and remove packages"
962+
msgstr "Запуск pkcon_runner для установки и удаления пакетов"
963+
961964
msgid "Unknown message type, no message assigned"
962965
msgstr "Неизвестный тип сообщения"
963966

gpoa/messages/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ def debug_code(code):
349349
debug_ids[232] = 'No user login records found'
350350
debug_ids[233] = 'Calculating time since the first user login after their password change'
351351
debug_ids[234] = 'No logins found after password change'
352+
debug_ids[235] = 'Running apt1_runner to install and remove packages'
352353

353354
return debug_ids.get(code, 'Unknown debug code')
354355

gpupdate.spec

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ ln -s %python3_sitelibdir/gpoa/gpupdate-setup \
106106
mkdir -p \
107107
%buildroot%_prefix/libexec/%name
108108

109+
ln -s %python3_sitelibdir/gpoa/apt1_runner \
110+
%buildroot%_prefix/libexec/%name/apt1_runner
109111
ln -s %python3_sitelibdir/gpoa/pkcon_runner \
110112
%buildroot%_prefix/libexec/%name/pkcon_runner
111113
ln -s %python3_sitelibdir/gpoa/scripts_runner \
@@ -166,11 +168,13 @@ fi
166168
%_bindir/gpupdate
167169
%_prefix/libexec/%name/scripts_runner
168170
%_prefix/libexec/%name/pkcon_runner
171+
%_prefix/libexec/%name/apt1_runner
169172
%attr(755,root,root) %python3_sitelibdir/gpoa/gpoa
170173
%attr(755,root,root) %python3_sitelibdir/gpoa/gpupdate
171174
%attr(755,root,root) %python3_sitelibdir/gpoa/gpupdate-setup
172175
%attr(755,root,root) %python3_sitelibdir/gpoa/scripts_runner
173176
%attr(755,root,root) %python3_sitelibdir/gpoa/pkcon_runner
177+
%attr(755,root,root) %python3_sitelibdir/gpoa/apt1_runner
174178
%python3_sitelibdir/gpoa
175179
%_datadir/%name
176180
%_unitdir/%name.service

0 commit comments

Comments
 (0)