Skip to content

Commit

Permalink
support canary release for tikv (#869)
Browse files Browse the repository at this point in the history
* change tkc to tkctl

* compatible with linux and macOS

* support canary release for tikv
  • Loading branch information
onlymellb authored Sep 3, 2019
1 parent 5de1408 commit 8029dcf
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 30 deletions.
26 changes: 19 additions & 7 deletions manifests/create-cert.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ if [ ! -x "$(command -v openssl)" ]; then
exit 1
fi

CURDIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd )

# reset namespace and ca_bundle of webhook.yaml
sed -i "s/caBundle:.*/caBundle: \${CA_BUNDLE}/g" $CURDIR/webhook.yaml
sed -i "s/namespace:.*/namespace: \${NAMESPACE}/g" $CURDIR/webhook.yaml

csrName=${service}.${namespace}
tmpdir=$(mktemp -d)

Expand Down Expand Up @@ -130,4 +124,22 @@ kubectl create secret generic ${secret} \
--dry-run -o yaml |
kubectl -n ${namespace} apply -f -

sed -i "s/namespace: .*$/namespace: ${namespace}/g" $CURDIR/webhook.yaml

CURDIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd )
os=`uname -s| tr '[A-Z]' '[a-z]'`

case ${os} in
linux)
sed -i "s/caBundle:.*/caBundle: \${CA_BUNDLE}/g" $CURDIR/webhook.yaml
sed -i "s/namespace:.*/namespace: \${NAMESPACE}/g" $CURDIR/webhook.yaml
sed -i "s/namespace: \${NAMESPACE}/namespace: ${namespace}/g" $CURDIR/webhook.yaml
;;
darwin)
sed -i "" "s/caBundle:.*/caBundle: \${CA_BUNDLE}/g" $CURDIR/webhook.yaml
sed -i "" "s/namespace:.*/namespace: \${NAMESPACE}/g" $CURDIR/webhook.yaml
sed -i "" "s/namespace: \${NAMESPACE}/namespace: ${namespace}/g" $CURDIR/webhook.yaml
;;
*)
echo "invalid os ${os}, only support Linux and Darwin" >&2
;;
esac
14 changes: 13 additions & 1 deletion manifests/patch-ca.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,16 @@ CURDIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd )

CA_BUNDLE=$(kubectl get configmap -n kube-system extension-apiserver-authentication -o=jsonpath='{.data.client-ca-file}' | base64 | tr -d '\n')
echo $CA_BUNDLE
sed -i "s/caBundle: .*$/caBundle: ${CA_BUNDLE}/g" $CURDIR/webhook.yaml

