@@ -140,6 +140,95 @@ def _pull_github(self, uri, dest=None):
140140 return self .client .pull (url , name = name , pull_folder = os .path .dirname (dest ))
141141
142142
143+ class PodmanContainer (ContainerTechnology ):
144+ """
145+ A Podman container controleer.
146+ """
147+
148+ # The module technology adds extensions here
149+ templatefile = "podman"
150+
151+ # TODO: how to define gpu for podman
152+ features = {"gpu" : {"nvidia" : "" , "amd" : "" }}
153+
154+ def __init__ (self ):
155+ print ("INIT" )
156+ import IPython
157+ IPython .embed ()
158+ try :
159+ from spython .main import Client
160+
161+ self .client = Client
162+ except :
163+ logger .exit ("podman (pip install podman) is required to use podman." )
164+
165+ def shell (self , image ):
166+ """
167+ Interactive shell into a container image.
168+ """
169+ print ("SHELL" )
170+ import IPython
171+ IPython .embed ()
172+ self .client .shell (image )
173+
174+ def pull (self , uri , dest ):
175+ """
176+ Pull a container to a destination
177+ """
178+ print ("PULL" )
179+ import IPython
180+ IPython .embed ()
181+
182+ if re .search ("^(docker|shub|https)" , uri ):
183+ return self ._pull (uri , dest )
184+ elif uri .startswith ("gh://" ):
185+ return self ._pull_github (uri , dest )
186+
187+ def _pull (self , uri , dest ):
188+ """
189+ Pull a URI that Singularity recognizes
190+ """
191+ pull_folder = os .path .dirname (dest )
192+ name = os .path .basename (dest )
193+ return self .client .pull (uri , name = name , pull_folder = pull_folder )
194+
195+ def inspect (self , image ):
196+ """
197+ Inspect an image and return metadata.
198+ """
199+ return self .client .inspect (image )
200+
201+ def _pull_github (self , uri , dest = None ):
202+ """
203+ Pull a singularity-deploy container to a destination
204+ """
205+ # Assemble the url based on the container uri
206+ uri = uri .replace ("gh://" , "" , 1 )
207+
208+ # repository name and image prefix
209+ repo = "/" .join (uri .split ("/" )[0 :2 ])
210+ prefix = repo .replace ("/" , "-" )
211+
212+ # The tag includes release and contianer tag (e.g., 0.0.1:latest)
213+ tag = uri .replace (repo , "" , 1 ).strip ("/" )
214+ github_tag , container_tag = tag .split (":" , 1 )
215+
216+ # Assemble the artifact url
217+ url = "https://github.com/%s/releases/download/%s/%s.%s.sif" % (
218+ repo ,
219+ github_tag ,
220+ prefix ,
221+ container_tag ,
222+ )
223+
224+ # If no destination, default to present working directory
225+ if not dest :
226+ dest = os .path .basename (url )
227+ name = os .path .basename (dest )
228+ return self .client .pull (url , name = name , pull_folder = os .path .dirname (dest ))
229+
230+
231+
143232class Tags :
144233 """Make it easy to interact with tags (name and version)"""
145234
0 commit comments