Skip to content
Snippets Groups Projects
Commit 86588463 authored by Max Goltzsche's avatar Max Goltzsche Committed by Derek Su
Browse files

Merge pod template's volumeMount.


The helper Pod template's `data` volumeMount is merged with the defaults in order to allow users to specify the `mountPropagation` within the template.

Closes #165

Signed-off-by: default avatarMax Goltzsche <max.goltzsche@gmail.com>
parent 43f29411
No related branches found
No related tags found
No related merge requests found
...@@ -31,6 +31,10 @@ const ( ...@@ -31,6 +31,10 @@ const (
KeyNode = "kubernetes.io/hostname" KeyNode = "kubernetes.io/hostname"
NodeDefaultNonListedNodes = "DEFAULT_PATH_FOR_NON_LISTED_NODES" NodeDefaultNonListedNodes = "DEFAULT_PATH_FOR_NON_LISTED_NODES"
helperScriptDir = "/script"
helperDataVolName = "data"
helperScriptVolName = "script"
) )
var ( var (
...@@ -204,13 +208,14 @@ func (p *LocalPathProvisioner) Provision(opts pvController.ProvisionOptions) (*v ...@@ -204,13 +208,14 @@ func (p *LocalPathProvisioner) Provision(opts pvController.ProvisionOptions) (*v
logrus.Infof("Creating volume %v at %v:%v", name, node.Name, path) logrus.Infof("Creating volume %v at %v:%v", name, node.Name, path)
storage := pvc.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)] storage := pvc.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
volMode := string(*pvc.Spec.VolumeMode) provisionCmd := []string{"/bin/sh", "/script/setup"}
if err := p.createHelperPod(ActionTypeCreate, provisionCmd, volumeOptions{
createCmdsForPath := []string{ Name: name,
"/bin/sh", Path: path,
"/script/setup", Mode: *pvc.Spec.VolumeMode,
} SizeInBytes: storage.Value(),
if err := p.createHelperPod(ActionTypeCreate, createCmdsForPath, name, path, node.Name, volMode, storage.Value()); err != nil { Node: node.Name,
}); err != nil {
return nil, err return nil, err
} }
...@@ -271,9 +276,14 @@ func (p *LocalPathProvisioner) Delete(pv *v1.PersistentVolume) (err error) { ...@@ -271,9 +276,14 @@ func (p *LocalPathProvisioner) Delete(pv *v1.PersistentVolume) (err error) {
if pv.Spec.PersistentVolumeReclaimPolicy != v1.PersistentVolumeReclaimRetain { if pv.Spec.PersistentVolumeReclaimPolicy != v1.PersistentVolumeReclaimRetain {
logrus.Infof("Deleting volume %v at %v:%v", pv.Name, node, path) logrus.Infof("Deleting volume %v at %v:%v", pv.Name, node, path)
storage := pv.Spec.Capacity[v1.ResourceName(v1.ResourceStorage)] storage := pv.Spec.Capacity[v1.ResourceName(v1.ResourceStorage)]
volMode := string(*pv.Spec.VolumeMode) cleanupCmd := []string{"/bin/sh", "/script/teardown"}
cleanupCmdsForPath := []string{"/bin/sh", "/script/teardown"} if err := p.createHelperPod(ActionTypeDelete, cleanupCmd, volumeOptions{
if err := p.createHelperPod(ActionTypeDelete, cleanupCmdsForPath, pv.Name, path, node, volMode, storage.Value()); err != nil { Name: pv.Name,
Path: path,
Mode: *pv.Spec.VolumeMode,
SizeInBytes: storage.Value(),
Node: node,
}); err != nil {
logrus.Infof("clean up volume %v failed: %v", pv.Name, err) logrus.Infof("clean up volume %v failed: %v", pv.Name, err)
return err return err
} }
...@@ -324,29 +334,30 @@ func (p *LocalPathProvisioner) getPathAndNodeForPV(pv *v1.PersistentVolume) (pat ...@@ -324,29 +334,30 @@ func (p *LocalPathProvisioner) getPathAndNodeForPV(pv *v1.PersistentVolume) (pat
return path, node, nil return path, node, nil
} }
func (p *LocalPathProvisioner) createHelperPod(action ActionType, cmdsForPath []string, name, path, node, volumeMode string, sizeInBytes int64) (err error) { type volumeOptions struct {
Name string
Path string
Mode v1.PersistentVolumeMode
SizeInBytes int64
Node string
}
func (p *LocalPathProvisioner) createHelperPod(action ActionType, cmd []string, o volumeOptions) (err error) {
defer func() { defer func() {
err = errors.Wrapf(err, "failed to %v volume %v", action, name) err = errors.Wrapf(err, "failed to %v volume %v", action, o.Name)
}() }()
if name == "" || path == "" || node == "" { if o.Name == "" || o.Path == "" || o.Node == "" {
return fmt.Errorf("invalid empty name or path or node") return fmt.Errorf("invalid empty name or path or node")
} }
path, err = filepath.Abs(path) if !filepath.IsAbs(o.Path) {
if err != nil { return fmt.Errorf("volume path %s is not absolute", o.Path)
return err
}
path = strings.TrimSuffix(path, "/")
parentDir, volumeDir := filepath.Split(path)
parentDir = strings.TrimSuffix(parentDir, "/")
volumeDir = strings.TrimSuffix(volumeDir, "/")
if parentDir == "" || volumeDir == "" {
// it covers the `/` case
return fmt.Errorf("invalid path %v for %v: cannot find parent dir or volume dir", action, path)
} }
o.Path = filepath.Clean(o.Path)
parentDir, volumeDir := filepath.Split(o.Path)
hostPathType := v1.HostPathDirectoryOrCreate hostPathType := v1.HostPathDirectoryOrCreate
lpvVolumes := []v1.Volume{ lpvVolumes := []v1.Volume{
{ {
Name: "data", Name: helperDataVolName,
VolumeSource: v1.VolumeSource{ VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{ HostPath: &v1.HostPathVolumeSource{
Path: parentDir, Path: parentDir,
...@@ -355,7 +366,7 @@ func (p *LocalPathProvisioner) createHelperPod(action ActionType, cmdsForPath [] ...@@ -355,7 +366,7 @@ func (p *LocalPathProvisioner) createHelperPod(action ActionType, cmdsForPath []
}, },
}, },
{ {
Name: "script", Name: helperScriptVolName,
VolumeSource: v1.VolumeSource{ VolumeSource: v1.VolumeSource{
ConfigMap: &v1.ConfigMapVolumeSource{ ConfigMap: &v1.ConfigMapVolumeSource{
LocalObjectReference: v1.LocalObjectReference{ LocalObjectReference: v1.LocalObjectReference{
...@@ -375,18 +386,6 @@ func (p *LocalPathProvisioner) createHelperPod(action ActionType, cmdsForPath [] ...@@ -375,18 +386,6 @@ func (p *LocalPathProvisioner) createHelperPod(action ActionType, cmdsForPath []
}, },
}, },
} }
lpvVolumeMounts := []v1.VolumeMount{
{
Name: "data",
ReadOnly: false,
MountPath: parentDir,
},
{
Name: "script",
ReadOnly: false,
MountPath: "/script",
},
}
lpvTolerations := []v1.Toleration{ lpvTolerations := []v1.Toleration{
{ {
Operator: v1.TolerationOpExists, Operator: v1.TolerationOpExists,
...@@ -394,23 +393,33 @@ func (p *LocalPathProvisioner) createHelperPod(action ActionType, cmdsForPath [] ...@@ -394,23 +393,33 @@ func (p *LocalPathProvisioner) createHelperPod(action ActionType, cmdsForPath []
} }
helperPod := p.helperPod.DeepCopy() helperPod := p.helperPod.DeepCopy()
scriptMount := addVolumeMount(&helperPod.Spec.Containers[0].VolumeMounts, helperScriptVolName, helperScriptDir)
scriptMount.MountPath = helperScriptDir
dataMount := addVolumeMount(&helperPod.Spec.Containers[0].VolumeMounts, helperDataVolName, parentDir)
parentDir = dataMount.MountPath
parentDir = strings.TrimSuffix(parentDir, string(filepath.Separator))
volumeDir = strings.TrimSuffix(volumeDir, string(filepath.Separator))
if parentDir == "" || volumeDir == "" || !filepath.IsAbs(parentDir) {
// it covers the `/` case
return fmt.Errorf("invalid path %v for %v: cannot find parent dir or volume dir or parent dir is relative", action, o.Path)
}
// use different name for helper pods // use different name for helper pods
// https://github.com/rancher/local-path-provisioner/issues/154 // https://github.com/rancher/local-path-provisioner/issues/154
helperPod.Name = (helperPod.Name + "-" + string(action) + "-" + name) helperPod.Name = (helperPod.Name + "-" + string(action) + "-" + o.Name)
if len(helperPod.Name) > HelperPodNameMaxLength { if len(helperPod.Name) > HelperPodNameMaxLength {
helperPod.Name = helperPod.Name[:HelperPodNameMaxLength] helperPod.Name = helperPod.Name[:HelperPodNameMaxLength]
} }
helperPod.Namespace = p.namespace helperPod.Namespace = p.namespace
helperPod.Spec.NodeName = node helperPod.Spec.NodeName = o.Node
helperPod.Spec.ServiceAccountName = p.serviceAccountName helperPod.Spec.ServiceAccountName = p.serviceAccountName
helperPod.Spec.RestartPolicy = v1.RestartPolicyNever helperPod.Spec.RestartPolicy = v1.RestartPolicyNever
helperPod.Spec.Tolerations = append(helperPod.Spec.Tolerations, lpvTolerations...) helperPod.Spec.Tolerations = append(helperPod.Spec.Tolerations, lpvTolerations...)
helperPod.Spec.Volumes = append(helperPod.Spec.Volumes, lpvVolumes...) helperPod.Spec.Volumes = append(helperPod.Spec.Volumes, lpvVolumes...)
helperPod.Spec.Containers[0].VolumeMounts = append(helperPod.Spec.Containers[0].VolumeMounts, lpvVolumeMounts...) helperPod.Spec.Containers[0].Command = cmd
helperPod.Spec.Containers[0].Command = cmdsForPath
helperPod.Spec.Containers[0].Args = []string{"-p", filepath.Join(parentDir, volumeDir), helperPod.Spec.Containers[0].Args = []string{"-p", filepath.Join(parentDir, volumeDir),
"-s", strconv.FormatInt(sizeInBytes, 10), "-s", strconv.FormatInt(o.SizeInBytes, 10),
"-m", volumeMode} "-m", string(o.Mode)}
// If it already exists due to some previous errors, the pod will be cleaned up later automatically // If it already exists due to some previous errors, the pod will be cleaned up later automatically
// https://github.com/rancher/local-path-provisioner/issues/27 // https://github.com/rancher/local-path-provisioner/issues/27
...@@ -441,10 +450,23 @@ func (p *LocalPathProvisioner) createHelperPod(action ActionType, cmdsForPath [] ...@@ -441,10 +450,23 @@ func (p *LocalPathProvisioner) createHelperPod(action ActionType, cmdsForPath []
return fmt.Errorf("create process timeout after %v seconds", CmdTimeoutCounts) return fmt.Errorf("create process timeout after %v seconds", CmdTimeoutCounts)
} }
logrus.Infof("Volume %v has been %vd on %v:%v", name, action, node, path) logrus.Infof("Volume %v has been %vd on %v:%v", o.Name, action, o.Node, o.Path)
return nil return nil
} }
func addVolumeMount(mounts *[]v1.VolumeMount, name, mountPath string) *v1.VolumeMount {
for i, m := range *mounts {
if m.Name == name {
if m.MountPath == "" {
(*mounts)[i].MountPath = mountPath
}
return &(*mounts)[i]
}
}
*mounts = append(*mounts, v1.VolumeMount{Name: name, MountPath: mountPath})
return &(*mounts)[len(*mounts)-1]
}
func isJSONFile(configFile string) bool { func isJSONFile(configFile string) bool {
return strings.HasSuffix(configFile, ".json") return strings.HasSuffix(configFile, ".json")
} }
......
...@@ -33,5 +33,8 @@ func loadHelperPodFile(helperPodYaml string) (*v1.Pod, error) { ...@@ -33,5 +33,8 @@ func loadHelperPodFile(helperPodYaml string) (*v1.Pod, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("invalid unmarshal the helper pod with helperPodJson: %v", string(helperPodJSON)) return nil, fmt.Errorf("invalid unmarshal the helper pod with helperPodJson: %v", string(helperPodJSON))
} }
if len(p.Spec.Containers) == 0 {
return nil, fmt.Errorf("helper pod template does not specify any container")
}
return &p, nil return &p, nil
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment