@@ -227,19 +227,38 @@ def get_installed_packages(root_dir, is_container=True):
227227 """
228228 # These paths are relative to a Windows docker image layer root directory
229229 if is_container :
230- software_registry_locations = [
231- os .path .join (root_dir , 'Hives' , 'Software_Delta' ),
232- os .path .join (root_dir , 'Files' , 'Windows' , 'System32' , 'config' , 'SOFTWARE' )
233- ]
230+ hives_software_delta_loc = os .path .join (root_dir , 'Hives' , 'Software_Delta' )
231+ files_software_loc = os .path .join (
232+ root_dir ,
233+ 'Files' ,
234+ 'Windows' ,
235+ 'System32' ,
236+ 'config' ,
237+ 'SOFTWARE'
238+ )
239+ utilityvm_software_loc = os .path .join (
240+ root_dir ,
241+ 'UtilityVM' ,
242+ 'Files' ,
243+ 'Windows' ,
244+ 'System32' ,
245+ 'config' ,
246+ 'SOFTWARE'
247+ )
248+ root_prefixes_by_software_registry_locations = {
249+ hives_software_delta_loc : 'Files' ,
250+ files_software_loc : 'Files' ,
251+ utilityvm_software_loc : os .path .join ('UtilityVM' , 'Files' )
252+ }
234253 else :
235254 # TODO: Add support for virtual machines
236255 raise Exception ('Unsuported file system type' )
237256
238- for software_registry_loc in software_registry_locations :
257+ for software_registry_loc , root_prefix in root_prefixes_by_software_registry_locations . items () :
239258 if not os .path .exists (software_registry_loc ):
240259 continue
241260 for package in reg_parse (software_registry_loc ):
242- package .populate_installed_files (root_dir , is_container = is_container )
261+ package .populate_installed_files (root_dir , root_prefix = root_prefix )
243262 yield package
244263
245264
@@ -266,16 +285,27 @@ def create_absolute_installed_file_path(root_dir, file_path):
266285 return str (Path (root_dir ).joinpath (file_path ))
267286
268287
269- def create_relative_file_path (file_path , root_dir ):
288+ def create_relative_file_path (file_path , root_dir , root_prefix = '' ):
270289 """
271290 Return a subpath of `file_path` that is relative to `root_dir`
272291
273292 >>> file_path = '/home/test/example/foo.txt'
274293 >>> root_dir = '/home/test/'
275294 >>> create_relative_file_path(file_path, root_dir)
276295 'example/foo.txt'
296+
297+ If there is a `root_prefix`, then it is prepended to the resulting
298+ relative file path.
299+
300+ >>> file_path = '/home/test/example/foo.txt'
301+ >>> root_dir = '/home/test/'
302+ >>> create_relative_file_path(file_path, root_dir, 'prefix')
303+ 'prefix/example/foo.txt'
277304 """
278- return str (Path (file_path ).relative_to (root_dir ))
305+ relative_file_path = str (Path (file_path ).relative_to (root_dir ))
306+ if root_prefix :
307+ return os .path .join (root_prefix , relative_file_path )
308+ return relative_file_path
279309
280310
281311@attr .s ()
@@ -287,20 +317,18 @@ def recognize(cls, location):
287317 for installed in reg_parse (location ):
288318 yield installed
289319
290- def populate_installed_files (self , root_dir , is_container = False ):
320+ def populate_installed_files (self , root_dir , root_prefix = '' ):
291321 install_location = self .extra_data .get ('install_location' )
292322 if not install_location :
293323 return
294324
295- if is_container :
296- original_root_dir = root_dir
297- # If we are getting installed files from `root_dir` that is a
298- # Windows Docker layer path, we are setting the root to be the
299- # `Files` directory, since this directory represents the root `C:\`
300- # drive of a Windows installation.
301- # e.g. given a Windows Docker layer named `windows_docker_layer_id`,
302- # the files are stored in the subdirectory `windows_docker_layer_id/Files`
303- root_dir = os .path .join (root_dir , 'Files' )
325+ if root_prefix :
326+ # The rootfs location of a Docker image layer can be in a
327+ # subdirectory of the layer directory (where `root_dir` is the path
328+ # to the layer directory), so we append `root_prefix` (where prefix
329+ # is relative to the file paths within the Docker image layer's
330+ # rootfs files) to `root_dir`
331+ root_dir = os .path .join (root_dir , root_prefix )
304332
305333 absolute_install_location = create_absolute_installed_file_path (
306334 root_dir = root_dir ,
@@ -313,16 +341,11 @@ def populate_installed_files(self, root_dir, is_container=False):
313341 for root , _ , files in os .walk (absolute_install_location ):
314342 for file in files :
315343 installed_file_location = os .path .join (root , file )
316- if is_container :
317- relative_installed_file_path = create_relative_file_path (
318- file_path = installed_file_location ,
319- root_dir = original_root_dir
320- )
321- else :
322- relative_installed_file_path = create_relative_file_path (
323- file_path = installed_file_location ,
324- root_dir = root_dir
325- )
344+ relative_installed_file_path = create_relative_file_path (
345+ file_path = installed_file_location ,
346+ root_dir = root_dir ,
347+ root_prefix = root_prefix
348+ )
326349 installed_files .append (relative_installed_file_path )
327350
328351 known_program_files = self .extra_data .get ('known_program_files' , [])
@@ -331,16 +354,11 @@ def populate_installed_files(self, root_dir, is_container=False):
331354 root_dir = root_dir ,
332355 file_path = known_program_file_path ,
333356 )
334- if is_container :
335- relative_known_file_path = create_relative_file_path (
336- file_path = known_program_file_location ,
337- root_dir = original_root_dir
338- )
339- else :
340- relative_known_file_path = create_relative_file_path (
341- file_path = known_program_file_location ,
342- root_dir = root_dir
343- )
357+ relative_known_file_path = create_relative_file_path (
358+ file_path = known_program_file_location ,
359+ root_dir = root_dir ,
360+ root_prefix = root_prefix
361+ )
344362 if (not os .path .exists (known_program_file_location )
345363 or relative_known_file_path in installed_files ):
346364 continue
0 commit comments