Skip to content

Commit 0fe3547

Browse files
committed
updated handle of arguments; handle container limits when requested from POD; fixed little bug on volume mounting; fixed return error code
1 parent 3bee2ab commit 0fe3547

File tree

3 files changed

+138
-11
lines changed

3 files changed

+138
-11
lines changed

pkg/docker/Create.go

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,44 @@ func (h *SidecarHandler) CreateHandler(w http.ResponseWriter, r *http.Request) {
181181
cmd = append(cmd, mounts)
182182
}
183183

184+
memoryLimitsArray := []string{}
185+
cpuLimitsArray := []string{}
186+
187+
if container.Resources.Limits.Memory().Value() != 0 {
188+
memoryLimitsArray = append(memoryLimitsArray, "--memory", strconv.Itoa(int(container.Resources.Limits.Memory().Value()))+"b")
189+
}
190+
if container.Resources.Limits.Cpu().Value() != 0 {
191+
cpuLimitsArray = append(cpuLimitsArray, "--cpus", strconv.FormatFloat(float64(container.Resources.Limits.Cpu().Value()), 'f', -1, 64))
192+
}
193+
194+
cmd = append(cmd, memoryLimitsArray...)
195+
cmd = append(cmd, cpuLimitsArray...)
196+
197+
containerCommands := []string{}
198+
containerArgs := []string{}
199+
mountFileCommand := []string{}
200+
201+
// if container has a command and args, call parseContainerCommandAndReturnArgs
202+
if len(container.Command) > 0 || len(container.Args) > 0 {
203+
log.G(h.Ctx).Info("Container has command and args defined. Parsing...")
204+
log.G(h.Ctx).Info("Container command: " + strings.Join(container.Command, " "))
205+
log.G(h.Ctx).Info("Container args: " + strings.Join(container.Args, " "))
206+
207+
mountFileCommand, containerCommands, containerArgs, err = parseContainerCommandAndReturnArgs(h.Ctx, h.Config, req, container)
208+
if err != nil {
209+
HandleErrorAndRemoveData(h, w, statusCode, "Some errors occurred while creating container. Check Docker Sidecar's logs", err, &data)
210+
return
211+
}
212+
cmd = append(cmd, mountFileCommand...)
213+
}
214+
215+
// log container commands and args
216+
log.G(h.Ctx).Info("Container commands: " + strings.Join(containerCommands, " "))
217+
log.G(h.Ctx).Info("Container args: " + strings.Join(containerArgs, " "))
218+
184219
cmd = append(cmd, container.Image)
185-
cmd = append(cmd, container.Command...)
186-
cmd = append(cmd, container.Args...)
220+
cmd = append(cmd, containerCommands...)
221+
cmd = append(cmd, containerArgs...)
187222

188223
dockerOptions := ""
189224

@@ -194,15 +229,14 @@ func (h *SidecarHandler) CreateHandler(w http.ResponseWriter, r *http.Request) {
194229
}
195230
}
196231

197-
// print the docker command
198-
log.G(h.Ctx).Info("Docker command: " + "docker" + dockerOptions + " " + strings.Join(cmd, " "))
199-
200232
shell := exec.ExecTask{
201233
Command: "docker" + dockerOptions,
202234
Args: cmd,
203235
Shell: true,
204236
}
205237

