diff --git a/pkg/docker/Create.go b/pkg/docker/Create.go index cac3398..bf68e41 100644 --- a/pkg/docker/Create.go +++ b/pkg/docker/Create.go @@ -31,9 +31,6 @@ func (h *SidecarHandler) CreateHandler(w http.ResponseWriter, r *http.Request) { var req []commonIL.RetrievedPodData err = json.Unmarshal(bodyBytes, &req) - // log the received data - log.G(h.Ctx).Info("Received data: " + string(bodyBytes)) - if err != nil { HandleErrorAndRemoveData(h, w, statusCode, "Some errors occurred while creating container. Check Docker Sidecar's logs", err, nil) return @@ -49,53 +46,49 @@ func (h *SidecarHandler) CreateHandler(w http.ResponseWriter, r *http.Request) { for _, volume := range data.Pod.Spec.Volumes { if volume.HostPath != nil { if *volume.HostPath.Type == v1.HostPathDirectoryOrCreate || *volume.HostPath.Type == v1.HostPathDirectory { - _, err := os.Stat(volume.HostPath.Path + "/" + volume.Name) - if os.IsNotExist(err) { - log.G(h.Ctx).Info("-- Creating directory " + volume.HostPath.Path + "/" + volume.Name) - err = os.MkdirAll(volume.HostPath.Path+"/"+volume.Name, os.ModePerm) - if err != nil { + _, err := os.Stat(volume.HostPath.Path) + if *volume.HostPath.Type == v1.HostPathDirectory { + if os.IsNotExist(err) { HandleErrorAndRemoveData(h, w, statusCode, "Some errors occurred while creating container. Check Docker Sidecar's logs", err, &data) + return + } + pathsOfVolumes[volume.Name] = volume.HostPath.Path + } else if *volume.HostPath.Type == v1.HostPathDirectoryOrCreate { + if os.IsNotExist(err) { + err = os.MkdirAll(volume.HostPath.Path, os.ModePerm) + if err != nil { + HandleErrorAndRemoveData(h, w, statusCode, "Some errors occurred while creating container. Check Docker Sidecar's logs", err, &data) + return + } else { + pathsOfVolumes[volume.Name] = volume.HostPath.Path + } } else { - log.G(h.Ctx).Info("-- Created directory " + volume.HostPath.Path) - pathsOfVolumes[volume.Name] = volume.HostPath.Path + "/" + volume.Name + pathsOfVolumes[volume.Name] = volume.HostPath.Path } - } else { - log.G(h.Ctx).Info("-- Directory " + volume.HostPath.Path + "/" + volume.Name + " already exists") - pathsOfVolumes[volume.Name] = volume.HostPath.Path + "/" + volume.Name } } } + + if volume.PersistentVolumeClaim != nil { + if _, ok := pathsOfVolumes[volume.PersistentVolumeClaim.ClaimName]; !ok { + // WIP: This is a temporary solution to mount CVMFS volumes + pathsOfVolumes[volume.PersistentVolumeClaim.ClaimName] = "/mnt/cvmfs" + } + + } } - // define all containers, that is an object with two keys: 'initContainers' and 'containers'. The value of each key is an array of containers allContainers := map[string][]v1.Container{ "initContainers": data.Pod.Spec.InitContainers, "containers": data.Pod.Spec.Containers, } - // // if allContainers is greater than 0, create a network for the pod - // if len(allContainers) > 0 { - // // create a network for the pod - // shell := exec.ExecTask{ - // Command: "docker", - // Args: []string{"network", "create", podNamespace + "-" + podUID}, - // Shell: true, - // } - // shell.Execute() - // } - // iterate over all containers for containerType, containers := range allContainers { isInitContainer := containerType == "initContainers" for _, container := range containers { - if isInitContainer { - log.G(h.Ctx).Info("-- Init Container: " + container.Name) - } else { - log.G(h.Ctx).Info("-- Regular Container: " + container.Name) - } - containerName := podNamespace + "-" + podUID + "-" + container.Name var isGpuRequested bool = false @@ -105,12 +98,9 @@ func (h *SidecarHandler) CreateHandler(w http.ResponseWriter, r *http.Request) { numGpusRequested := val.Value() - log.G(h.Ctx).Infof("Number of GPU requested: %d", numGpusRequested) - // if the container is requesting 0 GPU, skip the GPU assignment if numGpusRequested == 0 { log.G(h.Ctx).Info("Container " + containerName + " is not requesting a GPU") - } else { log.G(h.Ctx).Info("Container " + containerName + " is requesting " + val.String() + " GPU") @@ -147,8 +137,6 @@ func (h *SidecarHandler) CreateHandler(w http.ResponseWriter, r *http.Request) { log.G(h.Ctx).Info("Container " + containerName + " is not requesting a GPU") } - log.G(h.Ctx).Info("-- Preparing environment variables for " + containerName) - var envVars string = "" // add environment variables to the docker command for _, envVar := range container.Env { @@ -173,15 +161,21 @@ func (h *SidecarHandler) CreateHandler(w http.ResponseWriter, r *http.Request) { log.G(h.Ctx).Error("Volume " + volumeMount.Name + " not found in pathsOfVolumes") continue } - if volumeMount.ReadOnly { envVars += " -v " + pathsOfVolumes[volumeMount.Name] + ":" + volumeMount.MountPath + ":ro" } else { - envVars += " -v " + pathsOfVolumes[volumeMount.Name] + ":" + volumeMount.MountPath + // if it is Bidirectional, add :shared to the volume + if *volumeMount.MountPropagation == v1.MountPropagationBidirectional { + envVars += " -v " + pathsOfVolumes[volumeMount.Name] + ":" + volumeMount.MountPath + ":shared" + } else { + envVars += " -v " + pathsOfVolumes[volumeMount.Name] + ":" + volumeMount.MountPath + } } } } + //docker run --privileged -v /home:/home -d --name demo1 docker:dind + log.G(h.Ctx).Info("- Creating container " + containerName) cmd := []string{"run", "-d", "--name", containerName} diff --git a/pkg/docker/aux.go b/pkg/docker/aux.go index 3b9aebe..1249136 100644 --- a/pkg/docker/aux.go +++ b/pkg/docker/aux.go @@ -58,42 +58,44 @@ func parseContainerCommandAndReturnArgs(Ctx context.Context, config commonIL.Int } if len(container.Command) > 0 { - if container.Command[0] == "/bin/bash" || container.Command[0] == "/bin/sh" { - fileName := prefileName + "_script.sh" - if len(container.Command) > 1 { - if strings.HasSuffix(container.Command[1], ".sh") { - return []string{}, container.Command, container.Args, nil - } - if container.Command[1] == "-c" { - // get the actual current path of the folder - fileNamePath := filepath.Join(wd, config.DataRootFolder+podNamespace+"-"+podUID, fileName) - log.G(Ctx).Info("Creating file " + fileNamePath) - err = os.WriteFile(fileNamePath, []byte(container.Args[0]), 0644) - if err != nil { - log.G(Ctx).Error(err) - return nil, nil, nil, err - } - return []string{"-v " + fileNamePath + ":/" + fileName}, []string{container.Command[0] + " /" + fileName}, []string{}, nil - } - } - } else if strings.HasPrefix(container.Command[0], "python") { - fileName := prefileName + "_script.py" - if container.Command[1] == "-c" { - fileNamePath := filepath.Join(wd, config.DataRootFolder+podNamespace+"-"+podUID, fileName) - log.G(Ctx).Info("Creating file " + fileNamePath) - err = os.WriteFile(fileNamePath, []byte(container.Args[0]), 0644) - if err != nil { - log.G(Ctx).Error(err) - return nil, nil, nil, err - } - return []string{"-v " + fileNamePath + ":/" + fileName}, []string{container.Command[0] + " /" + fileName}, []string{}, nil + + fileName := prefileName + "_script.sh" + + if len(container.Args) == 0 { + fileNamePath := filepath.Join(wd, config.DataRootFolder+podNamespace+"-"+podUID, fileName) + log.G(Ctx).Info("Creating file " + fileNamePath) + err = os.WriteFile(fileNamePath, []byte(strings.Join(container.Command, " ")), 0644) + if err != nil { + log.G(Ctx).Error(err) + return nil, nil, nil, err } - } else { - return []string{}, container.Command, container.Args, nil + return []string{"-v " + fileNamePath + ":/" + fileName}, []string{"/bin/sh" + " /" + fileName}, []string{}, nil } + argsFileName := container.Name + "_args" + argsFileNamePath := filepath.Join(wd, config.DataRootFolder+podNamespace+"-"+podUID, argsFileName) + log.G(Ctx).Info("Creating file " + argsFileNamePath) + err = os.WriteFile(argsFileNamePath, []byte(strings.Join(container.Args, " ")), 0644) + if err != nil { + log.G(Ctx).Error(err) + return nil, nil, nil, err + } + + fullFileContent := strings.Join(container.Command, " ") + " \"$(cat " + argsFileName + ")\"" + fullFileNamePath := filepath.Join(wd, config.DataRootFolder+podNamespace+"-"+podUID, fileName) + log.G(Ctx).Info("Creating file " + fullFileNamePath) + err = os.WriteFile(fullFileNamePath, []byte(fullFileContent), 0644) + if err != nil { + log.G(Ctx).Error(err) + return nil, nil, nil, err + } + + // mount also the args file + return []string{"-v " + argsFileNamePath + ":/" + argsFileName, "-v " + fullFileNamePath + ":/" + fileName}, []string{"/bin/sh" + " /" + fileName}, []string{}, nil + + } else { + return []string{}, container.Command, container.Args, nil } - return []string{}, container.Command, container.Args, nil } // prepareMounts iterates along the struct provided in the data parameter and checks for ConfigMaps, Secrets and EmptyDirs to be mounted. @@ -353,16 +355,17 @@ func mountData(Ctx context.Context, config commonIL.InterLinkConfig, pod v1.Pod, emptyDirMountPath := "" isReadOnly := false - //isBidirectional := false + isBidirectional := false + for _, mountSpec := range container.VolumeMounts { if mountSpec.Name == vol.Name { emptyDirMountPath = mountSpec.MountPath if mountSpec.ReadOnly { isReadOnly = true } - // if mountSpec.MountPropagation != nil && *mountSpec.MountPropagation == v1.MountPropagationBidirectional { - // isBidirectional = true - // } + if mountSpec.MountPropagation != nil && *mountSpec.MountPropagation == v1.MountPropagationBidirectional { + isBidirectional = true + } break } } @@ -388,7 +391,11 @@ func mountData(Ctx context.Context, config commonIL.InterLinkConfig, pod v1.Pod, if isReadOnly { edPath += (":" + emptyDirMountPath + "/:ro") } else { - edPath += (":" + emptyDirMountPath + "/") + if isBidirectional { + edPath += (":" + emptyDirMountPath + "/:shared") + } else { + edPath += (":" + emptyDirMountPath + "/") + } } return []string{edPath}, nil