@@ -23,14 +23,15 @@ import (
2323 "strings"
2424 "time"
2525
26- etchosts "github.com/Roblox/nomad-driver-containerd/etchosts"
2726 "github.com/containerd/containerd"
2827 "github.com/containerd/containerd/cio"
28+ "github.com/containerd/containerd/containers"
2929 "github.com/containerd/containerd/contrib/seccomp"
3030 "github.com/containerd/containerd/oci"
3131 refdocker "github.com/containerd/containerd/reference/docker"
3232 remotesdocker "github.com/containerd/containerd/remotes/docker"
3333 "github.com/docker/go-units"
34+ etchosts "github.com/hashistack4u/nomad-driver-containerd/etchosts"
3435 specs "github.com/opencontainers/runtime-spec/specs-go"
3536)
3637
@@ -93,10 +94,31 @@ func withResolver(creds CredentialsOpt) containerd.RemoteOpt {
9394 return containerd .WithResolver (resolver )
9495}
9596
97+ func withFileLimit (maxOpenFiles uint64 ) oci.SpecOpts {
98+ return func (_ context.Context , _ oci.Client , _ * containers.Container , spec * oci.Spec ) error {
99+ newRlimits := []specs.POSIXRlimit {{
100+ Type : "RLIMIT_NOFILE" ,
101+ Hard : maxOpenFiles ,
102+ Soft : maxOpenFiles ,
103+ }}
104+
105+ // Copy existing rlimits excluding previous RLIMIT_NOFILE
106+ for _ , rlimit := range spec .Process .Rlimits {
107+ if rlimit .Type != "RLIMIT_NOFILE" {
108+ newRlimits = append (newRlimits , rlimit )
109+ }
110+ }
111+
112+ spec .Process .Rlimits = newRlimits
113+
114+ return nil
115+ }
116+ }
117+
96118func (d * Driver ) pullImage (imageName , imagePullTimeout string , auth * RegistryAuth ) (containerd.Image , error ) {
97119 pullTimeout , err := time .ParseDuration (imagePullTimeout )
98120 if err != nil {
99- return nil , fmt .Errorf ("Failed to parse image_pull_timeout: %v" , err )
121+ return nil , fmt .Errorf ("failed to parse image_pull_timeout: %v" , err )
100122 }
101123
102124 ctxWithTimeout , cancel := context .WithTimeout (d .ctxContainerd , pullTimeout )
@@ -117,7 +139,7 @@ func (d *Driver) pullImage(imageName, imagePullTimeout string, auth *RegistryAut
117139
118140func (d * Driver ) createContainer (containerConfig * ContainerConfig , config * TaskConfig ) (containerd.Container , error ) {
119141 if config .Command != "" && config .Entrypoint != nil {
120- return nil , fmt .Errorf ("Both command and entrypoint are set. Only one of them needs to be set. " )
142+ return nil , fmt .Errorf ("both command and entrypoint are set. Only one of them needs to be set" )
121143 }
122144
123145 // Entrypoint or Command set by the user, to override entrypoint or cmd defined in the image.
@@ -146,7 +168,7 @@ func (d *Driver) createContainer(containerConfig *ContainerConfig, config *TaskC
146168 }
147169
148170 if ! d .config .AllowPrivileged && config .Privileged {
149- return nil , fmt .Errorf ("Running privileged jobs are not allowed. Set allow_privileged to true in plugin config to allow running privileged jobs. " )
171+ return nil , fmt .Errorf ("running privileged jobs are not allowed. Set allow_privileged to true in plugin config to allow running privileged jobs" )
150172 }
151173
152174 // Enable privileged mode.
@@ -161,17 +183,22 @@ func (d *Driver) createContainer(containerConfig *ContainerConfig, config *TaskC
161183
162184 if config .PidMode != "" {
163185 if strings .ToLower (config .PidMode ) != "host" {
164- return nil , fmt .Errorf ("Invalid pid_mode. Set pid_mode=host to enable host pid namespace. " )
186+ return nil , fmt .Errorf ("invalid pid_mode. Set pid_mode=host to enable host pid namespace" )
165187 } else {
166188 opts = append (opts , oci .WithHostNamespace (specs .PIDNamespace ))
167189 }
168190 }
169191
192+ // Set the resource limit for open file descriptors
193+ if config .FileLimit > 0 {
194+ opts = append (opts , withFileLimit (uint64 (config .FileLimit )))
195+ }
196+
170197 // Size of /dev/shm
171198 if len (config .ShmSize ) > 0 {
172199 shmBytes , err := units .RAMInBytes (config .ShmSize )
173200 if err != nil {
174- return nil , fmt .Errorf ("Error in setting shm_size: %v" , err )
201+ return nil , fmt .Errorf ("error in setting shm_size: %v" , err )
175202 }
176203 opts = append (opts , oci .WithDevShmSize (shmBytes / 1024 ))
177204 }
@@ -182,7 +209,7 @@ func (d *Driver) createContainer(containerConfig *ContainerConfig, config *TaskC
182209 }
183210
184211 if ! config .Seccomp && config .SeccompProfile != "" {
185- return nil , fmt .Errorf ("seccomp must be set to true, if using a custom seccomp_profile. " )
212+ return nil , fmt .Errorf ("seccomp must be set to true, if using a custom seccomp_profile" )
186213 }
187214
188215 // Enable default (or custom) seccomp profile.
@@ -217,6 +244,18 @@ func (d *Driver) createContainer(containerConfig *ContainerConfig, config *TaskC
217244 opts = append (opts , oci .WithDroppedCapabilities (config .CapDrop ))
218245 }
219246
247+ // This translates to docker create/run --cpuset-cpus option.
248+ // --cpuset-cpus limit the specific CPUs or cores a container can use.
249+ if config .CPUSetCPUs != "" {
250+ opts = append (opts , oci .WithCPUs (config .CPUSetCPUs ))
251+ }
252+
253+ // --cpuset-mems is the list of memory nodes on which processes
254+ // in this cpuset are allowed to allocate memory.
255+ if config .CPUSetMEMs != "" {
256+ opts = append (opts , oci .WithCPUsMems (config .CPUSetMEMs ))
257+ }
258+
220259 // Set current working directory (cwd).
221260 if config .Cwd != "" {
222261 opts = append (opts , oci .WithProcessCwd (config .Cwd ))
@@ -249,11 +288,11 @@ func (d *Driver) createContainer(containerConfig *ContainerConfig, config *TaskC
249288 mounts := make ([]specs.Mount , 0 )
250289 for _ , mount := range config .Mounts {
251290 if (mount .Type == "bind" || mount .Type == "volume" ) && len (mount .Options ) <= 0 {
252- return nil , fmt .Errorf ("Options cannot be empty for mount type: %s. You need to atleast pass rbind and ro. " , mount .Type )
291+ return nil , fmt .Errorf ("options cannot be empty for mount type: %s. You need to atleast pass rbind and ro" , mount .Type )
253292 }
254293
255294 // Allow paths relative to $NOMAD_TASK_DIR.
256- // More details: https://github.com/Roblox /nomad-driver-containerd/issues/116#issuecomment-983171458
295+ // More details: https://github.com/hashistack4u /nomad-driver-containerd/issues/116#issuecomment-983171458
257296 if mount .Type == "bind" && strings .HasPrefix (mount .Source , "local" ) {
258297 mount .Source = containerConfig .TaskDirSrc + mount .Source [5 :]
259298 }
@@ -264,8 +303,7 @@ func (d *Driver) createContainer(containerConfig *ContainerConfig, config *TaskC
264303
265304 // Setup host DNS (/etc/resolv.conf) into the container.
266305 if config .HostDNS {
267- dnsMount := buildMountpoint ("bind" , "/etc/resolv.conf" , "/etc/resolv.conf" , []string {"rbind" , "ro" })
268- mounts = append (mounts , dnsMount )
306+ opts = append (opts , oci .WithHostResolvconf )
269307 }
270308
271309 // Setup "/secrets" (NOMAD_SECRETS_DIR) in the container.
0 commit comments