238+
log.G(h.Ctx).Info("Docker command: " + strings.Join(shell.Args, " "))
239+
206240
execReturn, err = shell.Execute()
207241
if err != nil {
208242
HandleErrorAndRemoveData(h, w, statusCode, "Some errors occurred while creating container. Check Docker Sidecar's logs", err, &data)

pkg/docker/Status.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55
"io"
66
"net/http"
7+
"strconv"
78
"strings"
89

910
exec "github.com/alexellis/go-execute/pkg/v1"
@@ -46,7 +47,7 @@ func (h *SidecarHandler) StatusHandler(w http.ResponseWriter, r *http.Request) {
4647
resp = append(resp, commonIL.PodStatus{PodName: pod.Name, PodUID: podUID, PodNamespace: podNamespace})
4748
for _, container := range pod.Spec.Containers {
4849
containerName := podNamespace + "-" + podUID + "-" + container.Name
49-
50+
5051
log.G(h.Ctx).Debug("- Getting status for container " + containerName)
5152
cmd := []string{"ps -af name=^" + containerName + "$ --format \"{{.Status}}\""}
5253

@@ -70,13 +71,20 @@ func (h *SidecarHandler) StatusHandler(w http.ResponseWriter, r *http.Request) {
7071
if execReturn.Stdout != "" {
7172
if containerstatus[0] == "Created" {
7273
log.G(h.Ctx).Info("-- Container " + containerName + " is going ready...")
73-
resp[i].Containers = append(resp[i].Containers,v1.ContainerStatus{Name: container.Name, State: v1.ContainerState{Waiting: &v1.ContainerStateWaiting{}}, Ready: false})
74+
resp[i].Containers = append(resp[i].Containers, v1.ContainerStatus{Name: container.Name, State: v1.ContainerState{Waiting: &v1.ContainerStateWaiting{}}, Ready: false})
7475
} else if containerstatus[0] == "Up" {
7576
log.G(h.Ctx).Info("-- Container " + containerName + " is running")
76-
resp[i].Containers = append(resp[i].Containers,v1.ContainerStatus{Name: container.Name, State: v1.ContainerState{Running: &v1.ContainerStateRunning{}}, Ready: true})
77+
resp[i].Containers = append(resp[i].Containers, v1.ContainerStatus{Name: container.Name, State: v1.ContainerState{Running: &v1.ContainerStateRunning{}}, Ready: true})
7778
} else if containerstatus[0] == "Exited" {
7879
log.G(h.Ctx).Info("-- Container " + containerName + " has been stopped")
79-
resp[i].Containers = append(resp[i].Containers,v1.ContainerStatus{Name: container.Name, State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{}}, Ready: false})
80+
containerExitCode := strings.Split(containerstatus[1], "(")
81+
exitCode, err := strconv.Atoi(strings.Trim(containerExitCode[1], ")"))
82+
if err != nil {
83+
log.G(h.Ctx).Error(err)
84+
exitCode = 0
85+
}
86+
log.G(h.Ctx).Info("-- Container exit code is: " + strconv.Itoa(exitCode))
87+
resp[i].Containers = append(resp[i].Containers, v1.ContainerStatus{Name: container.Name, State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{ExitCode: int32(exitCode)}}, Ready: false})
8088
// release all the GPUs from the container
8189
h.GpuManager.Release(containerName)
8290
}

pkg/docker/aux.go

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,65 @@ type SidecarHandler struct {
2323
GpuManager gpustrategies.GPUManagerInterface
2424
}
2525

26+
func parseContainerCommandAndReturnArgs(Ctx context.Context, config commonIL.InterLinkConfig, data []commonIL.RetrievedPodData, container v1.Container) ([]string, []string, []string, error) {
27+
28+
podUID := ""
29+
podNamespace := ""
30+
31+
for _, podData := range data {
32+
podUID = string(podData.Pod.UID)
33+
podNamespace = string(podData.Pod.Namespace)
34+
}
35+
36+
if container.Command == nil {
37+
return []string{}, container.Command, container.Args, nil
38+
}
39+
40+
wd, err := os.Getwd()
41+
if err != nil {
42+
log.G(Ctx).Error(err)
43+
return nil, nil, nil, err
44+
}
45+
46+
if len(container.Command) > 0 {
47+
if container.Command[0] == "/bin/bash" || container.Command[0] == "/bin/sh" {
48+
fileName := "script.sh"
49+
if len(container.Command) > 1 {
50+
if strings.HasSuffix(container.Command[1], ".sh") {
51+
return []string{}, container.Command, container.Args, nil
52+
}
53+
if container.Command[1] == "-c" {
54+
// get the actual current path of the folder
55+
fileNamePath := filepath.Join(wd, config.DataRootFolder+podNamespace+"-"+podUID, fileName)
56+
log.G(Ctx).Info("Creating file " + fileNamePath)
57+
err = os.WriteFile(fileNamePath, []byte(container.Args[0]), 0644)
58+
if err != nil {
59+
log.G(Ctx).Error(err)
60+
return nil, nil, nil, err
61+
}
62+
return []string{"-v " + fileNamePath + ":/" + fileName}, []string{container.Command[0] + " /" + fileName}, []string{}, nil
63+
}
64+
}
65+
} else if strings.HasPrefix(container.Command[0], "python") {
66+
fileName := "script.py"
67+
if container.Command[1] == "-c" {
68+
fileNamePath := filepath.Join(wd, config.DataRootFolder+podNamespace+"-"+podUID, fileName)
69+
log.G(Ctx).Info("Creating file " + fileNamePath)
70+
err = os.WriteFile(fileNamePath, []byte(container.Args[0]), 0644)
71+
if err != nil {
72+
log.G(Ctx).Error(err)
73+
return nil, nil, nil, err
74+
}
75+
return []string{"-v " + fileNamePath + ":/" + fileName}, []string{container.Command[0] + " /" + fileName}, []string{}, nil
76+
}
77+
} else {
78+
return []string{}, container.Command, container.Args, nil
79+
}
80+
81+
}
82+
return []string{}, container.Command, container.Args, nil
83+
}
84+
2685
// prepareMounts iterates along the struct provided in the data parameter and checks for ConfigMaps, Secrets and EmptyDirs to be mounted.
2786
// For each element found, the mountData function is called.
2887
// It returns a string composed as the docker -v command to bind mount directories and files and the first encountered error.
@@ -79,6 +138,7 @@ func prepareMounts(Ctx context.Context, config commonIL.InterLinkConfig, data []
79138
}
80139

81140
for _, emptyDir := range cont.EmptyDirs {
141+
log.G(Ctx).Info("-- EmptyDir to handle " + emptyDir)
82142
if containerName == podNamespace+"-"+podUID+"-"+cont.Name {
83143
paths, err := mountData(Ctx, config, podData.Pod, emptyDir, container)
84144
if err != nil {
@@ -257,6 +317,25 @@ func mountData(Ctx context.Context, config commonIL.InterLinkConfig, pod v1.Pod,
257317
if podVolumeSpec != nil && podVolumeSpec.EmptyDir != nil {
258318
var edPath string
259319

320+
parts := strings.Split(data.(string), "/")
321+
emptyDirName := parts[len(parts)-1]
322+
if emptyDirName != vol.Name {
323+
log.G(Ctx).Info("Skipping " + vol.Name + " as it is not the same as " + emptyDirName)
324+
continue
325+
}
326+
327+
emptyDirMountPath := ""
328+
isReadOnly := false
329+
for _, mountSpec := range container.VolumeMounts {
330+
if mountSpec.Name == vol.Name {
331+
emptyDirMountPath = mountSpec.MountPath
332+
if mountSpec.ReadOnly {
333+
isReadOnly = true
334+
}
335+
break
336+
}
337+
}
338+
260339
edPath = filepath.Join(wd+"/"+config.DataRootFolder, string(pod.UID)+"/"+"emptyDirs/"+vol.Name)
261340
log.G(Ctx).Info("-- Creating EmptyDir in " + edPath)
262341
cmd := []string{"-p " + edPath}
@@ -274,8 +353,14 @@ func mountData(Ctx context.Context, config commonIL.InterLinkConfig, pod v1.Pod,
274353
log.G(Ctx).Debug("-- Created EmptyDir in " + edPath)
275354
}
276355

277-
edPath += (":" + mountSpec.MountPath + "/")
278-
return []string{edPath}, nil
356+
// if the emptyDir is read only, append :ro to the path
357+
if isReadOnly {
358+
edPath += (":" + emptyDirMountPath + "/:ro")
359+
return []string{edPath}, nil
360+
} else {
361+
edPath += (":" + emptyDirMountPath + "/")
362+
return []string{edPath}, nil
363+
}
279364
}
280365
}
281366
}

0 commit comments

Comments
 (0)