@@ -20,6 +20,23 @@ def __init__(self, name):
20
20
self .name = name
21
21
super ().__init__ ()
22
22
23
+ @classmethod
24
+ def get_packages (cls ):
25
+ """Get all installed packages with name version number, release number (if available) and architecture
26
+
27
+ >>> host.package.get_packages()
28
+ {'acl.x86_64': {'arch': 'x86_64',
29
+ 'name': 'acl',
30
+ 'release': '4.3.1',
31
+ 'version': '2.2.52'},
32
+ <redacted>
33
+ 'zypper.x86_64': {'arch': 'x86_64',
34
+ 'name': 'zypper',
35
+ 'release': '150200.39.1',
36
+ 'version': '1.14.57'}}
37
+ """
38
+ raise NotImplementedError
39
+
23
40
@property
24
41
def is_installed (self ):
25
42
"""Test if the package is installed
@@ -94,6 +111,29 @@ def get_module_class(cls, host):
94
111
95
112
96
113
class DebianPackage (Package ):
114
+ @classmethod
115
+ def get_packages (cls ):
116
+ out = cls .run (r"dpkg-query -f '${Package}|${Version}|${Architecture}\n' -W" )
117
+ assert not out .stderr
118
+ pkgs = {}
119
+ for line in out .stdout .splitlines ():
120
+ line = line .strip ()
121
+ if not line :
122
+ continue
123
+ name , version , arch = line .split ("|" )
124
+ pkg_key = f"{ name } .{ arch } "
125
+ assert pkg_key not in pkgs , (
126
+ f"Package { pkg_key } already added to package list. "
127
+ "Check for duplicate package in command output"
128
+ )
129
+ pkgs [pkg_key ] = {
130
+ "name" : name ,
131
+ "version" : version ,
132
+ "release" : None ,
133
+ "arch" : arch ,
134
+ }
135
+ return pkgs
136
+
97
137
@property
98
138
def is_installed (self ):
99
139
result = self .run_test ("dpkg-query -f '${Status}' -W %s" , self .name )
@@ -155,6 +195,34 @@ def version(self):
155
195
156
196
157
197
class RpmPackage (Package ):
198
+ @classmethod
199
+ def get_packages (cls ):
200
+ out = cls .run (
201
+ r'rpm -qa --queryformat "%{NAME}|%{VERSION}|%{RELEASE}|%{ARCH}\n"'
202
+ )
203
+ assert not out .stderr
204
+ pkgs = {}
205
+ for line in out .stdout .splitlines ():
206
+ line = line .strip ()
207
+ if not line :
208
+ continue
209
+ name , version , release , arch = line .split ("|" )
210
+ # Ignore GPG keys imported with "rpm --import" e.g. "gpg-pubkey|50a3dd1c|50f35137|(none)"
211
+ if name == "gpg-pubkey" and arch == "(none)" :
212
+ continue
213
+ pkg_key = f"{ name } .{ arch } "
214
+ assert pkg_key not in pkgs , (
215
+ f"Package { pkg_key } already added to package list. "
216
+ "Check for duplicate package in command output"
217
+ )
218
+ pkgs [pkg_key ] = {
219
+ "name" : name ,
220
+ "version" : version ,
221
+ "release" : release ,
222
+ "arch" : arch ,
223
+ }
224
+ return pkgs
225
+
158
226
@property
159
227
def is_installed (self ):
160
228
return self .run_test ("rpm -q %s" , self .name ).rc == 0
@@ -185,6 +253,29 @@ def release(self):
185
253
186
254
187
255
class ArchPackage (Package ):
256
+ @classmethod
257
+ def get_packages (cls ):
258
+ out = cls .run (r'expac "%n|%v|%a"' )
259
+ assert not out .stderr
260
+ pkgs = {}
261
+ for line in out .stdout .splitlines ():
262
+ line = line .strip ()
263
+ if not line :
264
+ continue
265
+ name , version , arch = line .split ("|" )
266
+ pkg_key = f"{ name } .{ arch } "
267
+ assert pkg_key not in pkgs , (
268
+ f"Package { pkg_key } already added to package list. "
269
+ "Check for duplicate package in command output"
270
+ )
271
+ pkgs [pkg_key ] = {
272
+ "name" : name ,
273
+ "version" : version ,
274
+ "release" : None ,
275
+ "arch" : arch ,
276
+ }
277
+ return pkgs
278
+
188
279
@property
189
280
def is_installed (self ):
190
281
return self .run_test ("pacman -Q %s" , self .name ).rc == 0
0 commit comments