os=`uname -s| tr '[A-Z]' '[a-z]'`
case ${os} in
linux)
sed -i "s/caBundle: .*$/caBundle: ${CA_BUNDLE}/g" $CURDIR/webhook.yaml
;;
darwin)
sed -i "" "s/caBundle: .*$/caBundle: ${CA_BUNDLE}/g" $CURDIR/webhook.yaml
;;
*)
echo "invalid os ${os}, only support Linux and Darwin" >&2
;;
esac
4 changes: 3 additions & 1 deletion pkg/label/label.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ const (
AnnPVCDeferDeleting = "tidb.pingcap.com/pvc-defer-deleting"
// AnnPVCPodScheduling is pod scheduling annotation key, it represents whether the pod is scheduling
AnnPVCPodScheduling = "tidb.pingcap.com/pod-scheduling"
// AnnTiDBPartition is pod annotation which TiDB pod chould upgrade to
// AnnTiDBPartition is pod annotation which TiDB pod should upgrade to
AnnTiDBPartition string = "tidb.pingcap.com/tidb-partition"
// AnnTiKVPartition is pod annotation which TiKV pod should upgrade to
AnnTiKVPartition string = "tidb.pingcap.com/tikv-partition"
// AnnForceUpgradeKey is tc annotation key to indicate whether force upgrade should be done
AnnForceUpgradeKey = "tidb.pingcap.com/force-upgrade"

Expand Down
2 changes: 1 addition & 1 deletion pkg/tkctl/cmd/upinfo/upinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const (
You can omit --tidbcluster=<name> option by running 'tkc use <clusterName>',
`
upinfoExample = `
# get current tidb cluster info (set by tkc user)
# get current tidb cluster info (set by tkctl user)
tkctl upinfo
# get specified tidb cluster component upgrade info
Expand Down
51 changes: 31 additions & 20 deletions pkg/webhook/statefulset/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"strconv"

"github.com/golang/glog"
"github.com/pingcap/tidb-operator/pkg/apis/pingcap.com/v1alpha1"
"github.com/pingcap/tidb-operator/pkg/client/clientset/versioned"
"github.com/pingcap/tidb-operator/pkg/label"
"github.com/pingcap/tidb-operator/pkg/webhook/util"
Expand All @@ -43,58 +42,70 @@ func AdmitStatefulSets(ar v1beta1.AdmissionReview) *v1beta1.AdmissionResponse {

name := ar.Request.Name
namespace := ar.Request.Namespace
glog.Infof("admit statefulsets [%s/%s]", name, namespace)
glog.V(4).Infof("admit statefulsets [%s/%s]", namespace, name)

setResource := metav1.GroupVersionResource{Group: "apps", Version: "v1beta1", Resource: "statefulsets"}
if ar.Request.Resource != setResource {
err := fmt.Errorf("expect resource to be %s", setResource)
err := fmt.Errorf("expect resource to be %s instead of %s", setResource, ar.Request.Resource)
glog.Errorf("%v", err)
return util.ARFail(err)
}

if versionCli == nil {
cfg, err := rest.InClusterConfig()
if err != nil {
glog.Errorf("failed to get config: %v", err)
glog.Errorf("statefulset %s/%s, get k8s cluster config failed, err: %v", namespace, name, err)
return util.ARFail(err)
}

versionCli, err = versioned.NewForConfig(cfg)
if err != nil {
glog.Errorf("failed to create Clientset: %v", err)
glog.Errorf("statefulset %s/%s, create Clientset failed, err: %v", namespace, name, err)
return util.ARFail(err)
}
}

raw := ar.Request.OldObject.Raw
set := apps.StatefulSet{}
if _, _, err := deserializer.Decode(raw, nil, &set); err != nil {
glog.Errorf("deseriralizer fail to decode request %v", err)
glog.Errorf("statefulset %s/%s, decode request failed, err: %v", namespace, name, err)
return util.ARFail(err)
}

l := label.Label(set.Labels)

if !(l.IsTiDB() || l.IsTiKV()) {
// If it is not statefulset of tikv and tidb, return quickly.
return util.ARSuccess()
}

tc, err := versionCli.PingcapV1alpha1().TidbClusters(namespace).Get(set.Labels[label.InstanceLabelKey], metav1.GetOptions{})
if err != nil {
glog.Errorf("fail to fetch tidbcluster info namespace %s clustername(instance) %s err %v", namespace, set.Labels[label.InstanceLabelKey], err)
glog.Errorf("get tidbcluster %s/%s failed, statefulset %s, err %v", namespace, set.Labels[label.InstanceLabelKey], name, err)
return util.ARFail(err)
}

if set.Labels[label.ComponentLabelKey] == label.TiDBLabelVal {
protect, ok := tc.Annotations[label.AnnTiDBPartition]
var partitionStr string
partitionStr = tc.Annotations[label.AnnTiDBPartition]
if l.IsTiKV() {
partitionStr = tc.Annotations[label.AnnTiKVPartition]
}

if ok {
partition, err := strconv.ParseInt(protect, 10, 32)
if err != nil {
glog.Errorf("fail to convert protect to int namespace %s name %s err %v", namespace, name, err)
return util.ARFail(err)
}
if len(partitionStr) == 0 {
return util.ARSuccess()
}

if (*set.Spec.UpdateStrategy.RollingUpdate.Partition) <= int32(partition) && tc.Status.TiDB.Phase == v1alpha1.UpgradePhase {
glog.Infof("set has been protect by annotations name %s namespace %s", name, namespace)
return util.ARFail(errors.New("protect by annotation"))
}
}
partition, err := strconv.ParseInt(partitionStr, 10, 32)
if err != nil {
glog.Errorf("statefulset %s/%s, convert partition str %s to int failed, err: %v", namespace, name, partitionStr, err)
return util.ARFail(err)
}

setPartition := *set.Spec.UpdateStrategy.RollingUpdate.Partition
if setPartition > 0 && setPartition <= int32(partition) {
glog.V(4).Infof("statefulset %s/%s has been protect by partition %s annotations", namespace, name, partitionStr)
return util.ARFail(errors.New("protect by partition annotation"))
}
glog.Infof("admit statefulset %s/%s update partition to %d, protect partition is %d", namespace, name, setPartition, partition)
return util.ARSuccess()
}

0 comments on commit 8029dcf

Please sign in to comment.