Skip to content

Commit 4a0a84e

Browse files
author
jmccormick2001
committed
scale command added support for --node-label command flag
1 parent 83031ff commit 4a0a84e

File tree

13 files changed

+103
-65
lines changed

13 files changed

+103
-65
lines changed

apis/cr/v1/deepcopy_generated.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ func (in *Pgreplica) DeepCopyInto(out *Pgreplica) {
573573
*out = *in
574574
out.TypeMeta = in.TypeMeta
575575
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
576-
out.Spec = in.Spec
576+
in.Spec.DeepCopyInto(&out.Spec)
577577
out.Status = in.Status
578578
return
579579
}
@@ -636,6 +636,13 @@ func (in *PgreplicaSpec) DeepCopyInto(out *PgreplicaSpec) {
636636
*out = *in
637637
out.ReplicaStorage = in.ReplicaStorage
638638
out.ContainerResources = in.ContainerResources
639+
if in.UserLabels != nil {
640+
in, out := &in.UserLabels, &out.UserLabels
641+
*out = make(map[string]string, len(*in))
642+
for key, val := range *in {
643+
(*out)[key] = val
644+
}
645+
}
639646
return
640647
}
641648

apis/cr/v1/replica.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type PgreplicaSpec struct {
3838
ReplicaStorage PgStorageSpec `json:"replicastorage"`
3939
ContainerResources PgContainerResources `json:"containerresources"`
4040
Status string `json:"status"`
41+
UserLabels map[string]string `json:"userlabels"`
4142
//Strategy string `json:"strategy"`
4243
//Port string `json:"port"`
4344
//CCPImageTag string `json:"ccpimagetag"`
@@ -47,7 +48,6 @@ type PgreplicaSpec struct {
4748
//NodeName string `json:"NodeName"`
4849
//PrimarySecretName string `json:"primarysecretname"`
4950
//UserSecretName string `json:"usersecretname"`
50-
//UserLabels map[string]string `json:"userlabels"`
5151
}
5252

5353
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

apiserver/clusterservice/clusterimpl.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ func getPods(cluster *crv1.Pgcluster) ([]msgs.ShowClusterPod, error) {
242242
d := msgs.ShowClusterPod{}
243243
d.Name = p.Name
244244
d.Phase = string(p.Status.Phase)
245-
d.NodeLabel = ""
245+
d.NodeName = p.Spec.NodeName
246246
d.ReadyStatus = getReadyStatus(&p)
247247
//log.Infof("pod details are %v\n", p)
248248
d.PVCName = getPVCName(&p)

apiserver/clusterservice/scaleimpl.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ import (
2525
kerrors "k8s.io/apimachinery/pkg/api/errors"
2626
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2727
"strconv"
28+
"strings"
2829
)
2930

3031
// ScaleCluster ...
31-
func ScaleCluster(name, replicaCount, resourcesConfig, storageConfig string) msgs.ClusterScaleResponse {
32+
func ScaleCluster(name, replicaCount, resourcesConfig, storageConfig, nodeLabel string) msgs.ClusterScaleResponse {
3233
var err error
3334

3435
response := msgs.ClusterScaleResponse{}
@@ -74,8 +75,43 @@ func ScaleCluster(name, replicaCount, resourcesConfig, storageConfig string) msg
7475
spec.ReplicaStorage = util.GetStorageSpec(viper.Sub("Storage." + viper.GetString("ReplicaStorage")))
7576
}
7677

78+
spec.UserLabels = make(map[string]string)
79+
80+
var parts []string
81+
//validate nodeLabel
82+
if nodeLabel != "" {
83+
parts = strings.Split(nodeLabel, "=")
84+
if len(parts) != 2 {
85+
response.Status.Code = msgs.Error
86+
response.Status.Msg = nodeLabel + " node label does not follow key=value format"
87+
return response
88+
}
89+
90+
keyValid, valueValid, err := apiserver.IsValidNodeLabel(parts[0], parts[1])
91+
if err != nil {
92+
response.Status.Code = msgs.Error
93+
response.Status.Msg = err.Error()
94+
return response
95+
}
96+
97+
if !keyValid {
98+
response.Status.Code = msgs.Error
99+
response.Status.Msg = nodeLabel + " key was not valid .. check node labels for correct values to specify"
100+
return response
101+
}
102+
if !valueValid {
103+
response.Status.Code = msgs.Error
104+
response.Status.Msg = nodeLabel + " node label value was not valid .. check node labels for correct values to specify"
105+
return response
106+
}
107+
spec.UserLabels["NodeLabelKey"] = parts[0]
108+
spec.UserLabels["NodeLabelValue"] = parts[1]
109+
110+
}
111+
77112
labels := make(map[string]string)
78113
labels["pg-cluster"] = cluster.Spec.Name
114+
79115
spec.ClusterName = cluster.Spec.Name
80116

81117
var rc int

apiserver/clusterservice/scaleservice.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ func ScaleClusterHandler(w http.ResponseWriter, r *http.Request) {
4545
if storageConfig != "" {
4646
log.Debug("storage-config param was [" + storageConfig + "]")
4747
}
48+
nodeLabel := r.URL.Query().Get("node-label")
49+
if nodeLabel != "" {
50+
log.Debug("node-label param was [" + nodeLabel + "]")
51+
}
4852

4953
switch r.Method {
5054
case "GET":
@@ -54,6 +58,6 @@ func ScaleClusterHandler(w http.ResponseWriter, r *http.Request) {
5458
w.WriteHeader(http.StatusOK)
5559
w.Header().Set("Content-Type", "application/json")
5660

57-
resp := ScaleCluster(clusterName, replicaCount, resourcesConfig, storageConfig)
61+
resp := ScaleCluster(clusterName, replicaCount, resourcesConfig, storageConfig, nodeLabel)
5862
json.NewEncoder(w).Encode(resp)
5963
}

apiservermsgs/clustermsgs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ type ShowClusterService struct {
5858
type ShowClusterPod struct {
5959
Name string
6060
Phase string
61-
NodeLabel string
61+
NodeName string
6262
PVCName string
6363
ReadyStatus string
6464
Primary bool

bin/remove-images.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
docker rmi -f pgo-lspvc crunchydata/pgo-lspvc:$CO_IMAGE_TAG \
17-
postgres-operator crunchydata/postgres-operator:$CO_IMAGE_TAG \
18-
pgo-load crunchydata/pgo-load:$CO_IMAGE_TAG \
19-
pgo-apiserver crunchydata/pgo-apiserver:$CO_IMAGE_TAG \
20-
pgo-rmdata crunchydata/pgo-rmdata:$CO_IMAGE_TAG
16+
docker rmi -f pgo-lspvc $CO_IMAGE_PREFIX/pgo-lspvc:$CO_IMAGE_TAG
17+
docker rmi -f postgres-operator $CO_IMAGE_PREFIX/postgres-operator:$CO_IMAGE_TAG
18+
docker rmi -f pgo-load $CO_IMAGE_PREFIX/pgo-load:$CO_IMAGE_TAG
19+
docker rmi -f pgo-apiserver $CO_IMAGE_PREFIX/pgo-apiserver:$CO_IMAGE_TAG
20+
docker rmi -f pgo-rmdata $CO_IMAGE_PREFIX/pgo-rmdata:$CO_IMAGE_TAG

docs/operator-docs.asciidoc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,23 @@ You can filter the results by Postgres version:
10601060
pgo show cluster all --version=9.6.2
10611061
....
10621062

1063+
The scale command will let you specify a *--node-label* flag which
1064+
can be used to influence what Kube node the replica will be scheduled
1065+
upon.
1066+
1067+
....
1068+
pgo scale mycluster --node-label=speed=fast
1069+
....
1070+
1071+
If you don't specify a *--node-label* flag, a node affinity
1072+
rule of *NotIn* will be specified to *prefer* that the replica
1073+
be schedule on a node that the primary is not running on.
1074+
1075+
You can also dictate what container resource and storage configurations
1076+
will be used for a replica by passing in extra command flags:
1077+
....
1078+
pgo scale mycluster --storage-config=storage1 --resources-config=small
1079+
....
10631080

10641081
=== pgo upgrade
10651082

golang-examples/listpods.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func main() {
4242
}
4343

4444
lo := meta_v1.ListOptions{}
45-
pods, err := clientset.CoreV1().Pods("default").List(lo)
45+
pods, err := clientset.CoreV1().Pods("demo").List(lo)
4646
if err != nil {
4747
panic(err.Error())
4848
}
@@ -65,7 +65,7 @@ func main() {
6565
}
6666
}
6767
fmt.Printf("Ready %d/%d\n", readyCount, containerCount)
68-
//fmt.Printf("%v\n", pod)
68+
fmt.Printf("NodeName is %s\n", pod.Spec.NodeName)
6969
//fmt.Printf("%v\n", pod.Spec.Volumes)
7070
for _, v := range pod.Spec.Volumes {
7171
if v.Name == "pgdata" {

operator/cluster/cluster_strategy_1.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,28 @@ func getPrimaryLabels(Name string, ClusterName string, replicaFlag bool, userLab
417417
return primaryLabels
418418
}
419419

420+
// GetReplicaAffinity ...
421+
// use NotIn as an operator when a node-label is not specified on the
422+
// replica, use the node labels from the primary in this case
423+
// use In as an operator when a node-label is specified on the replica
424+
// use the node labels from the replica in this case
425+
func GetReplicaAffinity(clusterLabels, replicaLabels map[string]string) string {
426+
var operator, key, value string
427+
log.Debug("GetReplicaAffinity ")
428+
if replicaLabels["NodeLabelKey"] != "" {
429+
//use the replica labels
430+
operator = "In"
431+
key = replicaLabels["NodeLabelKey"]
432+
value = replicaLabels["NodeLabelValue"]
433+
} else {
434+
//use the cluster labels
435+
operator = "NotIn"
436+
key = clusterLabels["NodeLabelKey"]
437+
value = clusterLabels["NodeLabelValue"]
438+
}
439+
return GetAffinity(key, value, operator)
440+
}
441+
420442
// GetAffinity ...
421443
func GetAffinity(nodeLabelKey, nodeLabelValue string, operator string) string {
422444
log.Debugf("GetAffinity with nodeLabelKey=[%s] nodeLabelKey=[%s] and operator=[%s]\n", nodeLabelKey, nodeLabelValue, operator)
@@ -556,7 +578,7 @@ func (r Strategy1) Scale(clientset *kubernetes.Clientset, client *rest.RESTClien
556578
RootSecretName: cluster.Spec.RootSecretName,
557579
PrimarySecretName: cluster.Spec.PrimarySecretName,
558580
UserSecretName: cluster.Spec.UserSecretName,
559-
NodeSelector: GetAffinity(cluster.Spec.UserLabels["NodeLabelKey"], cluster.Spec.UserLabels["NodeLabelValue"], "NotIn"),
581+
NodeSelector: GetReplicaAffinity(cluster.Spec.UserLabels, replica.Spec.UserLabels),
560582
}
561583

562584
switch replica.Spec.ReplicaStorage.StorageType {

0 commit comments

Comments
 (0)