@@ -101,13 +101,41 @@ def help(self,command=None,stdout=True):
101101 return help
102102
103103
104- def println (self ,output ):
105- '''print will print the output, given that quiet is not True
104+ def println (self ,output ,quiet = False ):
105+ '''print will print the output, given that quiet is not True. This
106+ function also serves to convert output in bytes to utf-8
106107 '''
107- if self .quiet is False :
108- if isinstance (output ,bytes ):
109- output = output .decode ('utf-8' )
108+ if isinstance (output ,bytes ):
109+ output = output .decode ('utf-8' )
110+
111+ if self .quiet is False and quiet is False :
110112 print (output )
113+ return output
114+
115+
116+ def bootstrap (self ,image_path ,spec_path ):
117+ '''create will bootstrap an image using a spec
118+ :param image_path: full path to image
119+ :param spec_path: full path to the spec file (Singularity)
120+ '''
121+ if self .debug == True :
122+ cmd = ['singularity' ,'--debug' ,'bootstrap' ,image_path ,spec_path ]
123+ else :
124+ cmd = ['singularity' ,'bootstrap' ,image_path ,spec_path ]
125+ output = self .run_command (cmd ,sudo = True )
126+ output = self .println (output )
127+ return image_path
128+
129+
130+ def compress (self ,image_path ):
131+ '''compress will (properly) compress an image'''
132+ if os .path .exists (image_path ):
133+ compressed_image = "%s.gz" % image_path
134+ os .system ('gzip -c -9 %s > %s' % (image_path ,compressed_image ))
135+ return compressed_image
136+ else :
137+ bot .logger .error ("Cannot find image %s" ,image_path )
138+ return None
111139
112140
113141 def create (self ,image_path ,size = None ,sudo = False ):
@@ -124,24 +152,21 @@ def create(self,image_path,size=None,sudo=False):
124152 else :
125153 cmd = ['singularity' ,'create' ,'--size' ,str (size ),image_path ]
126154 output = self .run_command (cmd ,sudo = sudo )
127- self .println (output )
155+ output = self .println (output )
128156 if os .path .exists (image_path ):
129157 return image_path
130158 return None
131159
132160
133- def bootstrap ( self , image_path , spec_path ):
134- '''create will bootstrap an image using a spec
135- :param image_path: full path to image
136- :param spec_path: full path to the spec file (Singularity)
137- '''
138- if self . debug == True :
139- cmd = [ 'singularity' , '--debug' , 'bootstrap' , image_path , spec_path ]
161+
162+ def decompress ( self , image_path ):
163+ '''decompress will (properly) decompress an image'''
164+ if os . path . exists ( image_path ):
165+ extracted_file = image_path . replace ( '.gz' , '' )
166+ os . system ( 'gzip -d -f %s' % image_path )
167+ return extracted_file
140168 else :
141- cmd = ['singularity' ,'bootstrap' ,image_path ,spec_path ]
142- output = self .run_command (cmd ,sudo = True )
143- self .println (output )
144- return image_path
169+ bot .logger .error ("Cannot find image %s" ,image_path )
145170
146171
147172 def execute (self ,image_path ,command ,writable = False ,contain = False ):
@@ -205,42 +230,74 @@ def importcmd(self,image_path,input_source):
205230 '''
206231 cmd = ['singularity' ,'import' ,image_path ,input_source ]
207232 output = self .run_command (cmd ,sudo = False )
208- self .println (output )
233+ output = self .println (output )
209234 return image_path
210235
211236
212- def pull (self ,image_path ,pull_folder = None ,name_by = None ):
237+ def inspect (self ,image_path ,json = True ,labels = True ,
238+ runscript = True ,test = True ,deffile = True ,
239+ environment = True ,quiet = False ):
240+ '''inspect will show labels, defile, runscript, and tests for an image
241+ :param image_path: path of image to inspect
242+ :param json: print json instead of raw text (default True)
243+ :param labels: show labels (default True):
244+ :param runscript: show runscript (default True)
245+ :param test: show test file (default True)
246+ :param environment: show environment (default True)
247+ '''
248+ cmd = ['singularity' ,'--quiet' ,'inspect' ]
249+ options = locals ()
250+ acceptable = ['environment' ,'json' ,'deffile' ,'labels' ,'runscript' ,'test' ]
251+ for key ,option in options .items ():
252+ if key in acceptable :
253+ if option is True :
254+ cmd .append ('--%s' % (key ))
255+
256+ cmd .append (image_path )
257+ output = self .run_command (cmd )
258+ output = self .println (output ,quiet = quiet )
259+ return output
260+
261+
262+ def pull (self ,image_path ,pull_folder = None ,name_by = None ,image_name = None ):
213263 '''pull will pull a singularity hub image
214264 :param image_path: full path to image
215265 :param name_by: can be one of commit or hash, default is by image name
216266 '''
217- if name_by is None :
218- name_by = "name"
219- name_by = name_by .lower ()
267+ if image_name is not None :
268+ name_by = None
269+ if name_by is not None :
270+ name_by = name_by .lower ()
220271
221272 if pull_folder is not None :
222273 os .environ ['SINGULARITY_PULLFOLDER' ] = pull_folder
223274
224- if not image_path .startswith ('shub://' ):
225- bot .logger .error ("pull is only valid for the shub://uri , %s is invalid." ,image_name )
275+ if not image_path .startswith ('shub://' ) or not image_path . startswith ( 'docker://' ) :
276+ bot .logger .error ("pull is only valid for docker and shub, %s is invalid." ,image_name )
226277 sys .exit (1 )
227278
228279 if self .debug == True :
229280 cmd = ['singularity' ,'--debug' ,'pull' ]
230281 else :
231282 cmd = ['singularity' ,'pull' ]
232283
233- if name_by in ['name' ,'commit' ,'hash' ]:
234- bot .logger .debug ("user specified naming pulled image by %s" ,name_by )
235- name_by = "--%s " % name_by
236- cmd .append (name_by )
284+ if image_path .startswith ('shub://' ):
285+ if name_by in ['commit' ,'hash' ]:
286+ bot .logger .debug ("user specified naming pulled image by %s" ,name_by )
287+ name_by = "--%s " % name_by
288+ cmd .append (name_by )
289+ elif image_name is not None :
290+ name_by = "--name %s" % (image_name )
291+
292+ elif image_path .startswith ('docker://' ):
293+ if image_name is not None :
294+ bot .logger .debug ("user specified name of image as %s" ,image_name )
295+ name_by = "--name %s" % (image_name )
237296
238297 cmd .append (image_path )
239298
240299 output = self .run_command (cmd )
241- self .println (output )
242- if isinstance (output ,bytes ):
243- output = output .decode ('utf-8' )
300+ output = self .println (output ,quiet = True )
244301 return output .split ("Container is at:" )[- 1 ].strip ('\n ' ).strip ()
245302
246303
@@ -266,8 +323,7 @@ def run(self,image_path,args=None,writable=False,contain=False):
266323 cmd = cmd + args
267324
268325 result = self .run_command (cmd ,sudo = sudo )
269- if isinstance (result ,bytes ):
270- result = result .decode ('utf-8' )
326+ result = self .println (result ,quiet = True )
271327 result = result .strip ('\n ' )
272328 try :
273329 result = json .loads (result )
@@ -281,8 +337,7 @@ def get_labels(self,image_path):
281337 '''
282338 cmd = ['singularity' ,'exec' ,image_path ,'cat' ,'/.singularity/labels.json' ]
283339 labels = self .run_command (cmd )
284- if isinstance (labels ,bytes ):
285- labels = labels .decode ('utf-8' )
340+ labels = self .println (labels ,quiet = True )
286341 if len (labels ) > 0 :
287342 return json .loads (labels )
288343 return labels
@@ -302,13 +357,11 @@ def get_args(self,image_path):
302357 return args
303358
304359
305- def add_flags (self ,cmd ,writable ,contain ):
360+ def add_flags (self ,cmd ,writable = False ,contain = False ):
306361 '''check_args is a general function for adding flags to a command list
307362 :param writable: adds --writable
308363 :param contain: adds --contain
309- '''
310-
311- # Does the user want to make the container writeable?
364+ '''
312365 if writable == True :
313366 cmd .append ('--writable' )
314367
0 commit comments