Skip to content

Commit

Permalink
added support for bidirection volumes
Browse files Browse the repository at this point in the history
  • Loading branch information
Bianco95 committed Jun 11, 2024
1 parent 4f56c88 commit 3546251
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 75 deletions.
70 changes: 32 additions & 38 deletions pkg/docker/Create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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")
Expand Down Expand Up @@ -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 {
Expand All @@ -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}
Expand Down
81 changes: 44 additions & 37 deletions pkg/docker/aux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
}
}
Expand All @@ -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
Expand Down

0 comments on commit 3546251

Please sign in to comment.