22
33import reframe .core .fields as fields
44import reframe .utility .typecheck as typ
5- from reframe .core .exceptions import ContainerPlatformError
5+ from reframe .core .exceptions import ContainerError
66
77
88class ContainerPlatform :
@@ -15,72 +15,83 @@ class ContainerPlatform:
1515 registry = fields .TypedField ('registry' , str , type (None ))
1616 image = fields .TypedField ('image' , str , type (None ))
1717 requires_mpi = fields .TypedField ('requires_mpi' , bool )
18- commands = fields .TypedField ('commands' , typ .List [str ], type ( None ) )
18+ commands = fields .TypedField ('commands' , typ .List [str ])
1919 mount_points = fields .TypedField ('mount_points' ,
20- typ .List [typ .Tuple [str , str ]], type (None ))
20+ typ .List [typ .Tuple [str , str ]])
21+ workdir = fields .TypedField ('workdir' , str , type (None ))
2122
2223 def __init__ (self ):
2324 self .registry = None
2425 self .image = None
2526 self .requires_mpi = False
26- self .commands = None
27+ self .commands = []
2728 self .mount_points = []
29+ self .workdir = None
2830
2931 @abc .abstractmethod
3032 def emit_prepare_cmds (self ):
31- """xxx."""
33+ """Returns commands that are necessary before running with this
34+ container platform.
35+
36+ :raises: `ContainerError` in case of errors.
37+
38+ .. note:
39+ This method is relevant only to developers of new container
40+ platforms.
41+ """
3242
3343 @abc .abstractmethod
3444 def emit_launch_cmds (self ):
3545 """Returns the command for running with this container platform.
3646
37- :raises: `ContainerPlatformError` in case of missing mandatory
38- fields.
47+ :raises: `ContainerError` in case of errors.
48+
49+ .. note:
50+ This method is relevant only to developers of new container
51+ platforms.
52+ """
53+ if self .registry :
54+ self .image = '/' .join ([self .registry , self .image ])
55+
56+ @abc .abstractmethod
57+ def validate (self ):
58+ """Validates this container platform.
59+
60+ :raises: `ContainerError` in case of errors.
3961
4062 .. note:
4163 This method is relevant only to developers of new container
42- plataforms .
64+ platforms .
4365 """
66+ if self .image is None :
67+ raise ContainerError ('no image specified.' )
68+
69+ if not self .commands :
70+ raise ContainerError ('no command specified' )
4471
4572
4673class Docker (ContainerPlatform ):
47- """An implementation of the container platform to run containers with
74+ """An implementation of ContainerPlatform to run containers with
4875 Docker.
4976 """
50- # def __init__(self):
51- # super().__init__()
52-
5377 def emit_prepare_cmds (self ):
5478 pass
5579
5680 def emit_launch_commands (self ):
81+ super ().emit_launch_cmds ()
5782 docker_opts = []
58-
59- if self .image is None :
60- raise ContainerPlatformError ('Please, specify the name of'
61- 'the image' )
62-
63- if self .commands is None :
64- raise ContainerPlatformError ('Please, specify a command' )
65-
66- if self .registry :
67- self .image = '%s/%s' % (self .registry , self .image )
68-
69- self .mount_points .append (('$PWD' , '/stagedir' ))
70- for mp in self .mount_points :
71- docker_opts .append ('-v %s:%s' % mp )
72-
73- cmd_base = "docker run %s %s bash -c 'cd /stagedir; %s'"
74-
75- return [cmd_base % (' ' .join (docker_opts ), self .image ,
76- '; ' .join (self .commands ))]
83+ docker_opts = ['-v "%s":"%s"' % mp for mp in self .mount_points ]
84+ run_cmd = 'docker run %s %s bash -c ' % (' ' .join (docker_opts ),
85+ self .image )
86+ return run_cmd + "'" + '; ' .join (
87+ ['cd ' + self .workdir ] + self .commands ) + "'"
7788
7889
7990class ContainerPlatformField (fields .TypedField ):
80- """A field representing a build system .
91+ """A field representing a container platforms .
8192
8293 You may either assign an instance of :class:`ContainerPlatform:` or a
83- string representing the name of the concrete class of a build system .
94+ string representing the name of the concrete class of a container platform .
8495 """
8596
8697 def __init__ (self , fieldname , * other_types ):
0 commit comments