// 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) } }
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 }
// 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 }
// 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 } } }