├── tests ├── e2e │ ├── example │ │ ├── data │ │ └── example.go │ ├── framework │ │ ├── pod.go │ │ ├── s3.go │ │ ├── action │ │ │ ├── delete.go │ │ │ └── update.go │ │ ├── tiproxy.go │ │ ├── tso.go │ │ ├── tikv_worker.go │ │ ├── scheduling.go │ │ └── cert.go │ ├── utils │ │ ├── image │ │ │ └── image.go │ │ ├── portforwarder │ │ │ └── opt.go │ │ ├── data │ │ │ └── namespace.go │ │ ├── s3 │ │ │ └── interface.go │ │ └── waiter │ │ │ ├── tso.go │ │ │ ├── tidb.go │ │ │ └── ticdc.go │ ├── upgrade │ │ └── upgrade_test.go │ ├── data │ │ ├── ns.go │ │ ├── ticdc.go │ │ ├── tso.go │ │ └── scheduling.go │ ├── br │ │ └── utils │ │ │ └── s3 │ │ │ └── interface.go │ ├── tikv │ │ └── topology.go │ └── e2e_test.go └── validation │ └── crd ├── examples ├── pdms │ ├── 00-cluster.yaml │ ├── 02-tso.yaml │ ├── 03-scheduling.yaml │ ├── 04-tikv.yaml │ └── 01-pd.yaml ├── basic │ ├── 00-cluster.yaml │ ├── 05-tiproxy.yaml │ ├── 03-tidb.yaml │ ├── 01-pd.yaml │ ├── 02-tikv.yaml │ ├── 04-tiflash.yaml │ └── 06-ticdc.yaml ├── overlay │ ├── 00-cluster.yaml │ ├── dashboard-session-secret.yaml │ ├── 02-tikv.yaml │ ├── 03-tidb.yaml │ └── 01-pd.yaml ├── schedule-policy │ ├── 00-cluster.yaml │ ├── 03-tidb.yaml │ ├── 01-pd.yaml │ └── 02-tikv.yaml ├── tls │ ├── 00-cluster.yaml │ ├── 03-tidb.yaml │ ├── 01-pd.yaml │ ├── 02-tikv.yaml │ └── 04-tiflash.yaml └── bootstrap-sql │ ├── 00-cluster.yaml │ ├── bsql-cm.yaml │ ├── 03-tidb.yaml │ ├── 01-pd.yaml │ └── 02-tikv.yaml ├── .gitignore ├── .dockerignore ├── cmd ├── resource-syncer │ └── README.md ├── tidb-backup-manager │ ├── main.go │ └── app │ │ └── cmd │ │ └── cmd.go └── testing-workload │ └── ping.go ├── charts └── tidb-operator │ ├── templates │ ├── NOTES.txt │ └── _helpers.tpl │ └── Chart.yaml ├── .codecov.yml ├── tools ├── mockgen │ ├── go.mod │ └── go.sum ├── mdtoc │ ├── go.mod │ └── go.sum ├── ginkgo │ └── go.mod ├── deepcopy-gen │ ├── go.mod │ └── go.sum ├── register-gen │ ├── go.mod │ └── go.sum ├── kind │ └── go.mod └── controller-gen │ └── go.mod ├── OWNERS ├── pkg ├── state │ ├── README.md │ ├── object.go │ └── pd_client.go ├── controllers │ ├── tiflashgroup │ │ └── tasks │ │ │ ├── util.go │ │ │ └── ctx.go │ ├── schedulergroup │ │ └── tasks │ │ │ ├── util.go │ │ │ └── ctx.go │ ├── schedulinggroup │ │ └── tasks │ │ │ ├── util.go │ │ │ └── ctx.go │ ├── ticdcgroup │ │ └── tasks │ │ │ ├── ctx.go │ │ │ └── util.go │ ├── tidbgroup │ │ └── tasks │ │ │ ├── ctx.go │ │ │ └── util.go │ ├── tikvgroup │ │ └── tasks │ │ │ └── ctx.go │ ├── tiproxygroup │ │ └── tasks │ │ │ ├── ctx.go │ │ │ └── util.go │ ├── scheduling │ │ └── tasks │ │ │ ├── ctx.go │ │ │ └── util.go │ ├── br │ │ ├── restore │ │ │ ├── tasks │ │ │ │ ├── ctx.go │ │ │ │ └── restore_manager.go │ │ │ └── builder.go │ │ ├── backup │ │ │ ├── tasks │ │ │ │ ├── ctx.go │ │ │ │ ├── backup_manager.go │ │ │ │ └── backup_cleaner.go │ │ │ └── builder.go │ │ ├── tibr │ │ │ └── tasks │ │ │ │ ├── cluster.go │ │ │ │ └── constants.go │ │ └── tibrgc │ │ │ └── tasks │ │ │ ├── cluster.go │ │ │ └── constants.go │ ├── tsogroup │ │ └── tasks │ │ │ ├── util.go │ │ │ └── ctx.go │ ├── pdgroup │ │ └── tasks │ │ │ └── util.go │ ├── tikv │ │ └── tasks │ │ │ └── finalizer.go │ ├── tidb │ │ └── tasks │ │ │ ├── adopt.go │ │ │ ├── activate.go │ │ │ └── pvc.go │ ├── tso │ │ └── tasks │ │ │ └── util.go │ ├── scheduler │ │ └── tasks │ │ │ └── util.go │ ├── tikvworker │ │ └── tasks │ │ │ └── util.go │ ├── pd │ │ └── tasks │ │ │ ├── finalizer.go │ │ │ └── pvc.go │ ├── tiflash │ │ └── tasks │ │ │ ├── util.go │ │ │ └── finalizer.go │ ├── ticdc │ │ └── tasks │ │ │ ├── pvc.go │ │ │ └── util.go │ └── tiproxy │ │ └── tasks │ │ ├── pvc.go │ │ └── util.go ├── apicall │ └── doc.go ├── timanager │ └── apis │ │ └── pd │ │ └── v1 │ │ ├── doc.go │ │ └── types_test.go ├── apiutil │ └── core │ │ └── v1alpha1 │ │ ├── doc.go │ │ ├── scheduler.go │ │ ├── scheduling.go │ │ ├── ticdc.go │ │ ├── tikv_worker.go │ │ └── util.go ├── utils │ ├── kubefeat │ │ └── feat.go │ ├── string │ │ ├── string.go │ │ └── string_test.go │ ├── integer.go │ ├── random │ │ └── random_test.go │ ├── k8s │ │ ├── rate_limiter.go │ │ ├── event_recorder.go │ │ ├── node_test.go │ │ ├── finalizer.go │ │ └── node.go │ ├── hasher │ │ ├── hasher.go │ │ └── hasher_test.go │ ├── http │ │ ├── error.go │ │ └── error_test.go │ └── time │ │ └── clock.go ├── ticdcapi │ └── v1 │ │ └── types.go ├── compatibility │ ├── feat.go │ └── semver.go ├── metrics │ └── metrics.go ├── pdapi │ └── pd │ │ ├── duration_test.go │ │ └── size_test.go ├── adoption │ ├── instance.go │ └── groups.go ├── tiflashapi │ └── v1 │ │ └── client_test.go ├── volumes │ ├── cloud │ │ └── utils.go │ └── types_test.go ├── tidbapi │ └── v1 │ │ └── types.go ├── features │ └── features.go ├── client │ └── opt.go ├── tikvapi │ └── v1 │ │ └── client_test.go └── version │ └── version_test.go ├── .github ├── workflows │ ├── auto-job-v2.yaml │ └── release-v2.yaml ├── licenserc.yaml └── dependabot.yml ├── hack ├── boilerplate │ ├── boilerplate.txt │ ├── boilerplate.yaml.txt │ └── boilerplate.go.txt ├── e2e.sh ├── build.sh ├── image.sh ├── kind.sh ├── githooks │ └── pre-push ├── verify.sh └── tools.sh ├── api ├── core │ └── v1alpha1 │ │ └── errors.go ├── br │ └── v1alpha1 │ │ ├── constant.go │ │ └── backup_schedule.go ├── go.mod └── meta │ └── v1alpha1 │ └── types.go ├── OWNERS_ALIASES ├── third_party └── kubernetes │ └── pkg │ └── util │ └── hash │ └── hash.go └── docs └── convention.md /tests/e2e/example/data: -------------------------------------------------------------------------------- 1 | ../../../examples -------------------------------------------------------------------------------- /tests/validation/crd: -------------------------------------------------------------------------------- 1 | ../../manifests/crd -------------------------------------------------------------------------------- /examples/pdms/00-cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: Cluster 3 | metadata: 4 | name: pdms 5 | spec: {} 6 | -------------------------------------------------------------------------------- /examples/basic/00-cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: Cluster 3 | metadata: 4 | name: basic 5 | spec: {} 6 | -------------------------------------------------------------------------------- /examples/overlay/00-cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: Cluster 3 | metadata: 4 | name: overlay 5 | spec: {} 6 | -------------------------------------------------------------------------------- /examples/schedule-policy/00-cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: Cluster 3 | metadata: 4 | name: schedule 5 | spec: {} 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _output/ 2 | .idea/ 3 | coverage.txt 4 | .vscode/ 5 | .cursorignore 6 | .DS_Store 7 | **/CLAUDE.md 8 | **/AGENTS.md 9 | .claude/ 10 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | _output/ 2 | .idea/ 3 | coverage.txt 4 | .vscode/ 5 | .cursorignore 6 | .DS_Store 7 | **/CLAUDE.md 8 | **/AGENTS.md 9 | .claude/ 10 | -------------------------------------------------------------------------------- /cmd/resource-syncer/README.md: -------------------------------------------------------------------------------- 1 | # Resource Syncer 2 | 3 | This binary is designed for syncing resources(secrets, configmap, etc...) of kubernetes into pods 4 | -------------------------------------------------------------------------------- /examples/tls/00-cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: Cluster 3 | metadata: 4 | name: tls 5 | spec: 6 | tlsCluster: 7 | enabled: true 8 | -------------------------------------------------------------------------------- /examples/bootstrap-sql/00-cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: Cluster 3 | metadata: 4 | name: bsql 5 | spec: 6 | bootstrapSQL: 7 | name: bsql 8 | -------------------------------------------------------------------------------- /examples/bootstrap-sql/bsql-cm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | bootstrap-sql: | 4 | SET PASSWORD FOR 'root'@'%' = 'pingcap'; 5 | kind: ConfigMap 6 | metadata: 7 | name: bsql 8 | -------------------------------------------------------------------------------- /examples/overlay/dashboard-session-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: dashboard-session-secret 5 | type: Opaque 6 | data: 7 | encryption_key: ZW5jcnlwdGVkLWtleQo= -------------------------------------------------------------------------------- /charts/tidb-operator/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Make sure tidb-operator components are running: 2 | 3 | kubectl get pods --namespace {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} 4 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: no 3 | notify: 4 | wait_for_ci: no 5 | 6 | comment: 7 | layout: "diff, flags" 8 | 9 | parsers: 10 | go: 11 | partials_as_hits: true #false by default 12 | -------------------------------------------------------------------------------- /tools/mockgen/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pingcap/tidb-operator/v2/tools/mockgen 2 | 3 | go 1.24.0 4 | 5 | tool go.uber.org/mock/mockgen 6 | 7 | require ( 8 | go.uber.org/mock v0.6.0 // indirect 9 | golang.org/x/mod v0.27.0 // indirect 10 | golang.org/x/sync v0.16.0 // indirect 11 | golang.org/x/tools v0.36.0 // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | # See the OWNERS docs at https://www.kubernetes.dev/docs/guide/owners/#owners 2 | # The members of 'sig-community-*' are synced from memberships defined in repository: https://github.com/pingcap/community. 3 | filters: 4 | .*: 5 | approvers: 6 | - sig-community-approvers 7 | reviewers: 8 | - sig-community-reviewers 9 | -------------------------------------------------------------------------------- /pkg/state/README.md: -------------------------------------------------------------------------------- 1 | # State 2 | 3 | This package is defined to implement all common state defined for common tasks. 4 | 5 | State defined in a controller can import common state in this package directly to avoid too many duplicated interface implementation. 6 | 7 | Now it only implements 8 | - IFeatureGates 9 | 10 | Expected: 11 | - IObject 12 | -------------------------------------------------------------------------------- /examples/pdms/02-tso.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TSOGroup 3 | metadata: 4 | name: tso 5 | spec: 6 | cluster: 7 | name: pdms 8 | replicas: 1 9 | template: 10 | metadata: 11 | annotations: 12 | author: pingcap 13 | spec: 14 | version: v8.5.2 15 | config: | 16 | [log] 17 | level = "debug" 18 | -------------------------------------------------------------------------------- /examples/bootstrap-sql/03-tidb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiDBGroup 3 | metadata: 4 | name: tidb 5 | labels: 6 | pingcap.com/group: tidb 7 | pingcap.com/component: tidb 8 | pingcap.com/cluster: bsql 9 | spec: 10 | cluster: 11 | name: bsql 12 | version: v8.5.2 13 | replicas: 1 14 | template: 15 | spec: 16 | config: "" 17 | -------------------------------------------------------------------------------- /examples/pdms/03-scheduling.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: SchedulingGroup 3 | metadata: 4 | name: scheduling 5 | spec: 6 | cluster: 7 | name: pdms 8 | replicas: 1 9 | template: 10 | metadata: 11 | annotations: 12 | author: pingcap 13 | spec: 14 | version: v8.5.2 15 | config: | 16 | [log] 17 | level = "debug" 18 | -------------------------------------------------------------------------------- /tools/mdtoc/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pingcap/tidb-operator/v2/tools/mdtoc 2 | 3 | go 1.24.0 4 | 5 | tool sigs.k8s.io/mdtoc 6 | 7 | require ( 8 | github.com/BurntSushi/toml v0.3.1 // indirect 9 | github.com/gomarkdown/markdown v0.0.0-20210514010506-3b9f47219fe7 // indirect 10 | github.com/mmarkdown/mmark v2.0.40+incompatible // indirect 11 | sigs.k8s.io/mdtoc v1.1.0 // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /examples/bootstrap-sql/01-pd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: PDGroup 3 | metadata: 4 | name: pd 5 | labels: 6 | pingcap.com/group: pd 7 | pingcap.com/component: pd 8 | pingcap.com/cluster: bsql 9 | spec: 10 | cluster: 11 | name: bsql 12 | version: v8.5.2 13 | replicas: 3 14 | template: 15 | spec: 16 | config: "" 17 | volumes: 18 | - name: data 19 | mounts: 20 | - type: data 21 | storage: 20Gi 22 | -------------------------------------------------------------------------------- /examples/pdms/04-tikv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiKVGroup 3 | metadata: 4 | name: tikv 5 | spec: 6 | cluster: 7 | name: pdms 8 | replicas: 1 9 | template: 10 | metadata: 11 | annotations: 12 | author: pingcap 13 | spec: 14 | version: v8.5.2 15 | config: | 16 | [log] 17 | level = "info" 18 | volumes: 19 | - name: data 20 | mounts: 21 | - type: data 22 | storage: 100Gi 23 | -------------------------------------------------------------------------------- /examples/bootstrap-sql/02-tikv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiKVGroup 3 | metadata: 4 | name: tikv 5 | labels: 6 | pingcap.com/group: tikv 7 | pingcap.com/component: tikv 8 | pingcap.com/cluster: bsql 9 | spec: 10 | cluster: 11 | name: bsql 12 | version: v8.5.2 13 | replicas: 3 14 | template: 15 | spec: 16 | config: "" 17 | volumes: 18 | - name: data 19 | mounts: 20 | - type: data 21 | storage: 100Gi 22 | -------------------------------------------------------------------------------- /examples/overlay/02-tikv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiKVGroup 3 | metadata: 4 | name: tikv 5 | labels: 6 | pingcap.com/group: tikv 7 | pingcap.com/component: tikv 8 | pingcap.com/cluster: overlay 9 | spec: 10 | cluster: 11 | name: overlay 12 | version: v8.5.2 13 | replicas: 3 14 | template: 15 | spec: 16 | config: "" 17 | volumes: 18 | - name: data 19 | mounts: 20 | - type: data 21 | storage: 100Gi 22 | -------------------------------------------------------------------------------- /examples/pdms/01-pd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: PDGroup 3 | metadata: 4 | name: pd 5 | spec: 6 | cluster: 7 | name: pdms 8 | replicas: 1 9 | template: 10 | metadata: 11 | annotations: 12 | author: pingcap 13 | spec: 14 | version: v8.5.2 15 | mode: ms 16 | config: | 17 | [log] 18 | level = "debug" 19 | volumes: 20 | - name: data 21 | mounts: 22 | - type: data 23 | storage: 20Gi 24 | -------------------------------------------------------------------------------- /examples/basic/05-tiproxy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiProxyGroup 3 | metadata: 4 | name: tiproxy 5 | labels: 6 | pingcap.com/group: tiproxy 7 | pingcap.com/component: tiproxy 8 | pingcap.com/cluster: basic 9 | spec: 10 | cluster: 11 | name: basic 12 | replicas: 3 13 | template: 14 | metadata: 15 | annotations: 16 | author: pingcap 17 | spec: 18 | version: v1.3.1 19 | resources: 20 | cpu: "1" 21 | memory: 2Gi 22 | -------------------------------------------------------------------------------- /examples/tls/03-tidb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiDBGroup 3 | metadata: 4 | name: tidb 5 | labels: 6 | pingcap.com/group: tidb 7 | pingcap.com/component: tidb 8 | pingcap.com/cluster: tls 9 | spec: 10 | cluster: 11 | name: tls 12 | version: v8.5.2 13 | replicas: 1 14 | template: 15 | spec: 16 | security: 17 | tls: 18 | mysql: 19 | enabled: true 20 | config: | 21 | [security] 22 | cluster-verify-cn = ["TiDB"] 23 | -------------------------------------------------------------------------------- /examples/tls/01-pd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: PDGroup 3 | metadata: 4 | name: pd 5 | labels: 6 | pingcap.com/group: pd 7 | pingcap.com/component: pd 8 | pingcap.com/cluster: tls 9 | spec: 10 | cluster: 11 | name: tls 12 | version: v8.5.2 13 | replicas: 3 14 | template: 15 | spec: 16 | config: | 17 | [security] 18 | cert-allowed-cn = ["TiDB"] 19 | volumes: 20 | - name: data 21 | mounts: 22 | - type: data 23 | storage: 20Gi 24 | -------------------------------------------------------------------------------- /tools/ginkgo/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pingcap/tidb-operator/v2/tools/ginkgo 2 | 3 | go 1.24.0 4 | 5 | tool github.com/onsi/ginkgo/v2/ginkgo 6 | 7 | require ( 8 | github.com/Masterminds/semver/v3 v3.4.0 // indirect 9 | github.com/go-task/slim-sprig/v3 v3.0.0 // indirect 10 | github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect 11 | github.com/onsi/ginkgo/v2 v2.27.3 // indirect 12 | golang.org/x/mod v0.27.0 // indirect 13 | golang.org/x/sync v0.16.0 // indirect 14 | golang.org/x/tools v0.36.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /examples/tls/02-tikv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiKVGroup 3 | metadata: 4 | name: tikv 5 | labels: 6 | pingcap.com/group: tikv 7 | pingcap.com/component: tikv 8 | pingcap.com/cluster: tls 9 | spec: 10 | cluster: 11 | name: tls 12 | version: v8.5.2 13 | replicas: 3 14 | template: 15 | spec: 16 | config: | 17 | [security] 18 | cert-allowed-cn = ["TiDB"] 19 | volumes: 20 | - name: data 21 | mounts: 22 | - type: data 23 | storage: 100Gi 24 | -------------------------------------------------------------------------------- /examples/basic/03-tidb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiDBGroup 3 | metadata: 4 | name: tidb 5 | labels: 6 | pingcap.com/group: tidb 7 | pingcap.com/component: tidb 8 | pingcap.com/cluster: basic 9 | spec: 10 | cluster: 11 | name: basic 12 | replicas: 2 13 | template: 14 | metadata: 15 | annotations: 16 | author: pingcap 17 | spec: 18 | version: v8.5.2 19 | resources: 20 | cpu: "1" 21 | memory: 2Gi 22 | config: | 23 | [log] 24 | level = "debug" 25 | -------------------------------------------------------------------------------- /tools/deepcopy-gen/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pingcap/tidb-operator/v2/tools/deepcopy-gen 2 | 3 | go 1.24.0 4 | 5 | tool k8s.io/code-generator/cmd/deepcopy-gen 6 | 7 | require ( 8 | github.com/go-logr/logr v1.4.2 // indirect 9 | github.com/spf13/pflag v1.0.5 // indirect 10 | golang.org/x/mod v0.21.0 // indirect 11 | golang.org/x/sync v0.8.0 // indirect 12 | golang.org/x/tools v0.26.0 // indirect 13 | k8s.io/code-generator v0.32.11 // indirect 14 | k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 // indirect 15 | k8s.io/klog/v2 v2.130.1 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /tools/register-gen/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pingcap/tidb-operator/v2/tools/register-gen 2 | 3 | go 1.24.0 4 | 5 | tool k8s.io/code-generator/cmd/register-gen 6 | 7 | require ( 8 | github.com/go-logr/logr v1.4.2 // indirect 9 | github.com/spf13/pflag v1.0.5 // indirect 10 | golang.org/x/mod v0.21.0 // indirect 11 | golang.org/x/sync v0.8.0 // indirect 12 | golang.org/x/tools v0.26.0 // indirect 13 | k8s.io/code-generator v0.32.11 // indirect 14 | k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 // indirect 15 | k8s.io/klog/v2 v2.130.1 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /.github/workflows/auto-job-v2.yaml: -------------------------------------------------------------------------------- 1 | name: auto-job-v2 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened, reopened, synchronize] 6 | 7 | permissions: 8 | contents: read 9 | pull-requests: write 10 | 11 | jobs: 12 | auto-job: 13 | runs-on: ubuntu-24.04 14 | steps: 15 | - name: Add v2 label if target branch is main or release-2.0 16 | if: github.event.pull_request.base.ref == 'main' || github.event.pull_request.base.ref == 'release-2.0' 17 | uses: actions-ecosystem/action-add-labels@v1 18 | with: 19 | labels: 'v2' 20 | -------------------------------------------------------------------------------- /hack/boilerplate/boilerplate.txt: -------------------------------------------------------------------------------- 1 | Copyright 2024 PingCAP, Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /examples/tls/04-tiflash.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiFlashGroup 3 | metadata: 4 | name: tiflash 5 | labels: 6 | pingcap.com/group: tiflash 7 | pingcap.com/component: tiflash 8 | pingcap.com/cluster: tls 9 | spec: 10 | cluster: 11 | name: tls 12 | version: v8.5.2 13 | replicas: 1 14 | template: 15 | spec: 16 | config: | 17 | [security] 18 | cert_allowed_cn = ["TiDB"] 19 | proxyConfig: | 20 | [security] 21 | cert-allowed-cn = ["TiDB"] 22 | volumes: 23 | - name: data 24 | mounts: 25 | - type: data 26 | storage: 100Gi 27 | -------------------------------------------------------------------------------- /hack/boilerplate/boilerplate.yaml.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2024 PingCAP, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /charts/tidb-operator/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | description: tidb-operator Helm chart for Kubernetes 3 | name: tidb-operator 4 | home: https://github.com/pingcap/tidb-operator 5 | sources: 6 | - https://github.com/pingcap/tidb-operator 7 | keywords: 8 | - operator 9 | - newsql 10 | - htap 11 | - database 12 | - mysql 13 | - raft 14 | maintainers: 15 | - name: csuzhangxc 16 | email: zhangxuecheng@pingcap.com 17 | - name: liubog2008 18 | email: liubo02@pingcap.com 19 | - name: fgksgf 20 | email: jianghuaxi@pingcap.com 21 | 22 | kubeVersion: ">=1.30.0-0" 23 | 24 | # will be set when package 25 | version: v0.0.0 26 | appVersion: v0.0.0 27 | -------------------------------------------------------------------------------- /examples/basic/01-pd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: PDGroup 3 | metadata: 4 | name: pd 5 | labels: 6 | pingcap.com/group: pd 7 | pingcap.com/component: pd 8 | pingcap.com/cluster: basic 9 | spec: 10 | cluster: 11 | name: basic 12 | replicas: 1 13 | template: 14 | metadata: 15 | annotations: 16 | author: pingcap 17 | spec: 18 | version: v8.5.2 19 | resources: 20 | cpu: "4" 21 | memory: 8Gi 22 | config: | 23 | [log] 24 | level = "debug" 25 | volumes: 26 | - name: data 27 | mounts: 28 | - type: data 29 | storage: 20Gi 30 | -------------------------------------------------------------------------------- /hack/boilerplate/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | -------------------------------------------------------------------------------- /examples/basic/02-tikv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiKVGroup 3 | metadata: 4 | name: tikv 5 | labels: 6 | pingcap.com/group: tikv 7 | pingcap.com/component: tikv 8 | pingcap.com/cluster: basic 9 | spec: 10 | cluster: 11 | name: basic 12 | replicas: 3 13 | template: 14 | metadata: 15 | annotations: 16 | author: pingcap 17 | spec: 18 | version: v8.5.2 19 | resources: 20 | cpu: "4" 21 | memory: 8Gi 22 | config: | 23 | [log] 24 | level = "info" 25 | volumes: 26 | - name: data 27 | mounts: 28 | - type: data 29 | storage: 100Gi 30 | -------------------------------------------------------------------------------- /tests/e2e/framework/pod.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package framework 16 | -------------------------------------------------------------------------------- /pkg/controllers/tiflashgroup/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | -------------------------------------------------------------------------------- /pkg/controllers/schedulergroup/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | -------------------------------------------------------------------------------- /pkg/controllers/schedulinggroup/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | -------------------------------------------------------------------------------- /examples/basic/04-tiflash.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiFlashGroup 3 | metadata: 4 | name: tiflash 5 | labels: 6 | pingcap.com/group: tiflash 7 | pingcap.com/component: tiflash 8 | pingcap.com/cluster: basic 9 | spec: 10 | cluster: 11 | name: basic 12 | replicas: 1 13 | template: 14 | metadata: 15 | annotations: 16 | author: pingcap 17 | spec: 18 | version: v8.5.2 19 | resources: 20 | cpu: "4" 21 | memory: 8Gi 22 | config: | 23 | mark_cache_size = 1073741824 24 | proxyConfig: "" 25 | volumes: 26 | - name: data 27 | mounts: 28 | - type: data 29 | storage: 100Gi 30 | -------------------------------------------------------------------------------- /examples/overlay/03-tidb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiDBGroup 3 | metadata: 4 | name: tidb 5 | labels: 6 | pingcap.com/group: tidb 7 | pingcap.com/component: tidb 8 | pingcap.com/cluster: overlay 9 | spec: 10 | cluster: 11 | name: overlay 12 | version: v8.5.2 13 | replicas: 2 14 | template: 15 | spec: 16 | config: "" 17 | overlay: 18 | pod: 19 | spec: 20 | terminationGracePeriodSeconds: 120 21 | securityContext: 22 | sysctls: 23 | - name: "net.ipv4.tcp_keepalive_intvl" 24 | value: "75" 25 | - name: "net.ipv4.tcp_keepalive_time" 26 | value: "300" 27 | -------------------------------------------------------------------------------- /pkg/controllers/ticdcgroup/tasks/ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | type ReconcileContext struct { 18 | State 19 | } 20 | -------------------------------------------------------------------------------- /pkg/controllers/tidbgroup/tasks/ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | type ReconcileContext struct { 18 | State 19 | } 20 | -------------------------------------------------------------------------------- /pkg/controllers/tiflashgroup/tasks/ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | type ReconcileContext struct { 18 | State 19 | } 20 | -------------------------------------------------------------------------------- /pkg/controllers/tikvgroup/tasks/ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | type ReconcileContext struct { 18 | State 19 | } 20 | -------------------------------------------------------------------------------- /pkg/controllers/tiproxygroup/tasks/ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | type ReconcileContext struct { 18 | State 19 | } 20 | -------------------------------------------------------------------------------- /pkg/apicall/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package apicall defines many useful functions to fetch data by kubernetes api 16 | package apicall 17 | -------------------------------------------------------------------------------- /pkg/controllers/schedulergroup/tasks/ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | type ReconcileContext struct { 18 | State 19 | } 20 | -------------------------------------------------------------------------------- /pkg/controllers/schedulinggroup/tasks/ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | type ReconcileContext struct { 18 | State 19 | } 20 | -------------------------------------------------------------------------------- /pkg/timanager/apis/pd/v1/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // +groupName=pd.pingcap.com 16 | // +versionName=v1 17 | // +k8s:deepcopy-gen=package 18 | package v1 19 | -------------------------------------------------------------------------------- /pkg/apiutil/core/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package coreutil is defined to get/set some fields in complex core/v1alpha1 api structs 16 | package coreutil 17 | -------------------------------------------------------------------------------- /pkg/utils/kubefeat/feat.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package kubefeat 16 | 17 | type Feature string 18 | 19 | var VolumeAttributesClass Feature = "VolumeAttributesClass" 20 | -------------------------------------------------------------------------------- /.github/licenserc.yaml: -------------------------------------------------------------------------------- 1 | header: 2 | license: 3 | spdx-id: Apache-2.0 4 | copyright-owner: 'PingCAP, Inc.' 5 | copyright-year: '2024' 6 | paths-ignore: 7 | - '**/.git/**' 8 | - .github/ 9 | - _output/** 10 | - ci/** 11 | - examples/** 12 | - charts/** 13 | - image/** 14 | - manifests/** 15 | - .gitignore 16 | - .dockerignore 17 | - .golangci.yml 18 | - LICENSES/ 19 | - '**/*.md' 20 | - .codecov.yml 21 | - '**/go.mod' 22 | - '**/go.sum' 23 | - '**/go.work' 24 | - '**/go.work.sum' 25 | - '**/LICENSE' 26 | - tests/validation/crd 27 | - third_party/** 28 | - tests/e2e/example/data 29 | - '**/OWNERS' 30 | - OWNERS_ALIASES 31 | - .cursorignore 32 | - .claude/** 33 | comment: on-failure 34 | -------------------------------------------------------------------------------- /pkg/controllers/scheduling/tasks/ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | type ReconcileContext struct { 18 | // TODO: replace all fields in ReconcileContext by State 19 | State 20 | } 21 | -------------------------------------------------------------------------------- /examples/schedule-policy/03-tidb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiDBGroup 3 | metadata: 4 | name: tidb 5 | labels: 6 | pingcap.com/group: tidb 7 | pingcap.com/component: tidb 8 | pingcap.com/cluster: schedule 9 | spec: 10 | cluster: 11 | name: schedule 12 | version: v8.5.2 13 | replicas: 2 14 | # All TiDB instances in the group will evenly spread in differnet zones 15 | schedulePolicies: 16 | - type: EvenlySpread 17 | evenlySpread: 18 | topologies: 19 | - topology: 20 | topology.kubernetes.io/zone: us-west-2a 21 | - topology: 22 | topology.kubernetes.io/zone: us-west-2b 23 | - topology: 24 | topology.kubernetes.io/zone: us-west-2c 25 | template: 26 | spec: 27 | config: "" 28 | 29 | 30 | -------------------------------------------------------------------------------- /pkg/controllers/ticdcgroup/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "fmt" 19 | ) 20 | 21 | func RBACName(groupName string) string { 22 | return fmt.Sprintf("%s-ticdc", groupName) 23 | } 24 | -------------------------------------------------------------------------------- /api/core/v1alpha1/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package v1alpha1 16 | 17 | import ( 18 | "errors" 19 | ) 20 | 21 | var ErrFieldIsManagedByOperator = errors.New("field is managed by operator, cannot be set in config file") 22 | -------------------------------------------------------------------------------- /pkg/controllers/tidbgroup/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "fmt" 19 | ) 20 | 21 | func InternalServiceName(groupName string) string { 22 | return fmt.Sprintf("%s-tidb", groupName) 23 | } 24 | -------------------------------------------------------------------------------- /hack/e2e.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2024 PingCAP, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | set -o errexit 18 | set -o nounset 19 | set -o pipefail 20 | 21 | ROOT=$(cd $(dirname "${BASH_SOURCE[0]}")/..; pwd -P) 22 | 23 | source $ROOT/hack/lib/e2e.sh 24 | 25 | e2e::e2e "$@" 26 | -------------------------------------------------------------------------------- /pkg/controllers/tiproxygroup/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "fmt" 19 | ) 20 | 21 | func InternalServiceName(groupName string) string { 22 | return fmt.Sprintf("%s-tiproxy", groupName) 23 | } 24 | -------------------------------------------------------------------------------- /tools/kind/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pingcap/tidb-operator/v2/tools/kind 2 | 3 | go 1.24.0 4 | 5 | tool sigs.k8s.io/kind 6 | 7 | require ( 8 | github.com/BurntSushi/toml v1.4.0 // indirect 9 | github.com/alessio/shellescape v1.4.2 // indirect 10 | github.com/evanphx/json-patch/v5 v5.6.0 // indirect 11 | github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect 12 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 13 | github.com/mattn/go-isatty v0.0.20 // indirect 14 | github.com/pelletier/go-toml v1.9.5 // indirect 15 | github.com/pkg/errors v0.9.1 // indirect 16 | github.com/spf13/cobra v1.8.0 // indirect 17 | github.com/spf13/pflag v1.0.5 // indirect 18 | golang.org/x/sys v0.6.0 // indirect 19 | gopkg.in/yaml.v3 v3.0.1 // indirect 20 | sigs.k8s.io/kind v0.24.0 // indirect 21 | sigs.k8s.io/yaml v1.4.0 // indirect 22 | ) 23 | -------------------------------------------------------------------------------- /hack/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2024 PingCAP, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | set -o errexit 18 | set -o nounset 19 | set -o pipefail 20 | 21 | ROOT=$(cd $(dirname "${BASH_SOURCE[0]}")/..; pwd -P) 22 | 23 | source $ROOT/hack/lib/vars.sh 24 | source $ROOT/hack/lib/build.sh 25 | 26 | build::all ${@} 27 | -------------------------------------------------------------------------------- /hack/image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2024 PingCAP, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | set -o errexit 18 | set -o nounset 19 | set -o pipefail 20 | 21 | ROOT=$(cd $(dirname "${BASH_SOURCE[0]}")/..; pwd -P) 22 | 23 | source $ROOT/hack/lib/vars.sh 24 | source $ROOT/hack/lib/image.sh 25 | 26 | image::build $@ 27 | -------------------------------------------------------------------------------- /examples/overlay/01-pd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: PDGroup 3 | metadata: 4 | name: pd 5 | labels: 6 | pingcap.com/group: pd 7 | pingcap.com/component: pd 8 | pingcap.com/cluster: overlay 9 | spec: 10 | cluster: 11 | name: overlay 12 | version: v8.5.2 13 | replicas: 3 14 | template: 15 | spec: 16 | config: "" 17 | volumes: 18 | - name: data 19 | path: /var/lib/pd 20 | mounts: 21 | - type: data 22 | storage: 20Gi 23 | overlay: 24 | pod: 25 | spec: 26 | containers: 27 | - name: pd 28 | env: 29 | - name: "DASHBOARD_SESSION_SECRET" 30 | valueFrom: 31 | secretKeyRef: 32 | name: "dashboard-session-secret" 33 | key: "encryption_key" 34 | -------------------------------------------------------------------------------- /hack/kind.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2024 PingCAP, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | set -o errexit 18 | set -o nounset 19 | set -o pipefail 20 | 21 | ROOT=$(cd $(dirname "${BASH_SOURCE[0]}")/..; pwd -P) 22 | 23 | source $ROOT/hack/lib/vars.sh 24 | source $ROOT/hack/lib/kind.sh 25 | 26 | kind::ensure_cluster 27 | -------------------------------------------------------------------------------- /hack/githooks/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2024 PingCAP, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | 18 | set -e 19 | 20 | echo "Running pre-push hook..." 21 | make check 22 | if [ $? -ne 0 ]; then 23 | echo "Pre-push checks failed. Please fix the issues before pushing." 24 | exit 1 25 | fi 26 | echo "Pre-push checks passed." 27 | exit 0 -------------------------------------------------------------------------------- /hack/verify.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2024 PingCAP, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | set -o errexit 18 | set -o nounset 19 | set -o pipefail 20 | 21 | ROOT=$(cd $(dirname "${BASH_SOURCE[0]}")/..; pwd -P) 22 | 23 | source $ROOT/hack/lib/verify.sh 24 | 25 | verify::generated "generated files are out of date" "Please run: $*" "$@" 26 | -------------------------------------------------------------------------------- /examples/schedule-policy/01-pd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: PDGroup 3 | metadata: 4 | name: pd 5 | labels: 6 | pingcap.com/group: pd 7 | pingcap.com/component: pd 8 | pingcap.com/cluster: schedule 9 | spec: 10 | cluster: 11 | name: schedule 12 | version: v8.5.2 13 | replicas: 3 14 | # All PD instances in the group will evenly spread in differnet zones 15 | schedulePolicies: 16 | - type: EvenlySpread 17 | evenlySpread: 18 | topologies: 19 | - topology: 20 | topology.kubernetes.io/zone: us-west-2a 21 | - topology: 22 | topology.kubernetes.io/zone: us-west-2b 23 | - topology: 24 | topology.kubernetes.io/zone: us-west-2c 25 | template: 26 | spec: 27 | config: "" 28 | volumes: 29 | - name: data 30 | mounts: 31 | - type: data 32 | storage: 20Gi 33 | -------------------------------------------------------------------------------- /examples/schedule-policy/02-tikv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiKVGroup 3 | metadata: 4 | name: tikv 5 | labels: 6 | pingcap.com/group: tikv 7 | pingcap.com/component: tikv 8 | pingcap.com/cluster: schedule 9 | spec: 10 | cluster: 11 | name: schedule 12 | version: v8.5.2 13 | replicas: 3 14 | # All TiKV instances in the group will evenly spread in differnet zones 15 | schedulePolicies: 16 | - type: EvenlySpread 17 | evenlySpread: 18 | topologies: 19 | - topology: 20 | topology.kubernetes.io/zone: us-west-2a 21 | - topology: 22 | topology.kubernetes.io/zone: us-west-2b 23 | - topology: 24 | topology.kubernetes.io/zone: us-west-2c 25 | template: 26 | spec: 27 | config: "" 28 | volumes: 29 | - name: data 30 | mounts: 31 | - type: data 32 | storage: 100Gi 33 | -------------------------------------------------------------------------------- /cmd/tidb-backup-manager/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "os" 19 | 20 | "k8s.io/klog/v2" 21 | 22 | "github.com/pingcap/tidb-operator/v2/cmd/tidb-backup-manager/app" 23 | ) 24 | 25 | func main() { 26 | klog.InitFlags(nil) 27 | if err := app.Run(); err != nil { 28 | os.Exit(1) 29 | } 30 | os.Exit(0) 31 | } 32 | -------------------------------------------------------------------------------- /pkg/utils/string/string.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package stringutil 16 | 17 | import "strings" 18 | 19 | // RemoveHTTPPrefix removes the http:// or https:// prefix from the given URL. 20 | func RemoveHTTPPrefix(url string) string { 21 | url = strings.TrimPrefix(url, "http://") 22 | url = strings.TrimPrefix(url, "https://") 23 | return url 24 | } 25 | -------------------------------------------------------------------------------- /pkg/state/object.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package state 16 | 17 | import ( 18 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 19 | "github.com/pingcap/tidb-operator/v2/pkg/client" 20 | ) 21 | 22 | type IObject[T client.Object] interface { 23 | Object() T 24 | } 25 | 26 | type ICluster interface { 27 | Cluster() *v1alpha1.Cluster 28 | } 29 | -------------------------------------------------------------------------------- /tests/e2e/utils/image/image.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package image 16 | 17 | var ( 18 | TiDBPreviousVersions []string = []string{"v8.1.0"} 19 | ) 20 | 21 | const ( 22 | // TiDB Version 23 | TiDBLatestPrev = "v8.1.0" 24 | TiDBLatest = "v8.2.0" // different version with PDMSImage 25 | 26 | // specific version 27 | // TiDBV7x5x3 = "v7.5.3" 28 | ) 29 | -------------------------------------------------------------------------------- /tests/e2e/framework/s3.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package framework 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/pingcap/tidb-operator/v2/tests/e2e/utils/s3" 21 | ) 22 | 23 | func (f *Framework) MustCreateS3(ctx context.Context) { 24 | s, err := s3.New("minio", f.restConfig) 25 | f.Must(err) 26 | f.Must(s.Init(ctx, f.Namespace.Name)) 27 | } 28 | -------------------------------------------------------------------------------- /.github/workflows/release-v2.yaml: -------------------------------------------------------------------------------- 1 | name: release-v2 2 | 3 | run-name: Release ${{ github.ref_name }} 4 | 5 | on: 6 | push: 7 | tags: 8 | - "v2.*.*" 9 | 10 | jobs: 11 | release: 12 | permissions: 13 | contents: write 14 | packages: write 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: make release ${{ github.ref_name }} 19 | run: V_RELEASE=${{ github.ref_name }} make release 20 | - name: release 21 | uses: softprops/action-gh-release@v2 22 | with: 23 | files: | 24 | _output/manifests/tidb-operator.crds.yaml 25 | _output/manifests/tidb-operator.yaml 26 | - name: push charts 27 | run: | 28 | echo "${{ github.token }}" | ./_output/bin/helm registry login -u pingcap ghcr.io --password-stdin 29 | ./_output/bin/helm push ./_output/manifests/tidb-operator-${{ github.ref_name }}.tgz oci://ghcr.io/pingcap/charts 30 | 31 | 32 | -------------------------------------------------------------------------------- /pkg/controllers/br/restore/tasks/ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | restoreMgr "github.com/pingcap/tidb-operator/v2/pkg/controllers/br/manager/restore" 19 | ) 20 | 21 | type Config struct { 22 | BackupManagerImage string 23 | } 24 | type ReconcileContext struct { 25 | State 26 | 27 | Config Config 28 | RestoreManager restoreMgr.RestoreManager 29 | } 30 | -------------------------------------------------------------------------------- /pkg/controllers/br/backup/tasks/ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/br/manager/backup" 19 | ) 20 | 21 | type Config struct { 22 | BackupManagerImage string 23 | } 24 | type ReconcileContext struct { 25 | State 26 | 27 | Config Config 28 | BackupManager backup.BackupManager 29 | BackupCleaner backup.BackupCleaner 30 | } 31 | -------------------------------------------------------------------------------- /api/br/v1alpha1/constant.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package v1alpha1 16 | 17 | const ( 18 | // DirPathBRBin is the directory path of br binary 19 | DirPathBRBin = "/var/lib/br-bin" 20 | ) 21 | 22 | const ( 23 | // Label value for meta.LabelKeyComponent 24 | LabelValComponentBackup = "backup" 25 | LabelValComponentRestore = "restore" 26 | LabelValComponentTiBR = "tibr" 27 | LabelValComponentTiBRGC = "tibrgc" 28 | ) 29 | -------------------------------------------------------------------------------- /cmd/testing-workload/ping.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "context" 19 | "database/sql" 20 | "time" 21 | ) 22 | 23 | const defaultTimeout = 10 * time.Second 24 | 25 | func Ping(ctx context.Context, db *sql.DB) error { 26 | ctx, cancel := context.WithTimeout(ctx, defaultTimeout) 27 | defer cancel() 28 | 29 | if err := db.PingContext(ctx); err != nil { 30 | return err 31 | } 32 | 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /pkg/utils/integer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | type Integer interface { 18 | int | int32 | int64 19 | } 20 | 21 | // ValuesDiffer determines whether the values pointed by two integer pointers are different. 22 | // If either a or b is nil, returns false. Otherwise, returns true if *a != *b. 23 | func ValuesDiffer[T Integer](a, b *T) bool { 24 | if a == nil || b == nil { 25 | return false 26 | } 27 | return *a != *b 28 | } 29 | -------------------------------------------------------------------------------- /examples/basic/06-ticdc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: core.pingcap.com/v1alpha1 2 | kind: TiCDCGroup 3 | metadata: 4 | name: ticdc 5 | labels: 6 | pingcap.com/group: ticdc 7 | pingcap.com/component: ticdc 8 | pingcap.com/cluster: basic 9 | spec: 10 | cluster: 11 | name: basic 12 | replicas: 2 13 | template: 14 | metadata: 15 | annotations: 16 | author: pingcap 17 | spec: 18 | version: v8.5.2 19 | resources: 20 | cpu: "1" 21 | memory: 2Gi 22 | overlay: 23 | pod: 24 | spec: 25 | containers: 26 | - name: ticdc 27 | volumeMounts: 28 | - mountPath: /var/lib/ticdc 29 | name: data 30 | volumes: 31 | - ephemeral: 32 | volumeClaimTemplate: 33 | spec: 34 | accessModes: 35 | - ReadWriteOnce 36 | resources: 37 | requests: 38 | storage: 100Gi 39 | name: data 40 | -------------------------------------------------------------------------------- /tests/e2e/utils/portforwarder/opt.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package portforwarder 16 | 17 | import "io" 18 | 19 | type Options struct { 20 | Writer io.Writer 21 | } 22 | 23 | type Option interface { 24 | With(*Options) 25 | } 26 | 27 | type OptionFunc func(*Options) 28 | 29 | func (f OptionFunc) With(opts *Options) { 30 | f(opts) 31 | } 32 | 33 | func WithWriter(w io.Writer) Option { 34 | return OptionFunc(func(o *Options) { 35 | o.Writer = w 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /pkg/utils/random/random_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package random 16 | 17 | import ( 18 | "regexp" 19 | "testing" 20 | 21 | "github.com/stretchr/testify/assert" 22 | ) 23 | 24 | func TestRandom(t *testing.T) { 25 | re := regexp.MustCompile("^[" + letterBytes + "]{6}$") 26 | m := map[string]struct{}{} 27 | for i := 0; i < 1000; i++ { 28 | s := Random(6) 29 | assert.Regexp(t, re, s) 30 | _, ok := m[s] 31 | assert.False(t, ok) 32 | m[s] = struct{}{} 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/e2e/upgrade/upgrade_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | //go:build upgrade_e2e 16 | 17 | package upgrade 18 | 19 | import ( 20 | "io" 21 | "testing" 22 | 23 | . "github.com/onsi/ginkgo/v2" 24 | . "github.com/onsi/gomega" 25 | ctrl "sigs.k8s.io/controller-runtime" 26 | "sigs.k8s.io/controller-runtime/pkg/log/zap" 27 | ) 28 | 29 | func TestUpgrade(t *testing.T) { 30 | ctrl.SetLogger(zap.New(zap.WriteTo(io.Discard))) 31 | 32 | RegisterFailHandler(Fail) 33 | RunSpecs(t, "Upgrade E2E Suite") 34 | } 35 | -------------------------------------------------------------------------------- /pkg/utils/k8s/rate_limiter.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package k8s 16 | 17 | import ( 18 | "time" 19 | 20 | "k8s.io/client-go/util/workqueue" 21 | ctrl "sigs.k8s.io/controller-runtime" 22 | ) 23 | 24 | const ( 25 | controllerInitDelay = 1 * time.Second 26 | controllerMaxInterval = 1 * time.Minute 27 | ) 28 | 29 | var RateLimiter = workqueue.NewTypedMaxOfRateLimiter[ctrl.Request]( 30 | workqueue.NewTypedItemExponentialFailureRateLimiter[ctrl.Request](controllerInitDelay, controllerMaxInterval), 31 | ) 32 | -------------------------------------------------------------------------------- /OWNERS_ALIASES: -------------------------------------------------------------------------------- 1 | # See the OWNERS docs at https://www.kubernetes.dev/docs/guide/owners/#owners_aliases 2 | # The members of 'sig-community-*' are synced from memberships defined in repository: https://github.com/pingcap/community. 3 | aliases: 4 | sig-community-reviewers: 5 | - cvvz 6 | - howardlau1999 7 | - lichunzhu 8 | - shonge 9 | sig-community-approvers: 10 | - AstroProfundis 11 | - Benjamin2037 12 | - BornChanger 13 | - DanielZhangQD 14 | - Ehco1996 15 | - HuSharp 16 | - KanShiori 17 | - LinuxGit 18 | - WangLe1321 19 | - WizardXiao 20 | - Yisaer 21 | - aylei 22 | - azurezyq 23 | - charleszheng44 24 | - cofyc 25 | - csuzhangxc 26 | - dragonly 27 | - fengou1 28 | - fgksgf 29 | - gozssky 30 | - gregwebs 31 | - grovecai 32 | - handlerww 33 | - hanlins 34 | - jlerche 35 | - july2993 36 | - liubog2008 37 | - mikechengwei 38 | - niubell 39 | - onlymellb 40 | - qiffang 41 | - sdojjy 42 | - shuijing198799 43 | - srstack 44 | - tennix 45 | - weekface 46 | - z2665 47 | - zimulala 48 | -------------------------------------------------------------------------------- /charts/tidb-operator/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "chart.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "tidb-operator.fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | 18 | {{/* 19 | It is copied from https://github.com/cert-manager/cert-manager/blob/v1.17.2/deploy/charts/cert-manager/templates/_helpers.tpl 20 | */}} 21 | {{- define "image" -}} 22 | {{- $defaultTag := index . 1 -}} 23 | {{- with index . 0 -}} 24 | {{- if .registry -}}{{ printf "%s/%s" .registry .repository }}{{- else -}}{{- .repository -}}{{- end -}} 25 | {{- if .digest -}}{{ printf "@%s" .digest }}{{- else -}}{{ printf ":%s" (default $defaultTag .tag) }}{{- end -}} 26 | {{- end }} 27 | {{- end }} 28 | -------------------------------------------------------------------------------- /pkg/controllers/br/tibr/tasks/cluster.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/common" 19 | t "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 20 | ) 21 | 22 | func CondClusterNotFound(rtx *ReconcileContext) t.Condition { 23 | return t.CondFunc(func() bool { 24 | return rtx.Cluster() == nil 25 | }) 26 | } 27 | 28 | func CondClusterIsNotReadyForBR(rtx *ReconcileContext) t.Condition { 29 | return common.CondClusterPDAddrIsNotRegistered(rtx) 30 | } 31 | -------------------------------------------------------------------------------- /pkg/controllers/br/tibrgc/tasks/cluster.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/common" 19 | t "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 20 | ) 21 | 22 | func CondClusterNotFound(rtx *ReconcileContext) t.Condition { 23 | return t.CondFunc(func() bool { 24 | return rtx.Cluster() == nil 25 | }) 26 | } 27 | 28 | func CondClusterIsNotReadyForBRGC(rtx *ReconcileContext) t.Condition { 29 | return common.CondClusterPDAddrIsNotRegistered(rtx) 30 | } 31 | -------------------------------------------------------------------------------- /pkg/utils/hasher/hasher.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package hasher 16 | 17 | import ( 18 | "fmt" 19 | "hash/fnv" 20 | 21 | "k8s.io/apimachinery/pkg/util/rand" 22 | 23 | hashutil "github.com/pingcap/tidb-operator/v2/third_party/kubernetes/pkg/util/hash" 24 | ) 25 | 26 | // Hash an obj by this struct 27 | // NOTE: It may be changed if struct's fields are added or deleted. e.g. dep is upgraded 28 | func Hash(obj any) string { 29 | hasher := fnv.New32a() 30 | hashutil.DeepHashObject(hasher, obj) 31 | return rand.SafeEncodeString(fmt.Sprint(hasher.Sum32())) 32 | } 33 | -------------------------------------------------------------------------------- /pkg/controllers/tsogroup/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "github.com/pingcap/tidb-operator/v2/pkg/runtime" 19 | "github.com/pingcap/tidb-operator/v2/pkg/updater" 20 | ) 21 | 22 | func NotLeaderPolicy() updater.PreferPolicy[*runtime.TSO] { 23 | return updater.PreferPolicyFunc[*runtime.TSO](func(tsos []*runtime.TSO) []*runtime.TSO { 24 | var notLeader []*runtime.TSO 25 | for _, tso := range tsos { 26 | if !tso.Status.IsDefaultPrimary { 27 | notLeader = append(notLeader, tso) 28 | } 29 | } 30 | return notLeader 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /tests/e2e/framework/action/delete.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package action 16 | 17 | import ( 18 | "context" 19 | "fmt" 20 | 21 | "github.com/onsi/ginkgo/v2" 22 | "github.com/onsi/gomega" 23 | 24 | "github.com/pingcap/tidb-operator/v2/pkg/client" 25 | "github.com/pingcap/tidb-operator/v2/tests/e2e/framework" 26 | ) 27 | 28 | func MustDelete(ctx context.Context, f *framework.Framework, obj client.Object) { 29 | ginkgo.By(fmt.Sprintf("delete %v", client.ObjectKeyFromObject(obj))) 30 | 31 | err := f.Client.Delete(ctx, obj) 32 | gomega.ExpectWithOffset(1, err).To(gomega.Succeed()) 33 | } 34 | -------------------------------------------------------------------------------- /pkg/state/pd_client.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package state 16 | 17 | import "github.com/pingcap/tidb-operator/v2/pkg/pdapi/v1" 18 | 19 | type IPDClient interface { 20 | GetPDClient() pdapi.PDClient 21 | SetPDClient(pdapi.PDClient) 22 | } 23 | 24 | type pdClientState struct { 25 | pdClient pdapi.PDClient 26 | } 27 | 28 | func (s *pdClientState) GetPDClient() pdapi.PDClient { 29 | return s.pdClient 30 | } 31 | 32 | func (s *pdClientState) SetPDClient(pdClient pdapi.PDClient) { 33 | s.pdClient = pdClient 34 | } 35 | 36 | func NewPDClientState() IPDClient { 37 | return &pdClientState{} 38 | } 39 | -------------------------------------------------------------------------------- /pkg/timanager/apis/pd/v1/types_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package v1 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | ) 23 | 24 | func TestEngine(t *testing.T) { 25 | // we only have two engines now, TiKV and TiFlash 26 | s1 := Store{} 27 | assert.Equal(t, StoreEngine("tikv"), s1.Engine()) 28 | 29 | s2 := Store{ 30 | ObjectMeta: metav1.ObjectMeta{ 31 | Labels: map[string]string{ 32 | "engine": "tiflash", 33 | }, 34 | }, 35 | } 36 | assert.Equal(t, StoreEngine("tiflash"), s2.Engine()) 37 | } 38 | -------------------------------------------------------------------------------- /api/br/v1alpha1/backup_schedule.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package v1alpha1 16 | 17 | import ( 18 | "fmt" 19 | "time" 20 | ) 21 | 22 | func (bs *BackupSchedule) GetBackupCRDName(timestamp time.Time) string { 23 | return fmt.Sprintf("%s-%s", bs.GetName(), timestamp.UTC().Format(BackupNameTimeFormat)) 24 | } 25 | 26 | func (bs *BackupSchedule) GetLogBackupCRDName() string { 27 | return fmt.Sprintf("%s-%s", "log", bs.GetName()) 28 | } 29 | 30 | func (bs *BackupSchedule) GetCompactBackupCRDName(timestamp time.Time) string { 31 | return fmt.Sprintf("%s-%s-%s", "compact", bs.GetName(), timestamp.UTC().Format(BackupNameTimeFormat)) 32 | } 33 | -------------------------------------------------------------------------------- /pkg/apiutil/core/v1alpha1/scheduler.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package coreutil 16 | 17 | import ( 18 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 19 | ) 20 | 21 | func SchedulerClientPort(s *v1alpha1.Scheduler) int32 { 22 | if s.Spec.Server.Ports.Client != nil { 23 | return s.Spec.Server.Ports.Client.Port 24 | } 25 | return v1alpha1.DefaultSchedulerPortClient 26 | } 27 | 28 | func SchedulerGroupClientPort(sg *v1alpha1.SchedulerGroup) int32 { 29 | if sg.Spec.Template.Spec.Server.Ports.Client != nil { 30 | return sg.Spec.Template.Spec.Server.Ports.Client.Port 31 | } 32 | return v1alpha1.DefaultSchedulerPortClient 33 | } 34 | -------------------------------------------------------------------------------- /pkg/apiutil/core/v1alpha1/scheduling.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package coreutil 16 | 17 | import ( 18 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 19 | ) 20 | 21 | func SchedulingClientPort(s *v1alpha1.Scheduling) int32 { 22 | if s.Spec.Server.Ports.Client != nil { 23 | return s.Spec.Server.Ports.Client.Port 24 | } 25 | return v1alpha1.DefaultSchedulingPortClient 26 | } 27 | 28 | func SchedulingGroupClientPort(sg *v1alpha1.SchedulingGroup) int32 { 29 | if sg.Spec.Template.Spec.Server.Ports.Client != nil { 30 | return sg.Spec.Template.Spec.Server.Ports.Client.Port 31 | } 32 | return v1alpha1.DefaultSchedulingPortClient 33 | } 34 | -------------------------------------------------------------------------------- /api/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pingcap/tidb-operator/api/v2 2 | 3 | go 1.23.0 4 | 5 | require ( 6 | github.com/onsi/gomega v1.38.3 7 | k8s.io/api v0.32.11 8 | k8s.io/apimachinery v0.32.11 9 | k8s.io/klog/v2 v2.130.1 10 | k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 11 | ) 12 | 13 | require ( 14 | github.com/fxamacker/cbor/v2 v2.7.0 // indirect 15 | github.com/go-logr/logr v1.4.3 // indirect 16 | github.com/gogo/protobuf v1.3.2 // indirect 17 | github.com/google/go-cmp v0.7.0 // indirect 18 | github.com/google/gofuzz v1.2.0 // indirect 19 | github.com/json-iterator/go v1.1.12 // indirect 20 | github.com/kr/text v0.2.0 // indirect 21 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 22 | github.com/modern-go/reflect2 v1.0.2 // indirect 23 | github.com/rogpeppe/go-internal v1.13.1 // indirect 24 | github.com/stretchr/testify v1.10.0 // indirect 25 | github.com/x448/float16 v0.8.4 // indirect 26 | go.yaml.in/yaml/v3 v3.0.4 // indirect 27 | golang.org/x/net v0.43.0 // indirect 28 | golang.org/x/text v0.28.0 // indirect 29 | gopkg.in/inf.v0 v0.9.1 // indirect 30 | sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect 31 | sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect 32 | sigs.k8s.io/yaml v1.4.0 // indirect 33 | ) 34 | -------------------------------------------------------------------------------- /pkg/utils/http/error.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package httputil 16 | 17 | import ( 18 | "errors" 19 | "fmt" 20 | "net/http" 21 | ) 22 | 23 | type Error struct { 24 | Status int 25 | Message string 26 | } 27 | 28 | func (e Error) Error() string { 29 | return fmt.Sprintf("status: %d, message: %s", e.Status, e.Message) 30 | } 31 | 32 | func Errorf(status int, format string, args ...any) error { 33 | return Error{ 34 | Status: status, 35 | Message: fmt.Sprintf(format, args...), 36 | } 37 | } 38 | 39 | func IsNotFound(err error) bool { 40 | e := &Error{} 41 | if !errors.As(err, e) { 42 | return false 43 | } 44 | 45 | return e.Status == http.StatusNotFound 46 | } 47 | -------------------------------------------------------------------------------- /third_party/kubernetes/pkg/util/hash/hash.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Copied from https://github.com/kubernetes/kubernetes/blob/00236ae0d73d2455a2470469ed1005674f8ed61f/pkg/util/hash/hash.go#L29 18 | 19 | package hash 20 | 21 | import ( 22 | "fmt" 23 | "hash" 24 | 25 | "k8s.io/apimachinery/pkg/util/dump" 26 | ) 27 | 28 | // DeepHashObject writes specified object to hash using the spew library 29 | // which follows pointers and prints actual values of the nested objects 30 | // ensuring the hash does not change when a pointer changes. 31 | func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) { 32 | hasher.Reset() 33 | fmt.Fprintf(hasher, "%v", dump.ForHash(objectToWrite)) 34 | } 35 | -------------------------------------------------------------------------------- /pkg/utils/http/error_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package httputil 16 | 17 | import ( 18 | "fmt" 19 | "net/http" 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestErrorf(t *testing.T) { 26 | err := Errorf(http.StatusNotFound, "err: %v", "xxx") 27 | 28 | assert.EqualError(t, err, "status: 404, message: err: xxx") 29 | } 30 | 31 | func TestIsNotFound(t *testing.T) { 32 | err := Errorf(http.StatusNotFound, "not found") 33 | assert.True(t, IsNotFound(err)) 34 | err2 := Errorf(http.StatusBadRequest, "bad request") 35 | assert.False(t, IsNotFound(err2)) 36 | err3 := fmt.Errorf("response: %w", err) 37 | assert.True(t, IsNotFound(err3)) 38 | } 39 | -------------------------------------------------------------------------------- /pkg/controllers/pdgroup/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/pingcap/tidb-operator/v2/pkg/runtime" 21 | "github.com/pingcap/tidb-operator/v2/pkg/updater" 22 | ) 23 | 24 | func InternalServiceName(groupName string) string { 25 | return fmt.Sprintf("%s-pd", groupName) 26 | } 27 | 28 | func NotLeaderPolicy() updater.PreferPolicy[*runtime.PD] { 29 | return updater.PreferPolicyFunc[*runtime.PD](func(pds []*runtime.PD) []*runtime.PD { 30 | var notLeader []*runtime.PD 31 | for _, pd := range pds { 32 | if !pd.Status.IsLeader { 33 | notLeader = append(notLeader, pd) 34 | } 35 | } 36 | return notLeader 37 | }) 38 | } 39 | -------------------------------------------------------------------------------- /pkg/controllers/tikv/tasks/finalizer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | 20 | "github.com/pingcap/tidb-operator/v2/pkg/client" 21 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/common" 22 | ) 23 | 24 | const ( 25 | // for deleted store, we'll set grace period to the default 26 | // 30s for prestop hook and 30s for tikv 27 | defaultGracePeriod = 60 28 | ) 29 | 30 | var SubresourceLister = common.NewSubresourceLister( 31 | common.NewSubresource[corev1.PodList](client.GracePeriodSeconds(defaultGracePeriod)), 32 | common.NewSubresource[corev1.ConfigMapList](), 33 | common.NewSubresource[corev1.PersistentVolumeClaimList](), 34 | ) 35 | -------------------------------------------------------------------------------- /pkg/controllers/tsogroup/tasks/ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "context" 19 | 20 | tsom "github.com/pingcap/tidb-operator/v2/pkg/timanager/tso" 21 | "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 22 | ) 23 | 24 | type ReconcileContext struct { 25 | State 26 | } 27 | 28 | func TaskContextTSOClient(state *ReconcileContext, m tsom.TSOClientManager) task.Task { 29 | return task.NameTaskFunc("ContextTSOClient", func(_ context.Context) task.Result { 30 | if err := m.Register(state.Object()); err != nil { 31 | return task.Fail().With("cannot register tso client: %v", err) 32 | } 33 | return task.Complete().With("tso client is registered") 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /pkg/controllers/tidb/tasks/adopt.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/pingcap/tidb-operator/v2/pkg/adoption" 21 | "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 22 | ) 23 | 24 | func TaskRegisterForAdoption(state *ReconcileContext, am adoption.Manager) task.Task { 25 | return task.NameTaskFunc("RegisterForAdoption", func(ctx context.Context) task.Result { 26 | obj := state.Object() 27 | if obj == nil { 28 | key := state.Key() 29 | am.Unregister(key.Namespace, key.Name) 30 | return task.Complete().With("unregister deleted tidb") 31 | } 32 | am.Register(obj) 33 | return task.Complete().With("register tidb") 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /pkg/ticdcapi/v1/types.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package ticdcapi 16 | 17 | type CaptureStatus struct { 18 | ID string `json:"id"` 19 | Version string `json:"version"` 20 | IsOwner bool `json:"is_owner"` 21 | } 22 | 23 | type captureInfo struct { 24 | ID string `json:"id"` 25 | IsOwner bool `json:"is_owner"` 26 | AdvertiseAddr string `json:"address"` 27 | } 28 | 29 | // drainCaptureRequest is request for manual `DrainCapture` 30 | type drainCaptureRequest struct { 31 | CaptureID string `json:"capture_id"` 32 | } 33 | 34 | // drainCaptureResp is response for manual `DrainCapture` 35 | type drainCaptureResp struct { 36 | CurrentTableCount int `json:"current_table_count"` 37 | } 38 | -------------------------------------------------------------------------------- /pkg/compatibility/feat.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package compatibility 16 | 17 | // All these are features supported by different TiDB versions 18 | // NOTE: Do not add constraints with prerelease version 19 | // NOTE: MUST add key PRs in comments 20 | var ( 21 | // PDMS is supported 22 | // This feature is enabled after the tso primary transferring is supported 23 | // See https://github.com/tikv/pd/pull/8157 24 | PDMS = MustNewConstraints(">= v8.3.0") 25 | 26 | // PD ready api 27 | // See https://github.com/tikv/pd/pull/8749 28 | PDReadyAPI = MustNewConstraints(">= v9.0.0 || ^v8.5.2") 29 | 30 | // TiKV ready api 31 | // See https://github.com/tikv/tikv/pull/18237 32 | TiKVReadyAPI = MustNewConstraints(">= v9.0.0") 33 | ) 34 | -------------------------------------------------------------------------------- /pkg/controllers/br/backup/tasks/backup_manager.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "context" 19 | 20 | "k8s.io/client-go/tools/record" 21 | 22 | "github.com/pingcap/tidb-operator/v2/pkg/client" 23 | "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 24 | ) 25 | 26 | func TaskBackupManager(state *ReconcileContext, c client.Client, recorder record.EventRecorder) task.Task { 27 | return task.NameTaskFunc("BackupManager", func(ctx context.Context) task.Result { 28 | err := state.BackupManager.Sync(ctx, state.Backup()) 29 | if err != nil { 30 | return task.Fail().With("sync backup manager failed: %s", err) 31 | } 32 | 33 | return task.Complete().With("backup manager synced") 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /pkg/controllers/tso/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | 20 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 21 | metav1alpha1 "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 22 | ) 23 | 24 | // VolumeName returns the real spec.volumes[*].name of pod 25 | // TODO(liubo02): extract to namer pkg 26 | func VolumeName(volName string) string { 27 | return metav1alpha1.VolNamePrefix + volName 28 | } 29 | 30 | func VolumeMount(name string, mount *v1alpha1.VolumeMount) *corev1.VolumeMount { 31 | vm := &corev1.VolumeMount{ 32 | Name: name, 33 | MountPath: mount.MountPath, 34 | SubPath: mount.SubPath, 35 | } 36 | 37 | return vm 38 | } 39 | -------------------------------------------------------------------------------- /pkg/metrics/metrics.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package metrics 16 | 17 | import ( 18 | "github.com/prometheus/client_golang/prometheus" 19 | "sigs.k8s.io/controller-runtime/pkg/metrics" 20 | ) 21 | 22 | var ( 23 | 24 | // ControllerPanic is a counter to record the number of panics in the controller. 25 | ControllerPanic = prometheus.NewCounterVec( 26 | prometheus.CounterOpts{ 27 | Namespace: "tidb_operator", 28 | Subsystem: "controller", 29 | Name: "panic_total", 30 | Help: "The total number of panics in the controller", 31 | }, []string{}, 32 | ) 33 | ) 34 | 35 | func init() { 36 | // Register custom metrics with the global prometheus registry 37 | metrics.Registry.MustRegister(ControllerPanic) 38 | } 39 | -------------------------------------------------------------------------------- /pkg/controllers/scheduler/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | 20 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 21 | metav1alpha1 "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 22 | ) 23 | 24 | // VolumeName returns the real spec.volumes[*].name of pod 25 | // TODO(liubo02): extract to namer pkg 26 | func VolumeName(volName string) string { 27 | return metav1alpha1.VolNamePrefix + volName 28 | } 29 | 30 | func VolumeMount(name string, mount *v1alpha1.VolumeMount) *corev1.VolumeMount { 31 | vm := &corev1.VolumeMount{ 32 | Name: name, 33 | MountPath: mount.MountPath, 34 | SubPath: mount.SubPath, 35 | } 36 | 37 | return vm 38 | } 39 | -------------------------------------------------------------------------------- /pkg/controllers/scheduling/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | 20 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 21 | metav1alpha1 "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 22 | ) 23 | 24 | // VolumeName returns the real spec.volumes[*].name of pod 25 | // TODO(liubo02): extract to namer pkg 26 | func VolumeName(volName string) string { 27 | return metav1alpha1.VolNamePrefix + volName 28 | } 29 | 30 | func VolumeMount(name string, mount *v1alpha1.VolumeMount) *corev1.VolumeMount { 31 | vm := &corev1.VolumeMount{ 32 | Name: name, 33 | MountPath: mount.MountPath, 34 | SubPath: mount.SubPath, 35 | } 36 | 37 | return vm 38 | } 39 | -------------------------------------------------------------------------------- /pkg/controllers/tikvworker/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | 20 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 21 | metav1alpha1 "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 22 | ) 23 | 24 | // VolumeName returns the real spec.volumes[*].name of pod 25 | // TODO(liubo02): extract to namer pkg 26 | func VolumeName(volName string) string { 27 | return metav1alpha1.VolNamePrefix + volName 28 | } 29 | 30 | func VolumeMount(name string, mount *v1alpha1.VolumeMount) *corev1.VolumeMount { 31 | vm := &corev1.VolumeMount{ 32 | Name: name, 33 | MountPath: mount.MountPath, 34 | SubPath: mount.SubPath, 35 | } 36 | 37 | return vm 38 | } 39 | -------------------------------------------------------------------------------- /pkg/controllers/br/restore/tasks/restore_manager.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "context" 19 | 20 | "k8s.io/client-go/tools/record" 21 | 22 | "github.com/pingcap/tidb-operator/v2/pkg/client" 23 | "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 24 | ) 25 | 26 | func TaskRestoreManager(state *ReconcileContext, c client.Client, recorder record.EventRecorder) task.Task { 27 | return task.NameTaskFunc("RestoreManager", func(ctx context.Context) task.Result { 28 | err := state.RestoreManager.Sync(ctx, state.Restore()) 29 | if err != nil { 30 | return task.Fail().With("sync restore manager failed: %s", err) 31 | } 32 | 33 | return task.Complete().With("restore manager synced") 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /pkg/controllers/br/tibrgc/tasks/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import corev1 "k8s.io/api/core/v1" 18 | 19 | const ( 20 | ClusterNameField = "spec.cluster.name" 21 | 22 | ComponentName = "tibrgc" 23 | SecretAccessMode = int32(420) 24 | TLSVolumeName = "tibrgc-tls" 25 | TLSMountPath = "/var/lib/tibrgc-tls" 26 | 27 | T2DefaultBackoffLimit = int32(16) 28 | T3DefaultBackoffLimit = int32(32) 29 | ) 30 | 31 | var ( 32 | TLSCmdArgs = []string{ 33 | "--cacert", 34 | TLSMountPath + "/ca.crt", 35 | "--cert", 36 | TLSMountPath + "/tls.crt", 37 | "--key", 38 | TLSMountPath + "/tls.key", 39 | } 40 | tlsVolumeMount = corev1.VolumeMount{ 41 | Name: TLSVolumeName, MountPath: TLSMountPath, 42 | } 43 | ) 44 | -------------------------------------------------------------------------------- /pkg/utils/time/clock.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package time 16 | 17 | import "time" 18 | 19 | type Clock interface { 20 | Now() time.Time 21 | Since(time.Time) time.Duration 22 | } 23 | 24 | var ( 25 | _ Clock = &RealClock{} 26 | _ Clock = &FakeClock{} 27 | ) 28 | 29 | type RealClock struct{} 30 | 31 | func (RealClock) Since(t time.Time) time.Duration { 32 | return time.Since(t) 33 | } 34 | 35 | func (RealClock) Now() time.Time { 36 | return time.Now() 37 | } 38 | 39 | type FakeClock struct { 40 | NowFunc func() time.Time 41 | SinceFunc func(time.Time) time.Duration 42 | } 43 | 44 | func (f FakeClock) Now() time.Time { 45 | return f.NowFunc() 46 | } 47 | 48 | func (f FakeClock) Since(t time.Time) time.Duration { 49 | return f.SinceFunc(t) 50 | } 51 | -------------------------------------------------------------------------------- /pkg/pdapi/pd/duration_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pd 16 | 17 | import ( 18 | "testing" 19 | "time" 20 | 21 | "github.com/stretchr/testify/assert" 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestDuration(t *testing.T) { 26 | du := NewDuration(72*time.Hour + 3*time.Minute + 500*time.Millisecond) 27 | data, err := du.MarshalJSON() 28 | require.NoError(t, err) 29 | assert.Equal(t, `"72h3m0.5s"`, string(data)) 30 | data2, err := du.MarshalText() 31 | require.NoError(t, err) 32 | assert.Equal(t, "72h3m0.5s", string(data2)) 33 | 34 | var du2 Duration 35 | err = du2.UnmarshalJSON(data) 36 | require.NoError(t, err) 37 | assert.Equal(t, du, du2) 38 | 39 | err = du2.UnmarshalText(data2) 40 | require.NoError(t, err) 41 | assert.Equal(t, du, du2) 42 | } 43 | -------------------------------------------------------------------------------- /tests/e2e/framework/action/update.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package action 16 | 17 | import ( 18 | "context" 19 | "fmt" 20 | 21 | "github.com/onsi/ginkgo/v2" 22 | "github.com/onsi/gomega" 23 | 24 | "github.com/pingcap/tidb-operator/v2/pkg/client" 25 | "github.com/pingcap/tidb-operator/v2/tests/e2e/data" 26 | "github.com/pingcap/tidb-operator/v2/tests/e2e/framework" 27 | ) 28 | 29 | func MustUpdateCluster( 30 | ctx context.Context, 31 | f *framework.Framework, 32 | patches ...data.ClusterPatch, 33 | ) { 34 | ginkgo.By(fmt.Sprintf("update cluster %v", client.ObjectKeyFromObject(f.Cluster))) 35 | 36 | mp := client.MergeFrom(f.Cluster.DeepCopy()) 37 | for _, p := range patches { 38 | p(f.Cluster) 39 | } 40 | err := f.Client.Patch(ctx, f.Cluster, mp) 41 | gomega.ExpectWithOffset(1, err).To(gomega.Succeed()) 42 | } 43 | -------------------------------------------------------------------------------- /pkg/adoption/instance.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package adoption 16 | 17 | import ( 18 | "sigs.k8s.io/controller-runtime/pkg/client" 19 | 20 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 21 | ) 22 | 23 | type instance struct { 24 | hash string 25 | instance *v1alpha1.TiDB 26 | owner *v1alpha1.TiDBGroup 27 | } 28 | 29 | func (in *instance) isLocked() bool { 30 | return in.owner != nil 31 | } 32 | 33 | func (in *instance) lock(owner *v1alpha1.TiDBGroup) { 34 | in.owner = owner 35 | } 36 | 37 | func (in *instance) unlock() { 38 | in.owner = nil 39 | } 40 | 41 | func (in *instance) ownerKey() string { 42 | if in.owner == nil { 43 | return "" 44 | } 45 | return client.ObjectKeyFromObject(in.owner).String() 46 | } 47 | 48 | func (in *instance) key() string { 49 | return client.ObjectKeyFromObject(in.instance).String() 50 | } 51 | -------------------------------------------------------------------------------- /pkg/tiflashapi/v1/client_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tiflashapi 16 | 17 | import ( 18 | "context" 19 | "net/http" 20 | "net/http/httptest" 21 | "testing" 22 | "time" 23 | 24 | "github.com/stretchr/testify/assert" 25 | "github.com/stretchr/testify/require" 26 | ) 27 | 28 | func TestTiFlash_GetStoreStatus(t *testing.T) { 29 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 30 | assert.Equal(t, "/tiflash/store-status", r.URL.Path) 31 | assert.Equal(t, http.MethodGet, r.Method) 32 | _, err := w.Write([]byte("Running")) 33 | assert.NoError(t, err) 34 | })) 35 | defer server.Close() 36 | 37 | client := NewTiFlashClient(server.URL, 5*time.Second, nil) 38 | status, err := client.GetStoreStatus(context.Background()) 39 | require.NoError(t, err) 40 | assert.Equal(t, Running, status) 41 | } 42 | -------------------------------------------------------------------------------- /pkg/utils/string/string_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package stringutil 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestRemoveHTTPPrefix(t *testing.T) { 22 | tests := []struct { 23 | name string 24 | input string 25 | want string 26 | }{ 27 | {"http prefix", "http://example.com", "example.com"}, 28 | {"https prefix", "https://example.com", "example.com"}, 29 | {"no prefix", "example.com", "example.com"}, 30 | {"http in middle", "foohttp://bar", "foohttp://bar"}, 31 | {"https in middle", "foohttps://bar", "foohttps://bar"}, 32 | {"empty string", "", ""}, 33 | } 34 | 35 | for _, tt := range tests { 36 | t.Run(tt.name, func(t *testing.T) { 37 | got := RemoveHTTPPrefix(tt.input) 38 | if got != tt.want { 39 | t.Errorf("RemoveHTTPPrefix(%q) = %q, want %q", tt.input, got, tt.want) 40 | } 41 | }) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pkg/volumes/cloud/utils.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cloud 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | "k8s.io/apimachinery/pkg/api/resource" 20 | ) 21 | 22 | func NewTestPVC(size string) *corev1.PersistentVolumeClaim { 23 | return &corev1.PersistentVolumeClaim{ 24 | Spec: corev1.PersistentVolumeClaimSpec{ 25 | Resources: corev1.VolumeResourceRequirements{ 26 | Requests: corev1.ResourceList{ 27 | corev1.ResourceStorage: resource.MustParse(size), 28 | }, 29 | }, 30 | }, 31 | } 32 | } 33 | 34 | func NewTestPV(volID string) *corev1.PersistentVolume { 35 | return &corev1.PersistentVolume{ 36 | Spec: corev1.PersistentVolumeSpec{ 37 | PersistentVolumeSource: corev1.PersistentVolumeSource{ 38 | CSI: &corev1.CSIPersistentVolumeSource{ 39 | VolumeHandle: volID, 40 | }, 41 | }, 42 | }, 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /pkg/utils/k8s/event_recorder.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package k8s 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | "k8s.io/client-go/kubernetes" 20 | eventv1 "k8s.io/client-go/kubernetes/typed/core/v1" 21 | "k8s.io/client-go/tools/record" 22 | "k8s.io/klog/v2" 23 | 24 | "github.com/pingcap/tidb-operator/v2/pkg/scheme" 25 | ) 26 | 27 | // NewEventRecorder return the specify source's recoder 28 | func NewEventRecorder(kubeCli kubernetes.Interface, source string) record.EventRecorder { 29 | eventBroadcaster := record.NewBroadcaster() 30 | eventBroadcaster.StartLogging(klog.Infof) 31 | eventBroadcaster.StartRecordingToSink(&eventv1.EventSinkImpl{ 32 | Interface: eventv1.New(kubeCli.CoreV1().RESTClient()).Events("")}) 33 | recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: source}) 34 | return recorder 35 | } 36 | -------------------------------------------------------------------------------- /pkg/volumes/types_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package volumes 16 | 17 | import ( 18 | "errors" 19 | "testing" 20 | ) 21 | 22 | func TestWaitError(t *testing.T) { 23 | tests := []struct { 24 | name string 25 | err error 26 | expected bool 27 | }{ 28 | { 29 | name: "WaitError", 30 | err: &WaitError{Message: "test wait error"}, 31 | expected: true, 32 | }, 33 | { 34 | name: "regular error", 35 | err: errors.New("regular error"), 36 | expected: false, 37 | }, 38 | { 39 | name: "nil error", 40 | err: nil, 41 | expected: false, 42 | }, 43 | } 44 | 45 | for _, tt := range tests { 46 | t.Run(tt.name, func(t *testing.T) { 47 | if got := IsWaitError(tt.err); got != tt.expected { 48 | t.Errorf("IsWaitError() = %v, want %v", got, tt.expected) 49 | } 50 | }) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/e2e/data/ns.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package data 16 | 17 | import ( 18 | "math/rand" 19 | 20 | v1 "k8s.io/api/core/v1" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | ) 23 | 24 | const ( 25 | nsBaseName = "e2e-tidb-operator" 26 | ) 27 | 28 | // NewNamespace returns a random namespace object for testing. 29 | func NewNamespace() *v1.Namespace { 30 | return &v1.Namespace{ 31 | ObjectMeta: metav1.ObjectMeta{ 32 | Name: nsBaseName + "-" + randString(5), //nolint:mnd // refactor to a constant if needed 33 | }, 34 | } 35 | } 36 | 37 | func randString(n int) string { 38 | const letterBytes = "abcdefghijklmnopqrstuvwxyz" 39 | b := make([]byte, n) 40 | for i := range b { 41 | //nolint:gosec // no need to use cryptographically secure random number generator 42 | b[i] = letterBytes[rand.Intn(len(letterBytes))] 43 | } 44 | return string(b) 45 | } 46 | -------------------------------------------------------------------------------- /tests/e2e/utils/data/namespace.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package data 16 | 17 | import ( 18 | "math/rand" 19 | 20 | v1 "k8s.io/api/core/v1" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | ) 23 | 24 | const ( 25 | nsBaseName = "e2e-tidb-operator" 26 | ) 27 | 28 | // NewNamespace returns a random namespace object for testing. 29 | func NewNamespace() *v1.Namespace { 30 | return &v1.Namespace{ 31 | ObjectMeta: metav1.ObjectMeta{ 32 | Name: nsBaseName + "-" + randString(5), //nolint:mnd // refactor to a constant if needed 33 | }, 34 | } 35 | } 36 | 37 | func randString(n int) string { 38 | const letterBytes = "abcdefghijklmnopqrstuvwxyz" 39 | b := make([]byte, n) 40 | for i := range b { 41 | //nolint:gosec // no need to use cryptographically secure random number generator 42 | b[i] = letterBytes[rand.Intn(len(letterBytes))] 43 | } 44 | return string(b) 45 | } 46 | -------------------------------------------------------------------------------- /pkg/controllers/br/restore/builder.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package restore 16 | 17 | import ( 18 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/br/restore/tasks" 19 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/common" 20 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 21 | "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 22 | ) 23 | 24 | func (r *Reconciler) NewRunner(state *tasks.ReconcileContext, reporter task.TaskReporter) task.TaskRunner { 25 | runner := task.NewTaskRunner(reporter, 26 | // get cluster 27 | common.TaskContextCluster[scope.Restore](state, r.Client), 28 | // if it's paused just return 29 | task.IfBreak(common.CondClusterIsPaused(state)), 30 | task.IfBreak( 31 | common.CondClusterIsSuspending(state), 32 | ), 33 | 34 | tasks.TaskRestoreManager(state, r.Client, r.EventRecorder), 35 | ) 36 | 37 | return runner 38 | } 39 | -------------------------------------------------------------------------------- /tests/e2e/br/utils/s3/interface.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package s3 16 | 17 | import ( 18 | "context" 19 | "fmt" 20 | 21 | "github.com/pingcap/tidb-operator/api/v2/br/v1alpha1" 22 | "github.com/pingcap/tidb-operator/v2/pkg/client" 23 | "github.com/pingcap/tidb-operator/v2/tests/e2e/utils/k8s" 24 | ) 25 | 26 | type Interface interface { 27 | Init(ctx context.Context, ns, accessKey, secretKey string) error 28 | IsDataCleaned(ctx context.Context, ns, prefix string) (bool, error) 29 | Clean(ctx context.Context, ns string) error 30 | 31 | Config(ns, prefix string) *v1alpha1.S3StorageProvider 32 | Bucket() string 33 | } 34 | 35 | func New(provider string, c client.Client, fw k8s.PortForwarder) (Interface, error) { 36 | switch provider { 37 | case "kind": 38 | return NewMinio(c, fw), nil 39 | } 40 | return nil, fmt.Errorf("no storage supported for this provider: %s", provider) 41 | } 42 | -------------------------------------------------------------------------------- /pkg/tidbapi/v1/types.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tidbapi 16 | 17 | // ServerInfo is the information of a TiDB server. 18 | // ref https://github.com/pingcap/tidb/blob/v8.1.0/pkg/server/handler/tikvhandler/tikv_handler.go#L1696 19 | type ServerInfo struct { 20 | IsOwner bool `json:"is_owner"` 21 | } 22 | 23 | type ActivateRequest struct { 24 | KeyspaceName string `json:"keyspace_name"` 25 | MaxIdleSeconds uint `json:"max_idle_seconds"` 26 | 27 | // analyze table 28 | RunAutoAnalyze bool `json:"run_auto_analyze"` 29 | 30 | // DDL 31 | TiDBEnableDDL bool `json:"tidb_enable_ddl"` 32 | } 33 | 34 | type PoolStatus struct { 35 | State PoolState `json:"state"` 36 | // unused 37 | // KeyspaceName string `json:"keyspace_name"` 38 | } 39 | 40 | type PoolState string 41 | 42 | const ( 43 | PoolStateActivated PoolState = "activated" 44 | PoolStateStandBy PoolState = "standby" 45 | ) 46 | -------------------------------------------------------------------------------- /tests/e2e/example/example.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package example 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/onsi/ginkgo/v2" 21 | 22 | "github.com/pingcap/tidb-operator/v2/tests/e2e/framework" 23 | "github.com/pingcap/tidb-operator/v2/tests/e2e/label" 24 | "github.com/pingcap/tidb-operator/v2/tests/e2e/utils/yaml" 25 | ) 26 | 27 | var _ = ginkgo.Describe("Example", label.KindExample, label.P0, func() { 28 | f := framework.New() 29 | f.Setup(framework.WithSkipClusterCreation()) 30 | 31 | ginkgo.DescribeTable("Example", 32 | func(ctx context.Context, dir string, cn string) { 33 | // NOTE(liubo02): ignore resources config to avoid resource limit in local 34 | f.Must(yaml.ApplyDir(ctx, f.Client, dir, yaml.Namespace(f.Namespace.Name), yaml.IgnoreResources{})) 35 | f.WaitForAllReady(ctx, cn) 36 | }, 37 | ginkgo.Entry("basic", "example/data/basic", "basic"), 38 | ) 39 | }) 40 | -------------------------------------------------------------------------------- /tools/mockgen/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 4 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 5 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 8 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 9 | go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= 10 | go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= 11 | golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= 12 | golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= 13 | golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= 14 | golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 15 | golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= 16 | golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= 17 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 18 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 19 | -------------------------------------------------------------------------------- /pkg/compatibility/semver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package compatibility 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/Masterminds/semver/v3" 21 | ) 22 | 23 | func Check(v *semver.Version, constraints ...Constraints) bool { 24 | for _, c := range constraints { 25 | if !c.check(v) { 26 | return false 27 | } 28 | } 29 | 30 | return true 31 | } 32 | 33 | type Constraints interface { 34 | check(v *semver.Version) bool 35 | } 36 | 37 | type constraints struct { 38 | *semver.Constraints 39 | } 40 | 41 | func (c *constraints) check(v *semver.Version) bool { 42 | return c.Check(v) 43 | } 44 | 45 | func MustNewConstraints(expr string) Constraints { 46 | v, err := semver.NewConstraint(expr) 47 | if err != nil { 48 | panic(fmt.Errorf("cannot parse constraints %v: %w", expr, err)) 49 | } 50 | 51 | v.IncludePrerelease = true 52 | 53 | return &constraints{ 54 | Constraints: v, 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /pkg/controllers/pd/tasks/finalizer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 21 | ) 22 | 23 | func TaskDeleteMember(state *ReconcileContext) task.Task { 24 | return task.NameTaskFunc("DeleteMember", func(ctx context.Context) task.Result { 25 | cluster := state.Cluster() 26 | if state.PDClient == nil { 27 | if !cluster.GetDeletionTimestamp().IsZero() { 28 | return task.Complete().With("cluster is deleting, pd client has been deregistered") 29 | } 30 | return task.Fail().With("pd client is not registered") 31 | } 32 | // TODO: check whether quorum will be lost? 33 | if err := state.PDClient.Underlay().DeleteMember(ctx, state.PD().Name); err != nil { 34 | return task.Fail().With("cannot delete member: %v", err) 35 | } 36 | 37 | return task.Complete().With("member is deleted") 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /pkg/pdapi/pd/size_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pd 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | "github.com/stretchr/testify/require" 22 | ) 23 | 24 | func TestParseMBFromText(t *testing.T) { 25 | value := uint64(512) 26 | result := ParseMBFromText("1.0 MiB", value) 27 | assert.Equal(t, uint64(1), result) 28 | 29 | result = ParseMBFromText("invalid", value) 30 | assert.Equal(t, value, result) 31 | } 32 | 33 | func TestByteSize(t *testing.T) { 34 | b := ByteSize(17 * 1024 * 1024) // 17 MiB 35 | data, err := b.MarshalJSON() 36 | require.NoError(t, err) 37 | assert.Equal(t, `"17MiB"`, string(data)) 38 | 39 | var b2 ByteSize 40 | err = b2.UnmarshalJSON(data) 41 | require.NoError(t, err) 42 | assert.Equal(t, b, b2) 43 | 44 | data2 := []byte("17MiB") 45 | err = b2.UnmarshalText(data2) 46 | require.NoError(t, err) 47 | assert.Equal(t, b, b2) 48 | } 49 | -------------------------------------------------------------------------------- /pkg/controllers/br/tibr/tasks/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import corev1 "k8s.io/api/core/v1" 18 | 19 | const ( 20 | ComponentName = "tibr" 21 | ConfigFileName = "tibr-config.yaml" 22 | StatefulSetReplica = int32(1) 23 | APIServerPort = 19500 24 | SecretAccessMode = int32(420) 25 | ConfigVolumeName = "config-volume" 26 | TLSVolumeName = "tibr-tls" 27 | TLSMountPath = "/var/lib/tibr-tls" 28 | ConfigMountPath = "/etc/config" 29 | ) 30 | 31 | var ( 32 | TLSCmdArgs = []string{ 33 | "--cacert", 34 | TLSMountPath + "/ca.crt", 35 | "--cert", 36 | TLSMountPath + "/tls.crt", 37 | "--key", 38 | TLSMountPath + "/tls.key", 39 | } 40 | configVolumeMount = corev1.VolumeMount{ 41 | Name: ConfigVolumeName, MountPath: ConfigMountPath, 42 | } 43 | tlsVolumeMount = corev1.VolumeMount{ 44 | Name: TLSVolumeName, MountPath: TLSMountPath, 45 | } 46 | ) 47 | -------------------------------------------------------------------------------- /tools/deepcopy-gen/go.sum: -------------------------------------------------------------------------------- 1 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 2 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 3 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 4 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 5 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 6 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 7 | golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= 8 | golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 9 | golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= 10 | golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 11 | golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= 12 | golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= 13 | k8s.io/code-generator v0.32.11 h1:1IlZUPWcwUEesHrSPMIrd1LuwGYAhimWo7SrNulTLM0= 14 | k8s.io/code-generator v0.32.11/go.mod h1:8kN1gaDd9Vi2ulCHysz3xukpp2LpawIZuZuo176Qx44= 15 | k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 h1:si3PfKm8dDYxgfbeA6orqrtLkvvIeH8UqffFJDl0bz4= 16 | k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= 17 | k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= 18 | k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= 19 | -------------------------------------------------------------------------------- /tools/register-gen/go.sum: -------------------------------------------------------------------------------- 1 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 2 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 3 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 4 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 5 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 6 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 7 | golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= 8 | golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 9 | golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= 10 | golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 11 | golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= 12 | golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= 13 | k8s.io/code-generator v0.32.11 h1:1IlZUPWcwUEesHrSPMIrd1LuwGYAhimWo7SrNulTLM0= 14 | k8s.io/code-generator v0.32.11/go.mod h1:8kN1gaDd9Vi2ulCHysz3xukpp2LpawIZuZuo176Qx44= 15 | k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 h1:si3PfKm8dDYxgfbeA6orqrtLkvvIeH8UqffFJDl0bz4= 16 | k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= 17 | k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= 18 | k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= 19 | -------------------------------------------------------------------------------- /tests/e2e/data/ticdc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package data 16 | 17 | import ( 18 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 19 | "k8s.io/utils/ptr" 20 | 21 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 22 | ) 23 | 24 | func NewTiCDCGroup(ns string, patches ...GroupPatch[*v1alpha1.TiCDCGroup]) *v1alpha1.TiCDCGroup { 25 | cg := &v1alpha1.TiCDCGroup{ 26 | ObjectMeta: metav1.ObjectMeta{ 27 | Namespace: ns, 28 | Name: defaultTiCDCGroupName, 29 | }, 30 | Spec: v1alpha1.TiCDCGroupSpec{ 31 | Cluster: v1alpha1.ClusterReference{ 32 | Name: defaultClusterName, 33 | }, 34 | Replicas: ptr.To[int32](1), 35 | Template: v1alpha1.TiCDCTemplate{ 36 | Spec: v1alpha1.TiCDCTemplateSpec{ 37 | Version: defaultVersion, 38 | Image: ptr.To(defaultImageRegistry + "ticdc"), 39 | }, 40 | }, 41 | }, 42 | } 43 | for _, p := range patches { 44 | p.Patch(cg) 45 | } 46 | 47 | return cg 48 | } 49 | -------------------------------------------------------------------------------- /pkg/controllers/br/backup/builder.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package backup 16 | 17 | import ( 18 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/br/backup/tasks" 19 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/common" 20 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 21 | "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 22 | ) 23 | 24 | func (r *Reconciler) NewRunner(state *tasks.ReconcileContext, reporter task.TaskReporter) task.TaskRunner { 25 | runner := task.NewTaskRunner(reporter, 26 | // get cluster 27 | common.TaskContextCluster[scope.Backup](state, r.Client), 28 | // if it's paused just return 29 | task.IfBreak(common.CondClusterIsPaused(state)), 30 | task.IfBreak( 31 | common.CondClusterIsSuspending(state), 32 | ), 33 | 34 | tasks.TaskBackupCleaner(state, r.Client, r.EventRecorder), 35 | tasks.TaskBackupManager(state, r.Client, r.EventRecorder), 36 | ) 37 | 38 | return runner 39 | } 40 | -------------------------------------------------------------------------------- /cmd/tidb-backup-manager/app/cmd/cmd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cmd 16 | 17 | import ( 18 | "github.com/spf13/cobra" 19 | ) 20 | 21 | var kubecfg string 22 | 23 | //nolint:gocritic 24 | func NewBackupMgrCommand() *cobra.Command { 25 | cmds := &cobra.Command{ 26 | Use: "tidb-backup-manager", 27 | Short: "Helper for backup manage", 28 | Long: "Dump tidb cluster data, as well as backup and restore tidb cluster data", 29 | Run: runHelp, 30 | } 31 | 32 | cmds.PersistentFlags().StringVarP(&kubecfg, "kubeconfig", "k", "", "Path to kubeconfig file, omit this if run in cluster.") 33 | 34 | cmds.AddCommand(NewBackupCommand()) 35 | // cmds.AddCommand(NewExportCommand()) 36 | cmds.AddCommand(NewRestoreCommand()) 37 | // cmds.AddCommand(NewImportCommand()) 38 | cmds.AddCommand(NewCleanCommand()) 39 | // cmds.AddCommand(NewCompactCommand()) 40 | return cmds 41 | } 42 | 43 | func runHelp(cmd *cobra.Command, _ []string) { 44 | _ = cmd.Help() 45 | } 46 | -------------------------------------------------------------------------------- /pkg/adoption/groups.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package adoption 16 | 17 | import ( 18 | "k8s.io/apimachinery/pkg/util/sets" 19 | ) 20 | 21 | type groups struct { 22 | m map[string]sets.Set[string] 23 | } 24 | 25 | func newGroups() *groups { 26 | return &groups{ 27 | m: make(map[string]sets.Set[string]), 28 | } 29 | } 30 | 31 | func (g *groups) add(groupKey, name string) { 32 | if groupKey == "" { 33 | return 34 | } 35 | s, ok := g.m[groupKey] 36 | if !ok { 37 | s = sets.New[string]() 38 | } 39 | s.Insert(name) 40 | g.m[groupKey] = s 41 | } 42 | 43 | func (g *groups) del(groupKey, name string) { 44 | if groupKey == "" { 45 | return 46 | } 47 | s, ok := g.m[groupKey] 48 | if !ok { 49 | return 50 | } 51 | s.Delete(name) 52 | } 53 | 54 | func (g *groups) list(groupKey string) []string { 55 | if groupKey == "" { 56 | return nil 57 | } 58 | s, ok := g.m[groupKey] 59 | if !ok { 60 | return nil 61 | } 62 | return sets.List(s) 63 | } 64 | -------------------------------------------------------------------------------- /pkg/controllers/br/backup/tasks/backup_cleaner.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "context" 19 | 20 | "k8s.io/client-go/tools/record" 21 | 22 | "github.com/pingcap/tidb-operator/v2/pkg/client" 23 | "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 24 | ) 25 | 26 | func TaskBackupCleaner(state *ReconcileContext, c client.Client, recorder record.EventRecorder) task.Task { 27 | return task.NameTaskFunc("BackupCleaner", func(ctx context.Context) task.Result { 28 | // because a finalizer is installed on the backup on creation, when backup is deleted, 29 | // backup.DeletionTimestamp will be set, controller will be informed with an onUpdate event, 30 | // this is the moment that we can do clean up work. 31 | if err := state.BackupCleaner.Clean(ctx, state.Backup()); err != nil { 32 | return task.Fail().With("clean backup failed: %s", err) 33 | } 34 | 35 | return task.Complete().With("backup cleaned") 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /pkg/utils/hasher/hasher_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package hasher 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | 23 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 24 | ) 25 | 26 | func TestHash(t *testing.T) { 27 | cases := []struct { 28 | desc string 29 | obj any 30 | expected string 31 | }{ 32 | { 33 | desc: "empty", 34 | obj: nil, 35 | expected: "99c9b8c64", 36 | }, 37 | { 38 | desc: "obj", 39 | obj: &v1alpha1.TiDBGroup{ 40 | ObjectMeta: metav1.ObjectMeta{ 41 | Name: "xxx", 42 | }, 43 | }, 44 | // not important, feel free to change if tidb group is changed 45 | expected: "58c864c88", 46 | }, 47 | } 48 | 49 | for i := range cases { 50 | c := &cases[i] 51 | t.Run(c.desc, func(tt *testing.T) { 52 | h := Hash(c.obj) 53 | assert.Equal(tt, c.expected, h) 54 | }) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /pkg/controllers/tiflash/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | 20 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 21 | meta "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 22 | ) 23 | 24 | func ConfigMapName(podName string) string { 25 | return podName 26 | } 27 | 28 | // VolumeName returns the real spec.volumes[*].name of pod 29 | // TODO(liubo02): extract to namer pkg 30 | func VolumeName(volName string) string { 31 | return meta.VolNamePrefix + volName 32 | } 33 | 34 | func VolumeMount(name string, mount *v1alpha1.VolumeMount) *corev1.VolumeMount { 35 | vm := &corev1.VolumeMount{ 36 | Name: name, 37 | MountPath: mount.MountPath, 38 | SubPath: mount.SubPath, 39 | } 40 | if mount.Type == v1alpha1.VolumeMountTypeTiFlashData { 41 | if vm.MountPath == "" { 42 | vm.MountPath = v1alpha1.VolumeMountTiFlashDataDefaultPath 43 | } 44 | } 45 | 46 | return vm 47 | } 48 | -------------------------------------------------------------------------------- /pkg/apiutil/core/v1alpha1/ticdc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package coreutil 16 | 17 | import ( 18 | "fmt" 19 | 20 | corev1 "k8s.io/api/core/v1" 21 | 22 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 23 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 24 | ) 25 | 26 | func TiCDCGroupPort(cdcg *v1alpha1.TiCDCGroup) int32 { 27 | if cdcg.Spec.Template.Spec.Server.Ports.Port != nil { 28 | return cdcg.Spec.Template.Spec.Server.Ports.Port.Port 29 | } 30 | return v1alpha1.DefaultTiCDCPort 31 | } 32 | 33 | func TiCDCPort(cdc *v1alpha1.TiCDC) int32 { 34 | if cdc.Spec.Server.Ports.Port != nil { 35 | return cdc.Spec.Server.Ports.Port.Port 36 | } 37 | return v1alpha1.DefaultTiCDCPort 38 | } 39 | 40 | func TiCDCAdvertiseURL(ticdc *v1alpha1.TiCDC) string { 41 | ns := ticdc.Namespace 42 | if ns == "" { 43 | ns = corev1.NamespaceDefault 44 | } 45 | return fmt.Sprintf("%s.%s.%s:%d", PodName[scope.TiCDC](ticdc), ticdc.Spec.Subdomain, ns, TiCDCPort(ticdc)) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/features/features.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package features 16 | 17 | import ( 18 | "k8s.io/apimachinery/pkg/util/sets" 19 | 20 | meta "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 21 | coreutil "github.com/pingcap/tidb-operator/v2/pkg/apiutil/core/v1alpha1" 22 | "github.com/pingcap/tidb-operator/v2/pkg/client" 23 | "github.com/pingcap/tidb-operator/v2/pkg/runtime" 24 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 25 | ) 26 | 27 | type Gates interface { 28 | Enabled(feat meta.Feature) bool 29 | } 30 | 31 | type gates struct { 32 | s sets.Set[meta.Feature] 33 | } 34 | 35 | func (g *gates) Enabled(feat meta.Feature) bool { 36 | return g.s.Has(feat) 37 | } 38 | 39 | func New[ 40 | S scope.Object[F, T], 41 | F client.Object, 42 | T runtime.Object, 43 | ](obj F) Gates { 44 | return NewFromFeatures(coreutil.Features[S](obj)) 45 | } 46 | 47 | func NewFromFeatures(fs []meta.Feature) Gates { 48 | return &gates{ 49 | s: sets.New(fs...), 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/e2e/tikv/topology.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tikv 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/onsi/ginkgo/v2" 21 | 22 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 23 | "github.com/pingcap/tidb-operator/v2/tests/e2e/data" 24 | "github.com/pingcap/tidb-operator/v2/tests/e2e/framework" 25 | "github.com/pingcap/tidb-operator/v2/tests/e2e/label" 26 | ) 27 | 28 | var _ = ginkgo.Describe("Topology", label.TiKV, label.MultipleAZ, label.P0, func() { 29 | f := framework.New() 30 | f.Setup() 31 | 32 | ginkgo.It("Create tikv evenly spread in multiple azs", func(ctx context.Context) { 33 | ginkgo.By("Creating cluster") 34 | pdg := f.MustCreatePD(ctx) 35 | kvg := f.MustCreateTiKV(ctx, 36 | data.WithReplicas[scope.TiKVGroup](6), 37 | data.WithTiKVEvenlySpreadPolicy(), 38 | ) 39 | 40 | f.WaitForPDGroupReady(ctx, pdg) 41 | f.WaitForTiKVGroupReady(ctx, kvg) 42 | 43 | framework.MustEvenlySpread[scope.TiKVGroup](ctx, f, kvg) 44 | }) 45 | }) 46 | -------------------------------------------------------------------------------- /tests/e2e/framework/tiproxy.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package framework 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/onsi/ginkgo/v2" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | 23 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 24 | "github.com/pingcap/tidb-operator/v2/pkg/runtime" 25 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 26 | "github.com/pingcap/tidb-operator/v2/tests/e2e/utils/waiter" 27 | ) 28 | 29 | func (f *Framework) WaitForTiProxyGroupReady(ctx context.Context, pg *v1alpha1.TiProxyGroup) { 30 | ginkgo.By("wait for tiproxy group ready") 31 | f.Must(waiter.WaitForObjectCondition[scope.TiProxyGroup]( 32 | ctx, 33 | f.Client, 34 | pg, 35 | v1alpha1.CondReady, 36 | metav1.ConditionTrue, 37 | waiter.LongTaskTimeout, 38 | )) 39 | f.Must(waiter.WaitForTiProxysHealthy(ctx, f.Client, pg, waiter.LongTaskTimeout)) 40 | f.Must(waiter.WaitForPodsReady(ctx, f.Client, runtime.FromTiProxyGroup(pg), waiter.LongTaskTimeout)) 41 | } 42 | -------------------------------------------------------------------------------- /tests/e2e/framework/tso.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package framework 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/onsi/ginkgo/v2" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | 23 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 24 | "github.com/pingcap/tidb-operator/v2/pkg/runtime" 25 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 26 | "github.com/pingcap/tidb-operator/v2/tests/e2e/utils/waiter" 27 | ) 28 | 29 | func (f *Framework) WaitForTSOGroupReady(ctx context.Context, tg *v1alpha1.TSOGroup) { 30 | // TODO: maybe wait for cluster ready 31 | ginkgo.By("wait for tso group ready") 32 | f.Must(waiter.WaitForObjectCondition[scope.TSOGroup]( 33 | ctx, 34 | f.Client, 35 | tg, 36 | v1alpha1.CondReady, 37 | metav1.ConditionTrue, 38 | waiter.LongTaskTimeout, 39 | )) 40 | f.Must(waiter.WaitForTSOsHealthy(ctx, f.Client, tg, waiter.LongTaskTimeout)) 41 | f.Must(waiter.WaitForPodsReady(ctx, f.Client, runtime.FromTSOGroup(tg), waiter.LongTaskTimeout)) 42 | } 43 | -------------------------------------------------------------------------------- /tests/e2e/framework/tikv_worker.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package framework 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/onsi/ginkgo/v2" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | 23 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 24 | "github.com/pingcap/tidb-operator/v2/pkg/runtime" 25 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 26 | "github.com/pingcap/tidb-operator/v2/tests/e2e/utils/waiter" 27 | ) 28 | 29 | func (f *Framework) WaitForTiKVWorkerGroupReady(ctx context.Context, wg *v1alpha1.TiKVWorkerGroup) { 30 | ginkgo.By("wait for tikv worker group ready") 31 | f.Must(waiter.WaitForObjectCondition[scope.TiKVWorkerGroup]( 32 | ctx, 33 | f.Client, 34 | wg, 35 | v1alpha1.CondReady, 36 | metav1.ConditionTrue, 37 | waiter.LongTaskTimeout, 38 | )) 39 | f.Must(waiter.WaitForTiKVWorkersHealthy(ctx, f.Client, wg, waiter.LongTaskTimeout)) 40 | f.Must(waiter.WaitForPodsReady(ctx, f.Client, runtime.FromTiKVWorkerGroup(wg), waiter.LongTaskTimeout)) 41 | } 42 | -------------------------------------------------------------------------------- /pkg/apiutil/core/v1alpha1/tikv_worker.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package coreutil 16 | 17 | import ( 18 | "fmt" 19 | 20 | corev1 "k8s.io/api/core/v1" 21 | 22 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 23 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 24 | ) 25 | 26 | func TiKVWorkerAPIPort(w *v1alpha1.TiKVWorker) int32 { 27 | if w.Spec.Server.Ports.API != nil { 28 | return w.Spec.Server.Ports.API.Port 29 | } 30 | return v1alpha1.DefaultTiKVWorkerPortAPI 31 | } 32 | 33 | func TiKVWorkerGroupAPIPort(wg *v1alpha1.TiKVWorkerGroup) int32 { 34 | if wg.Spec.Template.Spec.Server.Ports.API != nil { 35 | return wg.Spec.Template.Spec.Server.Ports.API.Port 36 | } 37 | return v1alpha1.DefaultTiKVWorkerPortAPI 38 | } 39 | 40 | func TiKVWorkerAdvertiseAPIURL(w *v1alpha1.TiKVWorker) string { 41 | ns := w.Namespace 42 | if ns == "" { 43 | ns = corev1.NamespaceDefault 44 | } 45 | return fmt.Sprintf("%s.%s.%s:%d", PodName[scope.TiKVWorker](w), w.Spec.Subdomain, ns, TiKVWorkerAPIPort(w)) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/utils/k8s/node_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package k8s 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | "github.com/stretchr/testify/require" 22 | corev1 "k8s.io/api/core/v1" 23 | 24 | "github.com/pingcap/tidb-operator/v2/pkg/utils/fake" 25 | ) 26 | 27 | func TestGetNodeLabelsForKeys(t *testing.T) { 28 | node := fake.FakeObj[corev1.Node]("node", 29 | fake.Label[corev1.Node]("foo", "bar"), 30 | fake.Label[corev1.Node](corev1.LabelTopologyRegion, "us-west1"), 31 | fake.Label[corev1.Node](corev1.LabelTopologyZone, "us-west1-a"), 32 | fake.Label[corev1.Node](corev1.LabelHostname, "k8s-node-1"), 33 | fake.Label[corev1.Node]("rack", "rack-1"), 34 | ) 35 | labels := GetNodeLabelsForKeys(node, []string{"region", "zone", "host", "rack"}) 36 | require.Len(t, labels, 4) 37 | assert.Equal(t, "us-west1", labels["region"]) 38 | assert.Equal(t, "us-west1-a", labels["zone"]) 39 | assert.Equal(t, "k8s-node-1", labels["host"]) 40 | assert.Equal(t, "rack-1", labels["rack"]) 41 | } 42 | -------------------------------------------------------------------------------- /pkg/utils/k8s/finalizer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package k8s 16 | 17 | import ( 18 | "context" 19 | 20 | "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" 21 | 22 | "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 23 | "github.com/pingcap/tidb-operator/v2/pkg/client" 24 | ) 25 | 26 | // EnsureFinalizer ensures the finalizer is added to the object and updates the object if necessary. 27 | func EnsureFinalizer(ctx context.Context, cli client.Client, obj client.Object) error { 28 | if controllerutil.AddFinalizer(obj, v1alpha1.Finalizer) { 29 | if err := cli.Update(ctx, obj); err != nil { 30 | return err 31 | } 32 | } 33 | return nil 34 | } 35 | 36 | // RemoveFinalizer removes the finalizer from the object and updates the object if necessary. 37 | func RemoveFinalizer(ctx context.Context, cli client.Client, obj client.Object) error { 38 | if controllerutil.RemoveFinalizer(obj, v1alpha1.Finalizer) { 39 | if err := cli.Update(ctx, obj); err != nil { 40 | return err 41 | } 42 | } 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /pkg/client/opt.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package client 16 | 17 | type ApplyOptions struct { 18 | // Immutable defines fields which is immutable 19 | // It's only for some fields which cannot be changed but actually maybe changed. 20 | // For example, 21 | // Storage class ref can be changed in instance CR to modify volumes 22 | // if feature VolumeAttributesClass is not enabled(just like v1). 23 | // However, it's immutable in PVC. When VolumeAttributesClass is enabled, 24 | // storage class should not be applied to PVC. 25 | // NOTE; now slice/array is not supported 26 | Immutable [][]string 27 | } 28 | 29 | type ApplyOption interface { 30 | With(opts *ApplyOptions) 31 | } 32 | 33 | type ApplyOptionFunc func(opts *ApplyOptions) 34 | 35 | func (f ApplyOptionFunc) With(opts *ApplyOptions) { 36 | f(opts) 37 | } 38 | 39 | func Immutable(fields ...string) ApplyOption { 40 | return ApplyOptionFunc(func(opts *ApplyOptions) { 41 | if len(fields) == 0 { 42 | return 43 | } 44 | opts.Immutable = append(opts.Immutable, fields) 45 | }) 46 | } 47 | -------------------------------------------------------------------------------- /tests/e2e/framework/scheduling.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package framework 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/onsi/ginkgo/v2" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | 23 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 24 | "github.com/pingcap/tidb-operator/v2/pkg/runtime" 25 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 26 | "github.com/pingcap/tidb-operator/v2/tests/e2e/utils/waiter" 27 | ) 28 | 29 | func (f *Framework) WaitForSchedulingGroupReady(ctx context.Context, sg *v1alpha1.SchedulingGroup) { 30 | // TODO: maybe wait for cluster ready 31 | ginkgo.By("wait for scheduling group ready") 32 | f.Must(waiter.WaitForObjectCondition[scope.SchedulingGroup]( 33 | ctx, 34 | f.Client, 35 | sg, 36 | v1alpha1.CondReady, 37 | metav1.ConditionTrue, 38 | waiter.LongTaskTimeout, 39 | )) 40 | f.Must(waiter.WaitForSchedulingsHealthy(ctx, f.Client, sg, waiter.LongTaskTimeout)) 41 | f.Must(waiter.WaitForPodsReady(ctx, f.Client, runtime.FromSchedulingGroup(sg), waiter.LongTaskTimeout)) 42 | } 43 | -------------------------------------------------------------------------------- /hack/tools.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2024 PingCAP, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # DEPRECATED 17 | # It's not called now. All tools are migrated to use tools feature introduced in go1.24 18 | # Just keep it if some other tools which are not written by go are introduced. 19 | 20 | set -o errexit 21 | set -o nounset 22 | set -o pipefail 23 | 24 | ROOT=$(cd $(dirname "${BASH_SOURCE[0]}")/..; pwd -P) 25 | 26 | source $ROOT/hack/lib/vars.sh 27 | source $ROOT/hack/lib/download.sh 28 | 29 | BIN_DIR=$ROOT/_output/bin 30 | mkdir -p $BIN_DIR 31 | 32 | # Just keep as example 33 | function kubectl() { 34 | download s_curl $1 \ 35 | https://dl.k8s.io/release/VERSION/bin/OS/ARCH/kubectl \ 36 | v1.31.0 \ 37 | "version --client | awk '/Client/{print \$3}'" 38 | } 39 | 40 | # Create a script to call go tool in _output/bin 41 | function go_tools() { 42 | echo "installing ${1}" 43 | cat << EOF > ${BIN_DIR}/${1} 44 | #!/usr/bin/env bash 45 | go tool -modfile ${ROOT}/tools/${1}/go.mod ${1} "\${@}" 46 | EOF 47 | 48 | chmod +x ${BIN_DIR}/${1} 49 | } 50 | 51 | 52 | go_tools $1 53 | -------------------------------------------------------------------------------- /tests/e2e/utils/s3/interface.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package s3 16 | 17 | import ( 18 | "context" 19 | "fmt" 20 | 21 | "k8s.io/client-go/rest" 22 | ) 23 | 24 | type Interface interface { 25 | Init(ctx context.Context, ns string, opts ...Option) error 26 | } 27 | 28 | type Option interface { 29 | With(opts *Options) 30 | } 31 | 32 | type Options struct { 33 | Bucket string 34 | AccessKey string 35 | SecretKey string 36 | } 37 | 38 | type OptionFunc func(*Options) 39 | 40 | func (f OptionFunc) With(opts *Options) { 41 | f(opts) 42 | } 43 | 44 | func WithBucket(bucket string) Option { 45 | return OptionFunc(func(o *Options) { 46 | o.Bucket = bucket 47 | }) 48 | } 49 | 50 | func WithKey(ak, sk string) Option { 51 | return OptionFunc(func(o *Options) { 52 | o.AccessKey = ak 53 | o.SecretKey = sk 54 | }) 55 | } 56 | 57 | func New(provider string, cfg *rest.Config) (Interface, error) { 58 | switch provider { 59 | case "minio": 60 | return NewMinio(cfg) 61 | } 62 | return nil, fmt.Errorf("no storage supported for this provider: %s", provider) 63 | } 64 | -------------------------------------------------------------------------------- /pkg/apiutil/core/v1alpha1/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package coreutil 16 | 17 | import ( 18 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 19 | ) 20 | 21 | func hostToURL(host string, isTLS bool) string { 22 | scheme := "http" 23 | if isTLS { 24 | scheme = "https" 25 | } 26 | 27 | return scheme + "://" + host 28 | } 29 | 30 | var allMainContainers = map[string]struct{}{ 31 | v1alpha1.ContainerNamePD: {}, 32 | v1alpha1.ContainerNameTiKV: {}, 33 | v1alpha1.ContainerNameTiDB: {}, 34 | v1alpha1.ContainerNameTiFlash: {}, 35 | v1alpha1.ContainerNameTiCDC: {}, 36 | v1alpha1.ContainerNameTSO: {}, 37 | v1alpha1.ContainerNameScheduler: {}, 38 | v1alpha1.ContainerNameScheduling: {}, 39 | v1alpha1.ContainerNameTiProxy: {}, 40 | } 41 | 42 | // IsMainContainer checks whether the container is a main container 43 | // Main container means the main component container of an instance 44 | func IsMainContainer(name string) bool { 45 | if _, ok := allMainContainers[name]; ok { 46 | return true 47 | } 48 | 49 | return false 50 | } 51 | -------------------------------------------------------------------------------- /pkg/tikvapi/v1/client_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tikvapi 16 | 17 | import ( 18 | "net/http" 19 | "net/http/httptest" 20 | "testing" 21 | "time" 22 | 23 | "github.com/stretchr/testify/assert" 24 | "github.com/stretchr/testify/require" 25 | ) 26 | 27 | func TestTiKVClient_GetLeaderCount(t *testing.T) { 28 | jsonStr := ` 29 | # HELP tikv_raftstore_region_count Number of regions collected in region_collector 30 | # TYPE tikv_raftstore_region_count gauge 31 | tikv_raftstore_region_count{type="buckets"} 50 32 | tikv_raftstore_region_count{type="leader"} 20 33 | tikv_raftstore_region_count{type="region"} 50 34 | ` 35 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 36 | assert.Equal(t, "/metrics", r.URL.Path) 37 | assert.Equal(t, http.MethodGet, r.Method) 38 | _, err := w.Write([]byte(jsonStr)) 39 | assert.NoError(t, err) 40 | })) 41 | defer server.Close() 42 | 43 | client := NewTiKVClient(server.URL, 5*time.Second, nil, false) 44 | count, err := client.GetLeaderCount() 45 | require.NoError(t, err) 46 | assert.Equal(t, 20, count) 47 | } 48 | -------------------------------------------------------------------------------- /pkg/version/version_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package version 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func TestGetVersion(t *testing.T) { 24 | gitVersion = "v2.0.0" 25 | gitCommit = "1234567" 26 | gitTreeState = "clean" 27 | buildDate = "2024-01-01T00:00:00Z" 28 | 29 | info := Get() 30 | assert.Equal(t, "v2.0.0", info.GitVersion) 31 | assert.Equal(t, "1234567", info.GitCommit) 32 | assert.Equal(t, "clean", info.GitTreeState) 33 | assert.Equal(t, "2024-01-01T00:00:00Z", info.BuildDate) 34 | 35 | kvs := info.KeysAndValues() 36 | assert.Len(t, kvs, 14) 37 | assert.Equal(t, "gitVersion", kvs[0]) 38 | assert.Equal(t, "v2.0.0", kvs[1]) 39 | assert.Equal(t, "gitCommit", kvs[2]) 40 | assert.Equal(t, "1234567", kvs[3]) 41 | assert.Equal(t, "gitTreeState", kvs[4]) 42 | assert.Equal(t, "clean", kvs[5]) 43 | assert.Equal(t, "buildDate", kvs[6]) 44 | assert.Equal(t, "2024-01-01T00:00:00Z", kvs[7]) 45 | 46 | str := info.String() 47 | assert.Contains(t, str, "v2.0.0") 48 | assert.Contains(t, str, "1234567") 49 | assert.Contains(t, str, "clean") 50 | assert.Contains(t, str, "2024-01-01T00:00:00Z") 51 | } 52 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "docker" 4 | directories: 5 | - "/image" 6 | schedule: 7 | interval: "daily" 8 | - package-ecosystem: "gomod" 9 | open-pull-requests-limit: 20 10 | directories: 11 | - "/" 12 | - "/api" 13 | - "/tests/validation" 14 | - "/tools/**/*" 15 | schedule: 16 | interval: "daily" 17 | allow: 18 | - dependency-name: "k8s.io/*" 19 | - dependency-name: "sigs.k8s.io/*" 20 | - dependency-name: "github.com/Azure/azure-sdk-for-go/*" 21 | - dependency-name: "github.com/aws/aws-sdk-go-v2/*" 22 | - dependency-name: "github.com/aws/smithy-go" 23 | - dependency-name: "helm.sh/helm/v3" 24 | - dependency-name: "github.com/golangci/golangci-lint/v2" 25 | - dependency-name: "github.com/onsi/ginkgo/v2" 26 | - dependency-name: "github.com/onsi/gomega" 27 | - dependency-name: "go.uber.org/mock" 28 | - dependency-name: "github.com/apache/skywalking-eyes" 29 | ignore: 30 | - dependency-name: "k8s.io/*" 31 | update-types: 32 | - "version-update:semver-major" 33 | - "version-update:semver-minor" 34 | - dependency-name: "sigs.k8s.io/*" 35 | update-types: 36 | - "version-update:semver-major" 37 | - "version-update:semver-minor" 38 | - dependency-name: "helm.sh/helm/v3" 39 | update-types: 40 | - "version-update:semver-major" 41 | - "version-update:semver-minor" 42 | groups: 43 | k8s: 44 | patterns: 45 | - "k8s.io/*" 46 | - "sigs.k8s.io/*" 47 | aws: 48 | patterns: 49 | - "github.com/aws/aws-sdk-go-v2/*" 50 | - "github.com/aws/smithy-go" 51 | azure: 52 | patterns: 53 | - "github.com/Azure/azure-sdk-for-go/*" 54 | ginkgo: 55 | patterns: 56 | - "github.com/onsi/ginkgo/v2" 57 | - "github.com/onsi/gomega" 58 | -------------------------------------------------------------------------------- /docs/convention.md: -------------------------------------------------------------------------------- 1 | # Conventions of TiDB Operator 2 | 3 | 4 | - [Code conventions](#code-conventions) 5 | - [Directory and file conventions](#directory-and-file-conventions) 6 | 7 | 8 | Conventions are copied from [Kubernetes Conventions](https://www.kubernetes.dev/docs/guide/coding-convention), with some unused items removed. 9 | 10 | ## Code conventions 11 | 12 | - [Bash Sytle Guide](https://google.github.io/styleguide/shellguide.html) 13 | - [Effective Go](https://go.dev/doc/effective_go) 14 | - [Go Code Review Comments](https://go.dev/wiki/CodeReviewComments) 15 | - [Go Test Comments](https://go.dev/wiki/TestComments) 16 | - [Go Style Guide](https://google.github.io/styleguide/go/decisions) 17 | - [Kubernetes API Conventions](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md) 18 | 19 | ## Directory and file conventions 20 | 21 | - Avoid package sprawl. Find an appropriate subdirectory for new packages. 22 | - Avoid general utility packages. Packages called "util" are suspect. Instead, derive a name that describes your desired function. For example, the utility functions dealing with waiting for operations are in the wait package and include functionality like Poll. The full name is wait.Poll. 23 | - All filenames should be lowercase. 24 | - Go source files and directories use underscores, not dashes. 25 | - Package directories should generally avoid using separators as much as possible. When package names are multiple words, they usually should be in nested subdirectories. 26 | - Document directories and filenames should use dashes rather than underscores. 27 | - Forked third party Go code goes in third_party. 28 | - Third-party code must include licenses. This includes modified third-party code and excerpts, as well. 29 | 30 | -------------------------------------------------------------------------------- /tests/e2e/data/tso.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package data 16 | 17 | import ( 18 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 19 | "k8s.io/utils/ptr" 20 | 21 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 22 | ) 23 | 24 | func NewTSOGroup(ns string, patches ...GroupPatch[*v1alpha1.TSOGroup]) *v1alpha1.TSOGroup { 25 | tg := &v1alpha1.TSOGroup{ 26 | ObjectMeta: metav1.ObjectMeta{ 27 | Namespace: ns, 28 | Name: defaultTSOGroupName, 29 | }, 30 | Spec: v1alpha1.TSOGroupSpec{ 31 | Cluster: v1alpha1.ClusterReference{Name: defaultClusterName}, 32 | Replicas: ptr.To[int32](1), 33 | Template: v1alpha1.TSOTemplate{ 34 | Spec: v1alpha1.TSOTemplateSpec{ 35 | Version: defaultVersion, 36 | Image: ptr.To(defaultImageRegistry + "pd"), 37 | }, 38 | }, 39 | }, 40 | } 41 | for _, p := range patches { 42 | p.Patch(tg) 43 | } 44 | 45 | return tg 46 | } 47 | 48 | func WithTSONextGen() GroupPatch[*v1alpha1.TSOGroup] { 49 | return GroupPatchFunc[*v1alpha1.TSOGroup](func(obj *v1alpha1.TSOGroup) { 50 | obj.Spec.Template.Spec.Version = "v9.0.0" 51 | obj.Spec.Template.Spec.Image = ptr.To(defaultImageRegistry + "pd:master-next-gen") 52 | }) 53 | } 54 | -------------------------------------------------------------------------------- /pkg/controllers/tidb/tasks/activate.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 21 | "github.com/pingcap/tidb-operator/v2/pkg/client" 22 | "github.com/pingcap/tidb-operator/v2/pkg/tidbapi/v1" 23 | "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 24 | ) 25 | 26 | func TaskActivate(state *ReconcileContext, c client.Client) task.Task { 27 | return task.NameTaskFunc("Activate", func(ctx context.Context) task.Result { 28 | obj := state.Object() 29 | if obj.Spec.Mode == v1alpha1.TiDBModeStandBy { 30 | return task.Complete().With("tidb is standby") 31 | } 32 | if !state.IsHealthy() { 33 | return task.Retry(defaultTaskWaitDuration).With("tidb is unhealthy ") 34 | } 35 | status, err := state.TiDBClient.GetPoolStatus(ctx) 36 | if err != nil { 37 | return task.Fail().With("cannot get pool status: %v", err) 38 | } 39 | if status.State != tidbapi.PoolStateActivated { 40 | if err := state.TiDBClient.Activate(ctx, obj.Spec.Keyspace); err != nil { 41 | return task.Fail().With("cannot activate: %v", err) 42 | } 43 | } 44 | return task.Complete().With("tidb is activated") 45 | }) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/utils/k8s/node.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package k8s 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | ) 20 | 21 | // a pre-defined mapping that mapping some short label name to K8s well-known labels. 22 | // PD depend on short label name to gain better performance. 23 | // See: https://github.com/pingcap/tidb-operator/issues/4678 for more details. 24 | var shortLabelNameToK8sLabel = map[string][]string{ 25 | "region": {corev1.LabelTopologyRegion}, 26 | "zone": {corev1.LabelTopologyZone}, 27 | "host": {corev1.LabelHostname}, 28 | } 29 | 30 | // GetNodeLabelsForKeys gets the labels of the node for the specified keys. 31 | // This function is used to get the labels for setting store & server labels. 32 | func GetNodeLabelsForKeys(node *corev1.Node, keys []string) map[string]string { 33 | labels := make(map[string]string) 34 | for _, key := range keys { 35 | if value, ok := node.Labels[key]; ok { 36 | labels[key] = value 37 | continue 38 | } 39 | if k8sLabels, ok := shortLabelNameToK8sLabel[key]; ok { 40 | for _, kl := range k8sLabels { 41 | if value, ok := node.Labels[kl]; ok { 42 | labels[key] = value 43 | break 44 | } 45 | } 46 | } 47 | } 48 | return labels 49 | } 50 | -------------------------------------------------------------------------------- /tools/controller-gen/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pingcap/tidb-operator/v2/tools/controller-gen 2 | 3 | go 1.24.0 4 | 5 | tool sigs.k8s.io/controller-tools/cmd/controller-gen 6 | 7 | require ( 8 | github.com/fatih/color v1.18.0 // indirect 9 | github.com/fxamacker/cbor/v2 v2.7.0 // indirect 10 | github.com/go-logr/logr v1.4.2 // indirect 11 | github.com/gobuffalo/flect v1.0.3 // indirect 12 | github.com/gogo/protobuf v1.3.2 // indirect 13 | github.com/google/gofuzz v1.2.0 // indirect 14 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 15 | github.com/json-iterator/go v1.1.12 // indirect 16 | github.com/mattn/go-colorable v0.1.13 // indirect 17 | github.com/mattn/go-isatty v0.0.20 // indirect 18 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 19 | github.com/modern-go/reflect2 v1.0.2 // indirect 20 | github.com/spf13/cobra v1.9.1 // indirect 21 | github.com/spf13/pflag v1.0.6 // indirect 22 | github.com/x448/float16 v0.8.4 // indirect 23 | golang.org/x/mod v0.23.0 // indirect 24 | golang.org/x/net v0.35.0 // indirect 25 | golang.org/x/sync v0.11.0 // indirect 26 | golang.org/x/sys v0.30.0 // indirect 27 | golang.org/x/text v0.22.0 // indirect 28 | golang.org/x/tools v0.30.0 // indirect 29 | gopkg.in/inf.v0 v0.9.1 // indirect 30 | gopkg.in/yaml.v2 v2.4.0 // indirect 31 | gopkg.in/yaml.v3 v3.0.1 // indirect 32 | k8s.io/api v0.32.11 // indirect 33 | k8s.io/apiextensions-apiserver v0.32.11 // indirect 34 | k8s.io/apimachinery v0.32.11 // indirect 35 | k8s.io/klog/v2 v2.130.1 // indirect 36 | k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect 37 | sigs.k8s.io/controller-tools v0.17.3 // indirect 38 | sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect 39 | sigs.k8s.io/structured-merge-diff/v4 v4.4.3 // indirect 40 | sigs.k8s.io/yaml v1.4.0 // indirect 41 | ) 42 | -------------------------------------------------------------------------------- /pkg/controllers/tidb/tasks/pvc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | 20 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 21 | meta "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 22 | coreutil "github.com/pingcap/tidb-operator/v2/pkg/apiutil/core/v1alpha1" 23 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/common" 24 | "github.com/pingcap/tidb-operator/v2/pkg/features" 25 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 26 | ) 27 | 28 | func PVCNewer() common.PVCNewer[*v1alpha1.TiDB] { 29 | return common.PVCNewerFunc[*v1alpha1.TiDB](func( 30 | cluster *v1alpha1.Cluster, tidb *v1alpha1.TiDB, fg features.Gates, 31 | ) []*corev1.PersistentVolumeClaim { 32 | pvcs := coreutil.PVCs[scope.TiDB]( 33 | cluster, 34 | tidb, 35 | coreutil.WithLegacyK8sAppLabels(), 36 | coreutil.EnableVAC(fg.Enabled(meta.VolumeAttributesClass)), 37 | coreutil.PVCPatchFunc(func(_ *v1alpha1.Volume, pvc *corev1.PersistentVolumeClaim) { 38 | // legacy labels in v1 39 | if cluster.Status.ID != "" { 40 | pvc.Labels[v1alpha1.LabelKeyClusterID] = cluster.Status.ID 41 | } 42 | }), 43 | ) 44 | 45 | return pvcs 46 | }) 47 | } 48 | -------------------------------------------------------------------------------- /pkg/controllers/ticdc/tasks/pvc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | 20 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 21 | meta "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 22 | coreutil "github.com/pingcap/tidb-operator/v2/pkg/apiutil/core/v1alpha1" 23 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/common" 24 | "github.com/pingcap/tidb-operator/v2/pkg/features" 25 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 26 | ) 27 | 28 | func PVCNewer() common.PVCNewer[*v1alpha1.TiCDC] { 29 | return common.PVCNewerFunc[*v1alpha1.TiCDC](func( 30 | cluster *v1alpha1.Cluster, ticdc *v1alpha1.TiCDC, fg features.Gates, 31 | ) []*corev1.PersistentVolumeClaim { 32 | pvcs := coreutil.PVCs[scope.TiCDC]( 33 | cluster, 34 | ticdc, 35 | coreutil.WithLegacyK8sAppLabels(), 36 | coreutil.EnableVAC(fg.Enabled(meta.VolumeAttributesClass)), 37 | coreutil.PVCPatchFunc(func(_ *v1alpha1.Volume, pvc *corev1.PersistentVolumeClaim) { 38 | // legacy labels in v1 39 | if cluster.Status.ID != "" { 40 | pvc.Labels[v1alpha1.LabelKeyClusterID] = cluster.Status.ID 41 | } 42 | }), 43 | ) 44 | 45 | return pvcs 46 | }) 47 | } 48 | -------------------------------------------------------------------------------- /pkg/controllers/tiflash/tasks/finalizer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "context" 19 | 20 | corev1 "k8s.io/api/core/v1" 21 | 22 | "github.com/pingcap/tidb-operator/v2/pkg/client" 23 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/common" 24 | "github.com/pingcap/tidb-operator/v2/pkg/timanager" 25 | fm "github.com/pingcap/tidb-operator/v2/pkg/timanager/tiflash" 26 | "github.com/pingcap/tidb-operator/v2/pkg/utils/task/v3" 27 | ) 28 | 29 | const ( 30 | // for deleted store, we'll set grace period to the default 31 | defaultGracePeriod = 30 32 | ) 33 | 34 | var SubresourceLister = common.NewSubresourceLister( 35 | common.NewSubresource[corev1.PodList](client.GracePeriodSeconds(defaultGracePeriod)), 36 | common.NewSubresource[corev1.ConfigMapList](), 37 | common.NewSubresource[corev1.PersistentVolumeClaimList](), 38 | ) 39 | 40 | func TaskDeregisterTiFlashClient(state State, fcm fm.TiFlashClientManager) task.Task { 41 | return task.NameTaskFunc("DeregisterTiFlashClient", func(ctx context.Context) task.Result { 42 | key := state.Key() 43 | 44 | fcm.Deregister(timanager.PrimaryKey(key.Namespace, key.Name)) 45 | return task.Complete().With("deregister tiflash client") 46 | }) 47 | } 48 | -------------------------------------------------------------------------------- /tools/mdtoc/go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 4 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/gomarkdown/markdown v0.0.0-20210514010506-3b9f47219fe7 h1:oKYOfNR7Hp6XpZ4JqolL5u642Js5Z0n7psPVl+S5heo= 6 | github.com/gomarkdown/markdown v0.0.0-20210514010506-3b9f47219fe7/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU= 7 | github.com/mmarkdown/mmark v2.0.40+incompatible h1:vMeUeDzBK3H+/mU0oMVfMuhSXJlIA+DE/DMPQNAj5C4= 8 | github.com/mmarkdown/mmark v2.0.40+incompatible/go.mod h1:Uvmoz7tvsWpr7bMVxIpqZPyN3FbOtzDmnsJDFp7ltJs= 9 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 10 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 11 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 12 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 13 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 14 | golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ= 15 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 16 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 17 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 18 | sigs.k8s.io/mdtoc v1.1.0 h1:q3YtqYzmC2e0hgLXRIOm7/QLuPux1CX3ZHCwlbABxZo= 19 | sigs.k8s.io/mdtoc v1.1.0/go.mod h1:QZLVEdHH2iNIR4uHAZyvFRtjloHgVItk8lo/mzCtq3w= 20 | -------------------------------------------------------------------------------- /pkg/controllers/tiproxy/tasks/pvc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | 20 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 21 | meta "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 22 | coreutil "github.com/pingcap/tidb-operator/v2/pkg/apiutil/core/v1alpha1" 23 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/common" 24 | "github.com/pingcap/tidb-operator/v2/pkg/features" 25 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 26 | ) 27 | 28 | func PVCNewer() common.PVCNewer[*v1alpha1.TiProxy] { 29 | return common.PVCNewerFunc[*v1alpha1.TiProxy](func( 30 | cluster *v1alpha1.Cluster, tiproxy *v1alpha1.TiProxy, fg features.Gates, 31 | ) []*corev1.PersistentVolumeClaim { 32 | pvcs := coreutil.PVCs[scope.TiProxy]( 33 | cluster, 34 | tiproxy, 35 | coreutil.WithLegacyK8sAppLabels(), 36 | coreutil.EnableVAC(fg.Enabled(meta.VolumeAttributesClass)), 37 | coreutil.PVCPatchFunc(func(_ *v1alpha1.Volume, pvc *corev1.PersistentVolumeClaim) { 38 | // legacy labels in v1 39 | if cluster.Status.ID != "" { 40 | pvc.Labels[v1alpha1.LabelKeyClusterID] = cluster.Status.ID 41 | } 42 | }), 43 | ) 44 | 45 | return pvcs 46 | }) 47 | } 48 | -------------------------------------------------------------------------------- /api/meta/v1alpha1/types.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package v1alpha1 16 | 17 | const ( 18 | // Finalizer is the finalizer used by all resources managed by TiDB Operator. 19 | Finalizer = "pingcap.com/finalizer" 20 | ) 21 | 22 | const ( 23 | // NamePrefix for "names" in k8s resources 24 | // Users may overlay some fields in managed resource such as pods. Names with this 25 | // prefix is preserved to avoid conflicts with fields defined by users. 26 | NamePrefix = "ti-" 27 | 28 | // VolNamePrefix is defined for custom persistent volume which may have name conflicts 29 | // with the volumes managed by tidb operator 30 | VolNamePrefix = NamePrefix + "vol-" 31 | ) 32 | 33 | type Component string 34 | 35 | const ( 36 | // component name 37 | ComponentPD Component = "pd" 38 | ComponentTiDB Component = "tidb" 39 | ComponentTiKV Component = "tikv" 40 | ComponentTiKVWorker Component = "tikv-worker" 41 | ComponentTiFlash Component = "tiflash" 42 | ComponentTiCDC Component = "ticdc" 43 | ComponentTSO Component = "tso" 44 | ComponentScheduling Component = "scheduling" 45 | ComponentTiProxy Component = "tiproxy" 46 | // Deprecated: use ComponentScheduling 47 | ComponentScheduler Component = "scheduler" 48 | ) 49 | -------------------------------------------------------------------------------- /tests/e2e/data/scheduling.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package data 16 | 17 | import ( 18 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 19 | "k8s.io/utils/ptr" 20 | 21 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 22 | ) 23 | 24 | func NewSchedulingGroup(ns string, patches ...GroupPatch[*v1alpha1.SchedulingGroup]) *v1alpha1.SchedulingGroup { 25 | sg := &v1alpha1.SchedulingGroup{ 26 | ObjectMeta: metav1.ObjectMeta{ 27 | Namespace: ns, 28 | Name: defaultSchedulingGroupName, 29 | }, 30 | Spec: v1alpha1.SchedulingGroupSpec{ 31 | Cluster: v1alpha1.ClusterReference{Name: defaultClusterName}, 32 | Replicas: ptr.To[int32](1), 33 | Template: v1alpha1.SchedulingTemplate{ 34 | Spec: v1alpha1.SchedulingTemplateSpec{ 35 | Version: defaultVersion, 36 | Image: ptr.To(defaultImageRegistry + "pd"), 37 | }, 38 | }, 39 | }, 40 | } 41 | for _, p := range patches { 42 | p.Patch(sg) 43 | } 44 | 45 | return sg 46 | } 47 | 48 | func WithSchedulingNextGen() GroupPatch[*v1alpha1.SchedulingGroup] { 49 | return GroupPatchFunc[*v1alpha1.SchedulingGroup](func(obj *v1alpha1.SchedulingGroup) { 50 | obj.Spec.Template.Spec.Version = "v9.0.0" 51 | obj.Spec.Template.Spec.Image = ptr.To(defaultImageRegistry + "pd:master-next-gen") 52 | }) 53 | } 54 | -------------------------------------------------------------------------------- /pkg/controllers/pd/tasks/pvc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | corev1 "k8s.io/api/core/v1" 19 | 20 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 21 | meta "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 22 | coreutil "github.com/pingcap/tidb-operator/v2/pkg/apiutil/core/v1alpha1" 23 | "github.com/pingcap/tidb-operator/v2/pkg/controllers/common" 24 | "github.com/pingcap/tidb-operator/v2/pkg/features" 25 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 26 | ) 27 | 28 | func PVCNewer() common.PVCNewer[*v1alpha1.PD] { 29 | return common.PVCNewerFunc[*v1alpha1.PD]( 30 | func(cluster *v1alpha1.Cluster, pd *v1alpha1.PD, fg features.Gates) []*corev1.PersistentVolumeClaim { 31 | pvcs := coreutil.PVCs[scope.PD]( 32 | cluster, 33 | pd, 34 | coreutil.EnableVAC(fg.Enabled(meta.VolumeAttributesClass)), 35 | coreutil.PVCPatchFunc(func(_ *v1alpha1.Volume, pvc *corev1.PersistentVolumeClaim) { 36 | // legacy labels in v1 37 | if cluster.Status.ID != "" { 38 | pvc.Labels[v1alpha1.LabelKeyClusterID] = cluster.Status.ID 39 | } 40 | if pd.Status.ID != "" { 41 | pvc.Labels[v1alpha1.LabelKeyMemberID] = pd.Status.ID 42 | } 43 | }), 44 | ) 45 | 46 | return pvcs 47 | }, 48 | ) 49 | } 50 | -------------------------------------------------------------------------------- /tests/e2e/utils/waiter/tso.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package waiter 16 | 17 | import ( 18 | "context" 19 | "fmt" 20 | "time" 21 | 22 | "k8s.io/apimachinery/pkg/util/errors" 23 | 24 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 25 | "github.com/pingcap/tidb-operator/v2/pkg/client" 26 | ) 27 | 28 | func WaitForTSOsHealthy(ctx context.Context, c client.Client, tg *v1alpha1.TSOGroup, timeout time.Duration) error { 29 | list := v1alpha1.TSOList{} 30 | return WaitForList(ctx, c, &list, func() error { 31 | errs := []error{} 32 | if len(list.Items) != int(*tg.Spec.Replicas) { 33 | errs = append(errs, fmt.Errorf("tso %s/%s replicas %d not equal to %d", tg.Namespace, tg.Name, len(list.Items), *tg.Spec.Replicas)) 34 | } 35 | for i := range list.Items { 36 | tso := &list.Items[i] 37 | if err := checkInstanceStatus(v1alpha1.LabelValComponentTSO, tso.Name, tso.Namespace, tso.Generation, tso.Status.CommonStatus); err != nil { 38 | errs = append(errs, err) 39 | } 40 | } 41 | return errors.NewAggregate(errs) 42 | }, timeout, client.InNamespace(tg.Namespace), client.MatchingLabels{ 43 | v1alpha1.LabelKeyCluster: tg.Spec.Cluster.Name, 44 | v1alpha1.LabelKeyGroup: tg.Name, 45 | v1alpha1.LabelKeyComponent: v1alpha1.LabelValComponentTSO, 46 | }) 47 | } 48 | -------------------------------------------------------------------------------- /tests/e2e/framework/cert.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package framework 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/onsi/ginkgo/v2" 21 | 22 | "github.com/pingcap/tidb-operator/v2/tests/e2e/utils/cert" 23 | ) 24 | 25 | type CertManager interface { 26 | Install(ctx context.Context, ns, cluster string) 27 | } 28 | 29 | type certManager struct { 30 | f *Framework 31 | 32 | cf cert.Factory 33 | } 34 | 35 | type noopCertManager struct{} 36 | 37 | func (cm *noopCertManager) Install(ctx context.Context, ns, cluster string) {} 38 | 39 | func (f *Framework) SetupCertManager(tls bool) CertManager { 40 | if !tls { 41 | return &noopCertManager{} 42 | } 43 | 44 | w := &certManager{ 45 | f: f, 46 | cf: cert.NewFactory(f.Client), 47 | } 48 | w.deferCleanup() 49 | 50 | return w 51 | } 52 | 53 | // Install is called to install all certs of the whole cluster 54 | // NOTE: Install must be called after all groups have been created 55 | func (cm *certManager) Install(ctx context.Context, ns, cluster string) { 56 | cm.f.Must(cm.cf.Install(ctx, ns, cluster)) 57 | } 58 | 59 | func (cm *certManager) deferCleanup() { 60 | ginkgo.BeforeEach(func(ctx context.Context) { 61 | ginkgo.DeferCleanup(func(ctx context.Context) { 62 | cm.f.Must(cm.cf.Cleanup(ctx)) 63 | }) 64 | }) 65 | } 66 | -------------------------------------------------------------------------------- /tests/e2e/utils/waiter/tidb.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package waiter 16 | 17 | import ( 18 | "context" 19 | "fmt" 20 | "time" 21 | 22 | "k8s.io/apimachinery/pkg/util/errors" 23 | 24 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 25 | "github.com/pingcap/tidb-operator/v2/pkg/client" 26 | ) 27 | 28 | func WaitForTiDBsHealthy(ctx context.Context, c client.Client, dbg *v1alpha1.TiDBGroup, timeout time.Duration) error { 29 | list := v1alpha1.TiDBList{} 30 | return WaitForList(ctx, c, &list, func() error { 31 | errs := []error{} 32 | if len(list.Items) != int(*dbg.Spec.Replicas) { 33 | errs = append(errs, fmt.Errorf("db %s/%s replicas %d not equal to %d", dbg.Namespace, dbg.Name, len(list.Items), *dbg.Spec.Replicas)) 34 | } 35 | for i := range list.Items { 36 | db := &list.Items[i] 37 | if err := checkInstanceStatus(v1alpha1.LabelValComponentTiDB, db.Name, db.Namespace, db.Generation, db.Status.CommonStatus); err != nil { 38 | errs = append(errs, err) 39 | } 40 | } 41 | return errors.NewAggregate(errs) 42 | }, timeout, client.InNamespace(dbg.Namespace), client.MatchingLabels{ 43 | v1alpha1.LabelKeyCluster: dbg.Spec.Cluster.Name, 44 | v1alpha1.LabelKeyGroup: dbg.Name, 45 | v1alpha1.LabelKeyComponent: v1alpha1.LabelValComponentTiDB, 46 | }) 47 | } 48 | -------------------------------------------------------------------------------- /tests/e2e/utils/waiter/ticdc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package waiter 16 | 17 | import ( 18 | "context" 19 | "fmt" 20 | "time" 21 | 22 | "k8s.io/apimachinery/pkg/util/errors" 23 | 24 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 25 | "github.com/pingcap/tidb-operator/v2/pkg/client" 26 | ) 27 | 28 | func WaitForTiCDCsHealthy(ctx context.Context, c client.Client, cg *v1alpha1.TiCDCGroup, timeout time.Duration) error { 29 | list := v1alpha1.TiCDCList{} 30 | return WaitForList(ctx, c, &list, func() error { 31 | errs := []error{} 32 | if len(list.Items) != int(*cg.Spec.Replicas) { 33 | errs = append(errs, fmt.Errorf("cdc %s/%s replicas %d not equal to %d", cg.Namespace, cg.Name, len(list.Items), *cg.Spec.Replicas)) 34 | } 35 | for i := range list.Items { 36 | cdc := &list.Items[i] 37 | if err := checkInstanceStatus(v1alpha1.LabelValComponentTiCDC, cdc.Name, cdc.Namespace, cdc.Generation, cdc.Status.CommonStatus); err != nil { 38 | errs = append(errs, err) 39 | } 40 | } 41 | return errors.NewAggregate(errs) 42 | }, timeout, client.InNamespace(cg.Namespace), client.MatchingLabels{ 43 | v1alpha1.LabelKeyCluster: cg.Spec.Cluster.Name, 44 | v1alpha1.LabelKeyGroup: cg.Name, 45 | v1alpha1.LabelKeyComponent: v1alpha1.LabelValComponentTiCDC, 46 | }) 47 | } 48 | -------------------------------------------------------------------------------- /pkg/controllers/ticdc/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "fmt" 19 | 20 | corev1 "k8s.io/api/core/v1" 21 | 22 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 23 | meta "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 24 | coreutil "github.com/pingcap/tidb-operator/v2/pkg/apiutil/core/v1alpha1" 25 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 26 | ) 27 | 28 | func ConfigMapName(ticdcName string) string { 29 | return ticdcName 30 | } 31 | 32 | // TiCDCServiceURL returns the service URL of a TiCDC member. 33 | func TiCDCServiceURL(ticdc *v1alpha1.TiCDC, scheme string) string { 34 | return fmt.Sprintf("%s://%s.%s.%s.svc:%d", 35 | scheme, 36 | coreutil.PodName[scope.TiCDC](ticdc), 37 | ticdc.Spec.Subdomain, 38 | ticdc.Namespace, 39 | coreutil.TiCDCPort(ticdc), 40 | ) 41 | } 42 | 43 | // VolumeName returns the real spec.volumes[*].name of pod 44 | // TODO(liubo02): extract to namer pkg 45 | func VolumeName(volName string) string { 46 | return meta.VolNamePrefix + volName 47 | } 48 | 49 | func VolumeMount(name string, mount *v1alpha1.VolumeMount) *corev1.VolumeMount { 50 | vm := &corev1.VolumeMount{ 51 | Name: name, 52 | MountPath: mount.MountPath, 53 | SubPath: mount.SubPath, 54 | } 55 | 56 | return vm 57 | } 58 | -------------------------------------------------------------------------------- /tests/e2e/e2e_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package e2e 16 | 17 | import ( 18 | "io" 19 | "testing" 20 | 21 | . "github.com/onsi/ginkgo/v2" 22 | . "github.com/onsi/gomega" 23 | ctrl "sigs.k8s.io/controller-runtime" 24 | "sigs.k8s.io/controller-runtime/pkg/log/zap" 25 | 26 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/br" 27 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/cluster" 28 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/example" 29 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/pd" 30 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/ticdc" 31 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/tidb" 32 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/tiflash" 33 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/tikv" 34 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/tiproxy" 35 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/webhook" 36 | 37 | // TODO: move all tests into suite 38 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/suite/availability" 39 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/suite/cluster" 40 | _ "github.com/pingcap/tidb-operator/v2/tests/e2e/suite/scale" 41 | ) 42 | 43 | func TestE2E(t *testing.T) { 44 | ctrl.SetLogger(zap.New(zap.WriteTo(io.Discard))) 45 | 46 | RegisterFailHandler(Fail) 47 | RunSpecs(t, "E2E Suite") 48 | } 49 | -------------------------------------------------------------------------------- /pkg/controllers/tiproxy/tasks/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 PingCAP, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tasks 16 | 17 | import ( 18 | "fmt" 19 | 20 | corev1 "k8s.io/api/core/v1" 21 | 22 | "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1" 23 | meta "github.com/pingcap/tidb-operator/api/v2/meta/v1alpha1" 24 | coreutil "github.com/pingcap/tidb-operator/v2/pkg/apiutil/core/v1alpha1" 25 | "github.com/pingcap/tidb-operator/v2/pkg/runtime/scope" 26 | ) 27 | 28 | func ConfigMapName(tiproxyName string) string { 29 | return tiproxyName 30 | } 31 | 32 | // TiProxyServiceURL returns the service URL of a tiproxy member. 33 | func TiProxyServiceURL(tiproxy *v1alpha1.TiProxy, scheme string) string { 34 | return fmt.Sprintf("%s://%s.%s.%s.svc:%d", 35 | scheme, 36 | coreutil.PodName[scope.TiProxy](tiproxy), 37 | tiproxy.Spec.Subdomain, 38 | tiproxy.Namespace, 39 | coreutil.TiProxyAPIPort(tiproxy), 40 | ) 41 | } 42 | 43 | // VolumeName returns the real spec.volumes[*].name of pod 44 | // TODO(liubo02): extract to namer pkg 45 | func VolumeName(volName string) string { 46 | return meta.VolNamePrefix + volName 47 | } 48 | 49 | func VolumeMount(name string, mount *v1alpha1.VolumeMount) *corev1.VolumeMount { 50 | return &corev1.VolumeMount{ 51 | Name: name, 52 | MountPath: mount.MountPath, 53 | SubPath: mount.SubPath, 54 | } 55 | } 56 | --------------------------------------------------------------------------------