// assertNoPersistentStorage ensures that there are no persistent volumes or
// filesystems attached to the machine, and returns any mgo/txn assertions
// required to ensure that remains true.
336561
func (m *Machine) assertNoPersistentStorage() (bson.D, error) {
	attachments := names.NewSet()
	for _, v := range m.doc.Volumes {
		tag := names.NewVolumeTag(v)
		detachable, err := isDetachableVolumeTag(m.st.db(), tag)
		if err != nil {
			return nil, errors.Trace(err)
		}
		if detachable {
			attachments.Add(tag)
		}
	}
	for _, f := range m.doc.Filesystems {
		tag := names.NewFilesystemTag(f)
		detachable, err := isDetachableFilesystemTag(m.st.db(), tag)
		if err != nil {
			return nil, errors.Trace(err)
		}
		if detachable {
			attachments.Add(tag)
		}
	}
	if len(attachments) > 0 {
		return nil, &HasAttachmentsError{
			MachineId:   m.doc.Id,
			Attachments: attachments.SortedValues(),
		}
	}
	if m.doc.Life == Dying {
		return nil, nil
	}
	// A Dying machine cannot have attachments added to it,
	// but if we're advancing from Alive to Dead then we
	// must ensure no concurrent attachments are made.
	noNewVolumes := bson.DocElem{
		"volumes", bson.D{{
			"$not", bson.D{{
				"$elemMatch", bson.D{{
					"$nin", m.doc.Volumes,
				}},
			}},
		}},
		// There are no volumes that are not in
		// the set of volumes we previously knew
		// about => the current set of volumes
		// is a subset of the previously known set.
	}
	noNewFilesystems := bson.DocElem{
		"filesystems", bson.D{{
			"$not", bson.D{{
				"$elemMatch", bson.D{{
					"$nin", m.doc.Filesystems,
				}},
			}},
		}},
	}
	return bson.D{noNewVolumes, noNewFilesystems}, nil
}
59885
func (m *MockInterface) StorageV1alpha1() v1alpha13.StorageV1alpha1Interface {
	ret := m.ctrl.Call(m, "StorageV1alpha1")
	ret0, _ := ret[0].(v1alpha13.StorageV1alpha1Interface)
	return ret0
}
1242506
func (a *Assertion) NotContains(container, item interface{}, msg ...interface{}) *Assertion {
	NotContains(a.t, container, item, msg...)
	return a
}
499992
func checkVolumeSatisfyClaim(volume *v1.PersistentVolume, claim *v1.PersistentVolumeClaim) error {
	requestedQty := claim.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
	requestedSize := requestedQty.Value()

	// check if PV's DeletionTimeStamp is set, if so, return error.
	if utilfeature.DefaultFeatureGate.Enabled(features.StorageObjectInUseProtection) {
		if volume.ObjectMeta.DeletionTimestamp != nil {
			return fmt.Errorf("the volume is marked for deletion")
		}
	}

	volumeQty := volume.Spec.Capacity[v1.ResourceStorage]
	volumeSize := volumeQty.Value()
	if volumeSize < requestedSize {
		return fmt.Errorf("requested PV is too small")
	}

	requestedClass := v1helper.GetPersistentVolumeClaimClass(claim)
	if v1helper.GetPersistentVolumeClass(volume) != requestedClass {
		return fmt.Errorf("storageClassName does not match")
	}

	isMismatch, err := checkVolumeModeMismatches(&claim.Spec, &volume.Spec)
	if err != nil {
		return fmt.Errorf("error checking volumeMode: %v", err)
	}
	if isMismatch {
		return fmt.Errorf("incompatible volumeMode")
	}

	if !checkAccessModes(claim, volume) {
		return fmt.Errorf("incompatible accessMode")
	}

	return nil
}
1255699
func GetPersistentVolumeClass(volume *v1.PersistentVolume) string {
	// Use beta annotation first
	if class, found := volume.Annotations[v1.BetaStorageClassAnnotation]; found {
		return class
	}

	return volume.Spec.StorageClassName
}
1317605
func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *core.PersistentVolumeClaim) field.ErrorList {
	allErrs := ValidateObjectMetaUpdate(&newPvc.ObjectMeta, &oldPvc.ObjectMeta, field.NewPath("metadata"))
	allErrs = append(allErrs, ValidatePersistentVolumeClaim(newPvc)...)
	newPvcClone := newPvc.DeepCopy()
	oldPvcClone := oldPvc.DeepCopy()

	// PVController needs to update PVC.Spec w/ VolumeName.
	// Claims are immutable in order to enforce quota, range limits, etc. without gaming the system.
	if len(oldPvc.Spec.VolumeName) == 0 {
		// volumeName changes are allowed once.
		oldPvcClone.Spec.VolumeName = newPvcClone.Spec.VolumeName
	}

	if validateStorageClassUpgrade(oldPvcClone.Annotations, newPvcClone.Annotations,
		oldPvcClone.Spec.StorageClassName, newPvcClone.Spec.StorageClassName) {
		newPvcClone.Spec.StorageClassName = nil
		metav1.SetMetaDataAnnotation(&newPvcClone.ObjectMeta, core.BetaStorageClassAnnotation, oldPvcClone.Annotations[core.BetaStorageClassAnnotation])
	} else {
		// storageclass annotation should be immutable after creation
		// TODO: remove Beta when no longer needed
		allErrs = append(allErrs, ValidateImmutableAnnotation(newPvc.ObjectMeta.Annotations[v1.BetaStorageClassAnnotation], oldPvc.ObjectMeta.Annotations[v1.BetaStorageClassAnnotation], v1.BetaStorageClassAnnotation, field.NewPath("metadata"))...)
	}

	if utilfeature.DefaultFeatureGate.Enabled(features.ExpandPersistentVolumes) {
		// lets make sure storage values are same.
		if newPvc.Status.Phase == core.ClaimBound && newPvcClone.Spec.Resources.Requests != nil {
			newPvcClone.Spec.Resources.Requests["storage"] = oldPvc.Spec.Resources.Requests["storage"]
		}

		oldSize := oldPvc.Spec.Resources.Requests["storage"]
		newSize := newPvc.Spec.Resources.Requests["storage"]

		if !apiequality.Semantic.DeepEqual(newPvcClone.Spec, oldPvcClone.Spec) {
			allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "is immutable after creation except resources.requests for bound claims"))
		}
		if newSize.Cmp(oldSize) < 0 {
			allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "resources", "requests", "storage"), "field can not be less than previous value"))
		}

	} else {
		// changes to Spec are not allowed, but updates to label/and some annotations are OK.
		// no-op updates pass validation.
		if !apiequality.Semantic.DeepEqual(newPvcClone.Spec, oldPvcClone.Spec) {
			allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "field is immutable after creation"))
		}
	}

	allErrs = append(allErrs, ValidateImmutableField(newPvc.Spec.VolumeMode, oldPvc.Spec.VolumeMode, field.NewPath("volumeMode"))...)

	return allErrs
}
28116
func GetPersistentVolumeClaimQualifiedName(claim *v1.PersistentVolumeClaim) string {
	return utilstrings.JoinQualifiedName(claim.GetNamespace(), claim.GetName())
}
568771
func newPersistentVolumeClaims(c *CoreClient, namespace string) *persistentVolumeClaims {
	return &persistentVolumeClaims{
		client: c,
		ns:     namespace,
	}
}
1080220
func (k *kubernetesClient) EnsureStorageProvisioner(cfg caas.StorageProvisioner) (*caas.StorageProvisioner, error) {
	// First see if the named storage class exists.
	sc, err := k.getStorageClass(cfg.Name)
	if err == nil {
		return &caas.StorageProvisioner{
			Name:        sc.Name,
			Provisioner: sc.Provisioner,
			Parameters:  sc.Parameters,
		}, nil
	}
	if !k8serrors.IsNotFound(err) {
		return nil, errors.Annotatef(err, "getting storage class %q", cfg.Name)
	}
	// If it's not found but there's no provisioner specified, we can't
	// create it so just return not found.
	if cfg.Provisioner == "" {
		return nil, errors.NewNotFound(nil,
			fmt.Sprintf("storage class %q doesn't exist, but no storage provisioner has been specified",
				cfg.Name))
	}

	// Create the storage class with the specified provisioner.
	var reclaimPolicy *core.PersistentVolumeReclaimPolicy
	if cfg.ReclaimPolicy != "" {
		policy := core.PersistentVolumeReclaimPolicy(cfg.ReclaimPolicy)
		reclaimPolicy = &policy
	}
	storageClasses := k.client().StorageV1().StorageClasses()
	sc = &k8sstorage.StorageClass{
		ObjectMeta: v1.ObjectMeta{
			Name: qualifiedStorageClassName(cfg.Namespace, cfg.Name),
		},
		Provisioner:   cfg.Provisioner,
		ReclaimPolicy: reclaimPolicy,
		Parameters:    cfg.Parameters,
	}
	if cfg.Namespace != "" {
		sc.Labels = map[string]string{labelModel: k.namespace}
	}
	_, err = storageClasses.Create(sc)
	if err != nil {
		return nil, errors.Annotatef(err, "creating storage class %q", cfg.Name)
	}
	return &caas.StorageProvisioner{
		Name:        sc.Name,
		Provisioner: sc.Provisioner,
		Parameters:  sc.Parameters,
	}, nil
}
507624
func ValidatePersistentVolumeStatusUpdate(newPv, oldPv *api.PersistentVolume) validation.ErrorList {
	allErrs := validation.ErrorList{}
	allErrs = append(allErrs, ValidateObjectMetaUpdate(&newPv.ObjectMeta, &oldPv.ObjectMeta, validation.NewFieldPath("metadata"))...)
	if newPv.ResourceVersion == "" {
		allErrs = append(allErrs, validation.NewRequiredError(validation.NewFieldPath("resourceVersion")))
	}
	newPv.Spec = oldPv.Spec
	return allErrs
}
835979
func updateStorage(set *apps.StatefulSet, pod *v1.Pod) {
	currentVolumes := pod.Spec.Volumes
	claims := getPersistentVolumeClaims(set, pod)
	newVolumes := make([]v1.Volume, 0, len(claims))
	for name, claim := range claims {
		newVolumes = append(newVolumes, v1.Volume{
			Name: name,
			VolumeSource: v1.VolumeSource{
				PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
					ClaimName: claim.Name,
					// TODO: Use source definition to set this value when we have one.
					ReadOnly: false,
				},
			},
		})
	}
	for i := range currentVolumes {
		if _, ok := claims[currentVolumes[i].Name]; !ok {
			newVolumes = append(newVolumes, currentVolumes[i])
		}
	}
	pod.Spec.Volumes = newVolumes
}
335540
func (c *CachedPersistentVolumeClaimInfo) GetPersistentVolumeClaimInfo(namespace string, name string) (*v1.PersistentVolumeClaim, error) {
	return c.PersistentVolumeClaims(namespace).Get(name)
}
517261
func (m *MockInterface) StorageV1beta1() v1beta111.StorageV1beta1Interface {
	ret := m.ctrl.Call(m, "StorageV1beta1")
	ret0, _ := ret[0].(v1beta111.StorageV1beta1Interface)
	return ret0
}
1209119
func (v *version) PersistentVolumeClaims() PersistentVolumeClaimInformer {
	return &persistentVolumeClaimInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
793552
func checkModelEntityRefsAllReleasableStorage(sb *storageBackend, doc *modelEntityRefsDoc) ([]txn.Op, error) {
	for _, volumeId := range doc.Volumes {
		volumeTag := names.NewVolumeTag(volumeId)
		volume, err := getVolumeByTag(sb.mb, volumeTag)
		if err != nil {
			return nil, errors.Trace(err)
		}
		if !volume.Detachable() {
			continue
		}
		if err := checkStoragePoolReleasable(sb, volume.pool()); err != nil {
			return nil, errors.Annotatef(err,
				"cannot release %s", names.ReadableString(volumeTag),
			)
		}
	}
	for _, filesystemId := range doc.Filesystems {
		filesystemTag := names.NewFilesystemTag(filesystemId)
		filesystem, err := getFilesystemByTag(sb.mb, filesystemTag)
		if err != nil {
			return nil, errors.Trace(err)
		}
		if !filesystem.Detachable() {
			continue
		}
		if err := checkStoragePoolReleasable(sb, filesystem.pool()); err != nil {
			return nil, errors.Annotatef(err,
				"cannot release %s", names.ReadableString(filesystemTag),
			)
		}
	}
	return noNewStorageModelEntityRefs(doc), nil
}
452640
func ValidatePersistentVolumeUpdate(newPv, oldPv *api.PersistentVolume) field.ErrorList {
	allErrs := field.ErrorList{}
	allErrs = ValidatePersistentVolume(newPv)
	newPv.Status = oldPv.Status
	return allErrs
}
1129628
func (g *GPGKey) GetCanEncryptStorage() bool {
	if g == nil || g.CanEncryptStorage == nil {
		return false
	}
	return *g.CanEncryptStorage
}