Example #1
0
// PetSet - available only in kubernetes v1.3+
// big advantage: it allow create persistentVolume template
// this template can create persistent volumeClaim for each POD automatically
//
// create petSet for couchdb cluster
// init all necessary struct for petSet and then via kube client creates it
// @ param cluster - struct CouchdbCluster - required:
// @return extensions.Deployment - created kube deployment
// @return error - errors that occur during creation
//
func (cluster *CouchdbCluster) CreatePetSet() (*apps.PetSet, error) {
	/*
		PET SET, included in kube 1.3+
		http://kubernetes-v1-3.github.io/docs/user-guide/petset/
		// TESTING - ALPHA
	*/
	// pod template with volumes
	podTemplate := *cluster.CouchdbPodTemplate(true, CLUSTER_PREFIX+cluster.Tag)
	// pet set spec label selector
	lSelector := unversioned.LabelSelector{MatchLabels: cluster.Labels}

	// pvc claim
	pvc := api.PersistentVolumeClaim{}
	pvc.Name = CLUSTER_PREFIX + cluster.Tag
	pvc.Annotations = make(map[string]string)
	pvc.Annotations["volume.alpha.kubernetes.io/storage-class"] = "anything"

	// resource list for pvc claim template
	rsList := make(api.ResourceList)
	// SIZE
	rsList[api.ResourceStorage] = *(resource.NewQuantity(5*1024*1024*1024, resource.BinarySI))
	// pvc SPEC
	pvcSpec := api.PersistentVolumeClaimSpec{}
	pvcSpec.Resources.Requests = api.ResourceList(rsList)

	pvc.Spec = pvcSpec
	// pet set specs
	petSetSPec := apps.PetSetSpec{Replicas: int(cluster.Replicas), Template: podTemplate,
		Selector: &lSelector, VolumeClaimTemplates: []api.PersistentVolumeClaim{pvc}}

	// pet set
	petSet := apps.PetSet{Spec: petSetSPec}
	petSet.Name = CLUSTER_PREFIX + cluster.Tag
	petSet.Labels = cluster.Labels

	// get a new kube extensions client
	c, err := KubeClientApps(KUBE_API)
	// check for errors
	if err != nil {
		ErrorLog("kube_control: createPetSet: Cannot connect to Kubernetes api ")
		ErrorLog(err)
		return nil, err
	} else {
		// create deployment
		return c.PetSets(cluster.Namespace).Create(&petSet)
	}
}
Example #2
0
func petSetFromManifest(fileName, ns string) *apps.PetSet {
	var ps apps.PetSet
	framework.Logf("Parsing petset from %v", fileName)
	data, err := ioutil.ReadFile(fileName)
	Expect(err).NotTo(HaveOccurred())
	json, err := utilyaml.ToJSON(data)
	Expect(err).NotTo(HaveOccurred())

	Expect(runtime.DecodeInto(api.Codecs.UniversalDecoder(), json, &ps)).NotTo(HaveOccurred())
	ps.Namespace = ns
	if ps.Spec.Selector == nil {
		ps.Spec.Selector = &unversioned.LabelSelector{
			MatchLabels: ps.Spec.Template.Labels,
		}
	}
	return &ps
}
Example #3
0
// ValidatePetSetUpdate tests if required fields in the PetSet are set.
func ValidatePetSetUpdate(petSet, oldPetSet *apps.PetSet) field.ErrorList {
	allErrs := field.ErrorList{}

	// TODO: For now we're taking the safe route and disallowing all updates to spec except for Spec.Replicas.
	// Enable on a case by case basis.
	restoreReplicas := petSet.Spec.Replicas
	petSet.Spec.Replicas = oldPetSet.Spec.Replicas

	// The generation changes for this update
	restoreGeneration := petSet.Generation
	petSet.Generation = oldPetSet.Generation

	if !reflect.DeepEqual(petSet, oldPetSet) {
		allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "updates to petset spec for fields other than 'replicas' are forbidden."))
	}
	petSet.Spec.Replicas = restoreReplicas
	petSet.Generation = restoreGeneration
	allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(petSet.Spec.Replicas), field.NewPath("spec", "replicas"))...)
	return allErrs
}
Example #4
0
// updatePetCount attempts to update the Status.Replicas of the given PetSet, with a single GET/PUT retry.
func updatePetCount(psClient appsclientset.PetSetsGetter, ps apps.PetSet, numPets int) (updateErr error) {
	if ps.Status.Replicas == numPets || psClient == nil {
		return nil
	}
	var getErr error
	for i, ps := 0, &ps; ; i++ {
		glog.V(4).Infof(fmt.Sprintf("Updating replica count for PetSet: %s/%s, ", ps.Namespace, ps.Name) +
			fmt.Sprintf("replicas %d->%d (need %d), ", ps.Status.Replicas, numPets, ps.Spec.Replicas))

		ps.Status = apps.PetSetStatus{Replicas: numPets}
		_, updateErr = psClient.PetSets(ps.Namespace).UpdateStatus(ps)
		if updateErr == nil || i >= statusUpdateRetries {
			return updateErr
		}
		if ps, getErr = psClient.PetSets(ps.Namespace).Get(ps.Name); getErr != nil {
			return getErr
		}
	}
}