Example #1
0
// Reconstruct Volume object and reconstructedVolume data structure by reading the pod's volume directories
func (rc *reconciler) reconstructVolume(volume podVolume) (*reconstructedVolume, error) {
	plugin, err := rc.volumePluginMgr.FindPluginByName(volume.pluginName)
	if err != nil {
		return nil, err
	}
	volumeSpec, err := plugin.ConstructVolumeSpec(volume.volumeSpecName, volume.mountPath)
	if err != nil {
		return nil, err
	}
	volumeName, err := plugin.GetVolumeName(volumeSpec)
	if err != nil {
		return nil, err
	}
	pod := &api.Pod{
		ObjectMeta: api.ObjectMeta{
			UID: types.UID(volume.podName),
		},
	}
	attachablePlugin, err := rc.volumePluginMgr.FindAttachablePluginByName(volume.pluginName)
	if err != nil {
		return nil, err
	}
	var uniqueVolumeName api.UniqueVolumeName
	if attachablePlugin != nil {
		uniqueVolumeName = volumehelper.GetUniqueVolumeName(volume.pluginName, volumeName)
	} else {
		uniqueVolumeName = volumehelper.GetUniqueVolumeNameForNonAttachableVolume(volume.podName, plugin, volumeSpec)
	}

	volumeMounter, newMounterErr := plugin.NewMounter(
		volumeSpec,
		pod,
		volumepkg.VolumeOptions{})
	if newMounterErr != nil {
		return nil, fmt.Errorf(
			"MountVolume.NewMounter failed for volume %q (spec.Name: %q) pod %q (UID: %q) with: %v",
			uniqueVolumeName,
			volumeSpec.Name(),
			volume.podName,
			pod.UID,
			newMounterErr)
	}

	reconstructedVolume := &reconstructedVolume{
		volumeName:          uniqueVolumeName,
		podName:             volume.podName,
		volumeSpec:          volumeSpec,
		outerVolumeSpecName: volumeName, /* volumeName is InnerVolumeSpecName. But this information will not be used for cleanup */
		pod:                 pod,
		pluginIsAttachable:  attachablePlugin != nil,
		volumeGidValue:      "",
		devicePath:          "",
		mounter:             volumeMounter,
	}
	return reconstructedVolume, nil
}
Example #2
0
// Reconstruct Volume object and volumeToMount data structure by reading the pod's volume directories
func (rc *reconciler) reconstructVolume(volume podVolume) (*operationexecutor.VolumeToMount, error) {
	plugin, err := rc.volumePluginMgr.FindPluginByName(volume.pluginName)
	if err != nil {
		return nil, err
	}
	volumeSpec, err := plugin.ConstructVolumeSpec(volume.volumeSpecName, volume.mountPath)
	if err != nil {
		return nil, err
	}
	volumeName, err := plugin.GetVolumeName(volumeSpec)
	if err != nil {
		return nil, err
	}
	pod := &api.Pod{
		ObjectMeta: api.ObjectMeta{
			UID: types.UID(volume.podName),
		},
	}
	attachablePlugin, err := rc.volumePluginMgr.FindAttachablePluginByName(volume.pluginName)
	if err != nil {
		return nil, err
	}
	var uniqueVolumeName api.UniqueVolumeName
	if attachablePlugin != nil {
		uniqueVolumeName = volumehelper.GetUniqueVolumeName(volume.pluginName, volumeName)
	} else {
		uniqueVolumeName = volumehelper.GetUniqueVolumeNameForNonAttachableVolume(volume.podName, plugin, volumeSpec)
	}

	volumeToMount := &operationexecutor.VolumeToMount{
		VolumeName:          uniqueVolumeName,
		PodName:             volume.podName,
		VolumeSpec:          volumeSpec,
		OuterVolumeSpecName: volumeName, /*volumeName is InnerVolumeSpecName. But this information will not be used for cleanup*/
		Pod:                 pod,
		PluginIsAttachable:  attachablePlugin != nil,
		VolumeGidValue:      "",
		DevicePath:          "",
	}
	return volumeToMount, nil
}
Example #3
0
// Reconstruct Volume object and reconstructedVolume data structure by reading the pod's volume directories
func (rc *reconciler) reconstructVolume(volume podVolume) (*reconstructedVolume, error) {
	plugin, err := rc.volumePluginMgr.FindPluginByName(volume.pluginName)
	if err != nil {
		return nil, err
	}
	volumeSpec, err := plugin.ConstructVolumeSpec(volume.volumeSpecName, volume.mountPath)
	if err != nil {
		return nil, err
	}
	pod := &v1.Pod{
		ObjectMeta: v1.ObjectMeta{
			UID: types.UID(volume.podName),
		},
	}
	attachablePlugin, err := rc.volumePluginMgr.FindAttachablePluginByName(volume.pluginName)
	if err != nil {
		return nil, err
	}

	volumeName, err := plugin.GetVolumeName(volumeSpec)
	if err != nil {
		return nil, err
	}
	var uniqueVolumeName v1.UniqueVolumeName
	if attachablePlugin != nil {
		uniqueVolumeName = volumehelper.GetUniqueVolumeName(volume.pluginName, volumeName)
	} else {
		uniqueVolumeName = volumehelper.GetUniqueVolumeNameForNonAttachableVolume(volume.podName, plugin, volumeSpec)
	}

	volumeMounter, newMounterErr := plugin.NewMounter(
		volumeSpec,
		pod,
		volumepkg.VolumeOptions{})
	if newMounterErr != nil {
		return nil, fmt.Errorf(
			"MountVolume.NewMounter failed for volume %q (spec.Name: %q) pod %q (UID: %q) with: %v",
			uniqueVolumeName,
			volumeSpec.Name(),
			volume.podName,
			pod.UID,
			newMounterErr)
	}

	reconstructedVolume := &reconstructedVolume{
		volumeName: uniqueVolumeName,
		podName:    volume.podName,
		volumeSpec: volumeSpec,
		// volume.volumeSpecName is actually InnerVolumeSpecName. But this information will likely to be updated in updateStates()
		// by checking the desired state volumeToMount list and getting the real OuterVolumeSpecName.
		// In case the pod is deleted during this period and desired state does not have this information, it will not be used
		// for volume cleanup.
		outerVolumeSpecName: volume.volumeSpecName,
		pod:                 pod,
		pluginIsAttachable:  attachablePlugin != nil,
		volumeGidValue:      "",
		devicePath:          "",
		mounter:             volumeMounter,
	}
	return reconstructedVolume, nil
}
func (dsw *desiredStateOfWorld) AddPodToVolume(
	podName types.UniquePodName,
	pod *v1.Pod,
	volumeSpec *volume.Spec,
	outerVolumeSpecName string,
	volumeGidValue string) (v1.UniqueVolumeName, error) {
	dsw.Lock()
	defer dsw.Unlock()

	volumePlugin, err := dsw.volumePluginMgr.FindPluginBySpec(volumeSpec)
	if err != nil || volumePlugin == nil {
		return "", fmt.Errorf(
			"failed to get Plugin from volumeSpec for volume %q err=%v",
			volumeSpec.Name(),
			err)
	}

	var volumeName v1.UniqueVolumeName

	// The unique volume name used depends on whether the volume is attachable
	// or not.
	attachable := dsw.isAttachableVolume(volumeSpec)
	if attachable {
		// For attachable volumes, use the unique volume name as reported by
		// the plugin.
		volumeName, err =
			volumehelper.GetUniqueVolumeNameFromSpec(volumePlugin, volumeSpec)
		if err != nil {
			return "", fmt.Errorf(
				"failed to GetUniqueVolumeNameFromSpec for volumeSpec %q using volume plugin %q err=%v",
				volumeSpec.Name(),
				volumePlugin.GetPluginName(),
				err)
		}
	} else {
		// For non-attachable volumes, generate a unique name based on the pod
		// namespace and name and the name of the volume within the pod.
		volumeName = volumehelper.GetUniqueVolumeNameForNonAttachableVolume(podName, volumePlugin, volumeSpec)
	}

	volumeObj, volumeExists := dsw.volumesToMount[volumeName]
	if !volumeExists {
		volumeObj = volumeToMount{
			volumeName:         volumeName,
			podsToMount:        make(map[types.UniquePodName]podToMount),
			pluginIsAttachable: attachable,
			volumeGidValue:     volumeGidValue,
			reportedInUse:      false,
		}
		dsw.volumesToMount[volumeName] = volumeObj
	}

	// Create new podToMount object. If it already exists, it is refreshed with
	// updated values (this is required for volumes that require remounting on
	// pod update, like Downward API volumes).
	dsw.volumesToMount[volumeName].podsToMount[podName] = podToMount{
		podName:             podName,
		pod:                 pod,
		spec:                volumeSpec,
		outerVolumeSpecName: outerVolumeSpecName,
	}

	return volumeName, nil
}