11'''
22
3- Copyright (C) 2017 The Board of Trustees of the Leland Stanford Junior
4- University.
5- Copyright (C) 2016-2017 Vanessa Sochat.
3+ Copyright (C) 2016-2019 Vanessa Sochat.
64
75This program is free software: you can redistribute it and/or modify it
86under the terms of the GNU Affero General Public License as published by
@@ -43,8 +41,14 @@ def extract_guts(image_path,
4341 tag_root = True ,
4442 include_sizes = True ):
4543
46- '''extract the file guts from an in memory tarfile. The file is not closed.
47- This should not be done for large images.
44+ '''extract the file guts from an image.
45+
46+ Parameters
47+ ==========
48+ image_path: can be a tar, a Singularity image (sif) or a sandbox
49+ file_filter: the file filter to extract guts for.
50+ tag_root: if True (default) include if root owned or not.
51+ include_sizes: include content sizes (defaults to True)
4852 '''
4953 if file_filter is None :
5054 file_filter = get_level ('IDENTICAL' )
@@ -59,33 +63,44 @@ def extract_guts(image_path,
5963 if include_sizes :
6064 sizes = dict ()
6165
62- # Export the image
63- sandbox = Client .export (image_path )
66+ # Option 1: We are given a sandbox
67+ if os .path .isdir (image_path ):
68+ sandbox = image_path
69+
70+ # Option 2: it's not a sandbox, and we need to export.
71+ elif 'version 3' in get_singularity_version ():
72+ sandbox = Client .export (image_path )
73+ else :
74+ sandbox = Client .image .export (image_path )
6475
6576 # If it's tar, extract
66- if sandbox .endswith ('tar' ):
77+ if os . path . isfile ( sandbox ) and sandbox .endswith ('tar' ):
6778 with tarfile .open (sandbox ) as tar :
6879 sandbox = os .path .join (os .path .dirname (sandbox ), 'sandbox' )
6980 tar .extractall (path = sandbox )
7081
7182 # Recursively walk through sandbox
7283 for root , dirnames , filenames in os .walk (sandbox ):
7384 for filename in filenames :
74- member_name = os .path .join (root , filename )
85+ sandbox_name = os .path .join (root , filename )
86+
87+ # Remove the sandbox base
88+ member_name = sandbox_name .lstrip (sandbox )
89+
7590 allfiles .append (member_name )
7691 included = False
7792
7893 # Skip over directories and symbolic links
79- if os .path .isdir (member_name ) or os .path .islink (member_name ):
94+ if os .path .isdir (sandbox_name ) or os .path .islink (sandbox_name ):
8095 continue
8196
8297 # If we have flagged to include, and not flagged to skip
83- elif assess_content (member_name , file_filter ):
84- digest [member_name ] = extract_content (member_name , return_hash = True )
98+ elif assess_content (sandbox_name , file_filter ):
99+ digest [member_name ] = extract_content (sandbox_name , return_hash = True )
85100 included = True
86- elif include_file (member_name , file_filter ):
101+ elif include_file (sandbox_name , file_filter ):
87102 hasher = hashlib .md5 ()
88- with open (member_name , 'rb' ) as filey :
103+ with open (sandbox_name , 'rb' ) as filey :
89104 buf = filey .read ()
90105 hasher .update (buf )
91106 digest [member_name ] = hasher .hexdigest ()
@@ -94,9 +109,9 @@ def extract_guts(image_path,
94109 # Derive size, and if root owned
95110 if included :
96111 if include_sizes :
97- sizes [member_name ] = os .stat (member_name ).st_size
112+ sizes [member_name ] = os .stat (sandbox_name ).st_size
98113 if tag_root :
99- roots [member_name ] = is_root_owned (member_name )
114+ roots [member_name ] = is_root_owned (sandbox_name )
100115
101116 results ['all' ] = allfiles
102117 results ['hashes' ] = digest
@@ -107,16 +122,6 @@ def extract_guts(image_path,
107122 return results
108123
109124
110-
111- def get_memory_tar (image_path ):
112- '''get an in memory tar of an image. Use carefully, not as reliable
113- as get_image_tar
114- '''
115- byte_array = Client .export (image_path )
116- file_object = io .BytesIO (byte_array )
117- tar = tarfile .open (mode = "r|*" , fileobj = file_object )
118- return (file_object , tar )
119-
120125def create_tarfile (source_dir , output_filename = None ):
121126 ''' create a tarfile from a source directory'''
122127 if output_filename == None :
0 commit comments