diff --git a/docs/api-references/docs.md b/docs/api-references/docs.md index 24d809c455..261111cc0c 100644 --- a/docs/api-references/docs.md +++ b/docs/api-references/docs.md @@ -12757,12 +12757,35 @@ kubectl create secret generic -tidb-client-secret –namespace= -

TiFlashConfig

+

TiFlashCommonConfigWraper

(Appears on: -TiFlashSpec) +TiFlashConfigWraper)

+

+ + + + + + + + + + + + + +
FieldDescription
+GenericConfig
+ +github.com/pingcap/tidb-operator/pkg/util/config.GenericConfig + +
+
+

TiFlashConfig

+

TiFlashConfig is the configuration of TiFlash.

@@ -12803,6 +12826,74 @@ ProxyConfig
+

TiFlashConfigWraper

+

+(Appears on: +TiFlashSpec) +

+

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+config
+ + +TiFlashCommonConfigWraper + + +
+
+proxy
+ + +TiFlashProxyConfigWraper + + +
+
+

TiFlashProxyConfigWraper

+

+(Appears on: +TiFlashConfigWraper) +

+

+

+ + + + + + + + + + + + + +
FieldDescription
+GenericConfig
+ +github.com/pingcap/tidb-operator/pkg/util/config.GenericConfig + +
+

TiFlashSpec

(Appears on: @@ -12928,8 +13019,8 @@ TiFlash supports multiple disks.

config
- -TiFlashConfig + +TiFlashConfigWraper diff --git a/go.mod b/go.mod index a21749209a..23878682c8 100644 --- a/go.mod +++ b/go.mod @@ -93,6 +93,7 @@ require ( k8s.io/utils v0.0.0-20190801114015-581e00157fb1 sigs.k8s.io/apiserver-builder-alpha/cmd v0.0.0-20191113095113-4493943d2568 sigs.k8s.io/controller-runtime v0.4.0 + sigs.k8s.io/yaml v1.1.0 ) replace github.com/renstrom/dedent => github.com/lithammer/dedent v1.1.0 diff --git a/manifests/crd.yaml b/manifests/crd.yaml index 10209c86de..657612f762 100644 --- a/manifests/crd.yaml +++ b/manifests/crd.yaml @@ -7889,1156 +7889,7 @@ spec: type: object baseImage: type: string - config: - properties: - config: - properties: - flash: - properties: - compact_log_min_period: - format: int32 - type: integer - flash_cluster: - properties: - log: - type: string - master_ttl: - format: int32 - type: integer - refresh_interval: - format: int32 - type: integer - update_rule_interval: - format: int32 - type: integer - type: object - overlap_threshold: - format: double - type: number - proxy: - properties: - addr: - type: string - advertise-addr: - type: string - config: - type: string - data-dir: - type: string - log-file: - type: string - type: object - type: object - logger: - properties: - count: - format: int32 - type: integer - errorlog: - type: string - level: - type: string - log: - type: string - size: - type: string - type: object - mark_cache_size: - format: int64 - type: integer - minmax_index_cache_size: - format: int64 - type: integer - path_realtime_mode: - type: boolean - tmp_path: - type: string - type: object - proxy: - properties: - coprocessor: - properties: - batch-split-limit: - format: int64 - type: integer - region-max-keys: - format: int64 - type: integer - region-max-size: - type: string - region-split-keys: - format: int64 - type: integer - region-split-size: - type: string - split-region-on-table: - type: boolean - type: object - gc: - properties: - batch-keys: - format: int64 - type: integer - compaction-filter-skip-version-check: - type: boolean - enable-compaction-filter: - type: boolean - max-write-bytes-per-sec: - type: string - type: object - import: - properties: - import-dir: - type: string - max-open-engines: - format: int64 - type: integer - max-prepare-duration: - type: string - num-import-jobs: - format: int64 - type: integer - num-import-sst-jobs: - format: int64 - type: integer - num-threads: - format: int64 - type: integer - region-split-size: - type: string - stream-channel-window: - format: int64 - type: integer - upload-speed-limit: - type: string - type: object - log-file: - type: string - log-level: - type: string - log-rotation-timespan: - type: string - panic-when-unexpected-key-or-data: - type: boolean - pd: - properties: - endpoints: - items: - type: string - type: array - retry-interval: - type: string - retry-log-every: - format: int64 - type: integer - retry-max-count: - format: int64 - type: integer - type: object - raftdb: - properties: - allow-concurrent-memtable-write: - type: boolean - bytes-per-sync: - type: string - compaction-readahead-size: - type: string - create-if-missing: - type: boolean - defaultcf: - properties: - block-based-bloom-filter: - type: boolean - block-cache-size: - type: string - block-size: - type: string - bloom-filter-bits-per-key: - format: int64 - type: integer - cache-index-and-filter-blocks: - type: boolean - compaction-pri: - format: int64 - type: integer - compaction-style: - format: int64 - type: integer - compression-per-level: - items: - type: string - type: array - disable-auto-compactions: - type: boolean - disable-block-cache: - type: boolean - dynamic-level-bytes: - type: boolean - enable-doubly-skiplist: - type: boolean - force-consistency-checks: - type: boolean - hard-pending-compaction-bytes-limit: - type: string - level0-file-num-compaction-trigger: - format: int64 - type: integer - level0-slowdown-writes-trigger: - format: int64 - type: integer - level0-stop-writes-trigger: - format: int64 - type: integer - max-bytes-for-level-base: - type: string - max-bytes-for-level-multiplier: - format: int64 - type: integer - max-compaction-bytes: - type: string - max-write-buffer-number: - format: int64 - type: integer - min-write-buffer-number-to-merge: - format: int64 - type: integer - num-levels: - format: int64 - type: integer - optimize-filters-for-hits: - type: boolean - pin-l0-filter-and-index-blocks: - type: boolean - prop-keys-index-distance: - format: int64 - type: integer - prop-size-index-distance: - format: int64 - type: integer - read-amp-bytes-per-bit: - format: int64 - type: integer - soft-pending-compaction-bytes-limit: - type: string - target-file-size-base: - type: string - titan: - properties: - blob-cache-size: - type: string - blob-file-compression: - type: string - blob-run-mode: - type: string - discardable-ratio: - format: double - type: number - gc-merge-rewrite: - type: boolean - level_merge: - type: boolean - max-gc-batch-size: - type: string - merge-small-file-threshold: - type: string - min-blob-size: - type: string - min-gc-batch-size: - type: string - sample-ratio: - format: double - type: number - type: object - use-bloom-filter: - type: boolean - whole-key-filtering: - type: boolean - write-buffer-size: - type: string - type: object - enable-pipelined-write: - type: boolean - enable-statistics: - type: boolean - info-log-dir: - type: string - info-log-keep-log-file-num: - format: int64 - type: integer - info-log-max-size: - type: string - info-log-roll-time: - type: string - max-background-jobs: - format: int64 - type: integer - max-manifest-file-size: - type: string - max-open-files: - format: int64 - type: integer - max-sub-compactions: - format: int64 - type: integer - max-total-wal-size: - type: string - stats-dump-period: - type: string - use-direct-io-for-flush-and-compaction: - type: boolean - wal-bytes-per-sync: - type: string - wal-dir: - type: string - wal-recovery-mode: - type: string - wal-size-limit: - type: string - wal-ttl-seconds: - format: int64 - type: integer - writable-file-max-buffer-size: - type: string - type: object - raftstore: - properties: - abnormal-leader-missing-duration: - type: string - allow-remove-leader: - type: boolean - apply-early: - type: boolean - apply-max-batch-size: - format: int64 - type: integer - apply-pool-size: - format: int64 - type: integer - apply-yield-duration: - type: string - clean-stale-peer-delay: - type: string - cleanup-import-sst-interval: - type: string - consistency-check-interval: - type: string - dev-assert: - type: boolean - hibernate-regions: - type: boolean - leader-transfer-max-log-lag: - format: int64 - type: integer - lock-cf-compact-bytes-threshold: - type: string - lock-cf-compact-interval: - type: string - max-leader-missing-duration: - type: string - max-peer-down-duration: - type: string - merge-check-tick-interval: - type: string - merge-max-log-gap: - format: int64 - type: integer - messages-per-tick: - format: int64 - type: integer - notify-capacity: - format: int64 - type: integer - pd-heartbeat-tick-interval: - type: string - pd-store-heartbeat-tick-interval: - type: string - peer-stale-state-check-interval: - type: string - perf-level: - format: int64 - type: integer - prevote: - type: boolean - raft-base-tick-interval: - type: string - raft-election-timeout-ticks: - format: int64 - type: integer - raft-entry-cache-life-time: - type: string - raft-entry-max-size: - type: string - raft-heartbeat-ticks: - format: int64 - type: integer - raft-log-gc-count-limit: - format: int64 - type: integer - raft-log-gc-size-limit: - type: string - raft-log-gc-threshold: - format: int64 - type: integer - raft-log-gc-tick-interval: - type: string - raft-max-inflight-msgs: - format: int64 - type: integer - raft-max-size-per-msg: - type: string - raft-reject-transfer-leader-duration: - type: string - raft-store-max-leader-lease: - type: string - region-compact-check-interval: - type: string - region-compact-check-step: - format: int64 - type: integer - region-compact-min-tombstones: - format: int64 - type: integer - region-compact-tombstones-percent: - format: int64 - type: integer - region-split-check-diff: - type: string - report-region-flow-interval: - type: string - right-derive-when-split: - type: boolean - snap-apply-batch-size: - type: string - snap-gc-timeout: - type: string - snap-mgr-gc-tick-interval: - type: string - split-region-check-tick-interval: - type: string - store-max-batch-size: - format: int64 - type: integer - store-pool-size: - format: int64 - type: integer - store-reschedule-duration: - type: string - sync-log: - type: boolean - use-delete-range: - type: boolean - type: object - readpool: - properties: - coprocessor: - properties: - high-concurrency: - format: int64 - type: integer - low-concurrency: - format: int64 - type: integer - max-tasks-per-worker-high: - format: int64 - type: integer - max-tasks-per-worker-low: - format: int64 - type: integer - max-tasks-per-worker-normal: - format: int64 - type: integer - normal-concurrency: - format: int64 - type: integer - stack-size: - type: string - use-unified-pool: - type: boolean - type: object - storage: - properties: - high-concurrency: - format: int64 - type: integer - low-concurrency: - format: int64 - type: integer - max-tasks-per-worker-high: - format: int64 - type: integer - max-tasks-per-worker-low: - format: int64 - type: integer - max-tasks-per-worker-normal: - format: int64 - type: integer - normal-concurrency: - format: int64 - type: integer - stack-size: - type: string - use-unified-pool: - type: boolean - type: object - unified: - properties: - max-tasks-per-worker: - format: int32 - type: integer - max-thread-count: - format: int32 - type: integer - min-thread-count: - format: int32 - type: integer - stack-size: - type: string - type: object - type: object - rocksdb: - properties: - auto-tuned: - type: boolean - bytes-per-sync: - type: string - compaction-readahead-size: - type: string - create-if-missing: - type: boolean - defaultcf: - properties: - block-based-bloom-filter: - type: boolean - block-cache-size: - type: string - block-size: - type: string - bloom-filter-bits-per-key: - format: int64 - type: integer - cache-index-and-filter-blocks: - type: boolean - compaction-pri: - format: int64 - type: integer - compaction-style: - format: int64 - type: integer - compression-per-level: - items: - type: string - type: array - disable-auto-compactions: - type: boolean - disable-block-cache: - type: boolean - dynamic-level-bytes: - type: boolean - enable-doubly-skiplist: - type: boolean - force-consistency-checks: - type: boolean - hard-pending-compaction-bytes-limit: - type: string - level0-file-num-compaction-trigger: - format: int64 - type: integer - level0-slowdown-writes-trigger: - format: int64 - type: integer - level0-stop-writes-trigger: - format: int64 - type: integer - max-bytes-for-level-base: - type: string - max-bytes-for-level-multiplier: - format: int64 - type: integer - max-compaction-bytes: - type: string - max-write-buffer-number: - format: int64 - type: integer - min-write-buffer-number-to-merge: - format: int64 - type: integer - num-levels: - format: int64 - type: integer - optimize-filters-for-hits: - type: boolean - pin-l0-filter-and-index-blocks: - type: boolean - prop-keys-index-distance: - format: int64 - type: integer - prop-size-index-distance: - format: int64 - type: integer - read-amp-bytes-per-bit: - format: int64 - type: integer - soft-pending-compaction-bytes-limit: - type: string - target-file-size-base: - type: string - titan: - properties: - blob-cache-size: - type: string - blob-file-compression: - type: string - blob-run-mode: - type: string - discardable-ratio: - format: double - type: number - gc-merge-rewrite: - type: boolean - level_merge: - type: boolean - max-gc-batch-size: - type: string - merge-small-file-threshold: - type: string - min-blob-size: - type: string - min-gc-batch-size: - type: string - sample-ratio: - format: double - type: number - type: object - use-bloom-filter: - type: boolean - whole-key-filtering: - type: boolean - write-buffer-size: - type: string - type: object - enable-pipelined-write: - type: boolean - enable-statistics: - type: boolean - info-log-dir: - type: string - info-log-keep-log-file-num: - format: int64 - type: integer - info-log-max-size: - type: string - info-log-roll-time: - type: string - lockcf: - properties: - block-based-bloom-filter: - type: boolean - block-cache-size: - type: string - block-size: - type: string - bloom-filter-bits-per-key: - format: int64 - type: integer - cache-index-and-filter-blocks: - type: boolean - compaction-pri: - format: int64 - type: integer - compaction-style: - format: int64 - type: integer - compression-per-level: - items: - type: string - type: array - disable-auto-compactions: - type: boolean - disable-block-cache: - type: boolean - dynamic-level-bytes: - type: boolean - enable-doubly-skiplist: - type: boolean - force-consistency-checks: - type: boolean - hard-pending-compaction-bytes-limit: - type: string - level0-file-num-compaction-trigger: - format: int64 - type: integer - level0-slowdown-writes-trigger: - format: int64 - type: integer - level0-stop-writes-trigger: - format: int64 - type: integer - max-bytes-for-level-base: - type: string - max-bytes-for-level-multiplier: - format: int64 - type: integer - max-compaction-bytes: - type: string - max-write-buffer-number: - format: int64 - type: integer - min-write-buffer-number-to-merge: - format: int64 - type: integer - num-levels: - format: int64 - type: integer - optimize-filters-for-hits: - type: boolean - pin-l0-filter-and-index-blocks: - type: boolean - prop-keys-index-distance: - format: int64 - type: integer - prop-size-index-distance: - format: int64 - type: integer - read-amp-bytes-per-bit: - format: int64 - type: integer - soft-pending-compaction-bytes-limit: - type: string - target-file-size-base: - type: string - titan: - properties: - blob-cache-size: - type: string - blob-file-compression: - type: string - blob-run-mode: - type: string - discardable-ratio: - format: double - type: number - gc-merge-rewrite: - type: boolean - level_merge: - type: boolean - max-gc-batch-size: - type: string - merge-small-file-threshold: - type: string - min-blob-size: - type: string - min-gc-batch-size: - type: string - sample-ratio: - format: double - type: number - type: object - use-bloom-filter: - type: boolean - whole-key-filtering: - type: boolean - write-buffer-size: - type: string - type: object - max-background-jobs: - format: int64 - type: integer - max-manifest-file-size: - type: string - max-open-files: - format: int64 - type: integer - max-sub-compactions: - format: int64 - type: integer - max-total-wal-size: - type: string - raftcf: - properties: - block-based-bloom-filter: - type: boolean - block-cache-size: - type: string - block-size: - type: string - bloom-filter-bits-per-key: - format: int64 - type: integer - cache-index-and-filter-blocks: - type: boolean - compaction-pri: - format: int64 - type: integer - compaction-style: - format: int64 - type: integer - compression-per-level: - items: - type: string - type: array - disable-auto-compactions: - type: boolean - disable-block-cache: - type: boolean - dynamic-level-bytes: - type: boolean - enable-doubly-skiplist: - type: boolean - force-consistency-checks: - type: boolean - hard-pending-compaction-bytes-limit: - type: string - level0-file-num-compaction-trigger: - format: int64 - type: integer - level0-slowdown-writes-trigger: - format: int64 - type: integer - level0-stop-writes-trigger: - format: int64 - type: integer - max-bytes-for-level-base: - type: string - max-bytes-for-level-multiplier: - format: int64 - type: integer - max-compaction-bytes: - type: string - max-write-buffer-number: - format: int64 - type: integer - min-write-buffer-number-to-merge: - format: int64 - type: integer - num-levels: - format: int64 - type: integer - optimize-filters-for-hits: - type: boolean - pin-l0-filter-and-index-blocks: - type: boolean - prop-keys-index-distance: - format: int64 - type: integer - prop-size-index-distance: - format: int64 - type: integer - read-amp-bytes-per-bit: - format: int64 - type: integer - soft-pending-compaction-bytes-limit: - type: string - target-file-size-base: - type: string - titan: - properties: - blob-cache-size: - type: string - blob-file-compression: - type: string - blob-run-mode: - type: string - discardable-ratio: - format: double - type: number - gc-merge-rewrite: - type: boolean - level_merge: - type: boolean - max-gc-batch-size: - type: string - merge-small-file-threshold: - type: string - min-blob-size: - type: string - min-gc-batch-size: - type: string - sample-ratio: - format: double - type: number - type: object - use-bloom-filter: - type: boolean - whole-key-filtering: - type: boolean - write-buffer-size: - type: string - type: object - rate-bytes-per-sec: - type: string - rate-limiter-mode: - format: int64 - type: integer - stats-dump-period: - type: string - titan: - properties: - dirname: - type: string - disable-gc: - type: boolean - enabled: - type: boolean - max-background-gc: - format: int64 - type: integer - purge-obsolete-files-period: - type: string - type: object - use-direct-io-for-flush-and-compaction: - type: boolean - wal-bytes-per-sync: - type: string - wal-recovery-mode: - format: int64 - type: integer - wal-size-limit: - type: string - wal-ttl-seconds: - format: int64 - type: integer - writable-file-max-buffer-size: - type: string - writecf: - properties: - block-based-bloom-filter: - type: boolean - block-cache-size: - type: string - block-size: - type: string - bloom-filter-bits-per-key: - format: int64 - type: integer - cache-index-and-filter-blocks: - type: boolean - compaction-pri: - format: int64 - type: integer - compaction-style: - format: int64 - type: integer - compression-per-level: - items: - type: string - type: array - disable-auto-compactions: - type: boolean - disable-block-cache: - type: boolean - dynamic-level-bytes: - type: boolean - enable-doubly-skiplist: - type: boolean - force-consistency-checks: - type: boolean - hard-pending-compaction-bytes-limit: - type: string - level0-file-num-compaction-trigger: - format: int64 - type: integer - level0-slowdown-writes-trigger: - format: int64 - type: integer - level0-stop-writes-trigger: - format: int64 - type: integer - max-bytes-for-level-base: - type: string - max-bytes-for-level-multiplier: - format: int64 - type: integer - max-compaction-bytes: - type: string - max-write-buffer-number: - format: int64 - type: integer - min-write-buffer-number-to-merge: - format: int64 - type: integer - num-levels: - format: int64 - type: integer - optimize-filters-for-hits: - type: boolean - pin-l0-filter-and-index-blocks: - type: boolean - prop-keys-index-distance: - format: int64 - type: integer - prop-size-index-distance: - format: int64 - type: integer - read-amp-bytes-per-bit: - format: int64 - type: integer - soft-pending-compaction-bytes-limit: - type: string - target-file-size-base: - type: string - titan: - properties: - blob-cache-size: - type: string - blob-file-compression: - type: string - blob-run-mode: - type: string - discardable-ratio: - format: double - type: number - gc-merge-rewrite: - type: boolean - level_merge: - type: boolean - max-gc-batch-size: - type: string - merge-small-file-threshold: - type: string - min-blob-size: - type: string - min-gc-batch-size: - type: string - sample-ratio: - format: double - type: number - type: object - use-bloom-filter: - type: boolean - whole-key-filtering: - type: boolean - write-buffer-size: - type: string - type: object - type: object - security: - properties: - ca-path: - type: string - cert-path: - type: string - cipher-file: - type: string - encryption: {} - key-path: - type: string - override-ssl-target: - type: string - type: object - server: - properties: - advertise-status-addr: - type: string - concurrent-recv-snap-limit: - format: int32 - type: integer - concurrent-send-snap-limit: - format: int32 - type: integer - enable-request-batch: - type: boolean - end-point-batch-row-limit: - format: int32 - type: integer - end-point-enable-batch-if-possible: - format: int32 - type: integer - end-point-recursion-limit: - format: int32 - type: integer - end-point-request-max-handle-duration: - type: string - end-point-stream-batch-row-limit: - format: int32 - type: integer - end-point-stream-channel-size: - format: int32 - type: integer - engine-addr: - type: string - grpc-compression-type: - type: string - grpc-concurrency: - format: int32 - type: integer - grpc-concurrent-stream: - format: int32 - type: integer - grpc-keepalive-time: - type: string - grpc-keepalive-timeout: - type: string - grpc-memory-pool-quota: - type: string - grpc-raft-conn-num: - format: int32 - type: integer - grpc-stream-initial-window-size: - type: string - heavy-load-threshold: - format: int32 - type: integer - heavy-load-wait-duration: - type: string - labels: - type: object - max-grpc-send-msg-len: - format: int32 - type: integer - request-batch-enable-cross-command: - type: boolean - request-batch-wait-duration: - type: string - snap-max-total-size: - type: string - snap-max-write-bytes-per-sec: - type: string - stats-concurrency: - format: int32 - type: integer - status-addr: - type: string - status-thread-pool-size: - type: string - type: object - storage: - properties: - block-cache: - properties: - capacity: - type: string - high-pri-pool-ratio: - format: double - type: number - memory-allocator: - type: string - num-shard-bits: - format: int64 - type: integer - shared: - type: boolean - strict-capacity-limit: - type: boolean - type: object - max-key-size: - format: int64 - type: integer - reserve-space: - type: string - scheduler-concurrency: - format: int64 - type: integer - scheduler-notify-capacity: - format: int64 - type: integer - scheduler-pending-write-threshold: - type: string - scheduler-worker-pool-size: - format: int64 - type: integer - type: object - type: object - type: object + config: {} configUpdateStrategy: type: string env: diff --git a/pkg/apis/pingcap/v1alpha1/openapi_generated.go b/pkg/apis/pingcap/v1alpha1/openapi_generated.go index 13653f7187..76246f1834 100644 --- a/pkg/apis/pingcap/v1alpha1/openapi_generated.go +++ b/pkg/apis/pingcap/v1alpha1/openapi_generated.go @@ -6917,7 +6917,7 @@ func schema_pkg_apis_pingcap_v1alpha1_TiFlashSpec(ref common.ReferenceCallback) "config": { SchemaProps: spec.SchemaProps{ Description: "Config is the Configuration of TiFlash", - Ref: ref("github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.TiFlashConfig"), + Ref: ref("github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.TiFlashConfigWraper"), }, }, "logTailer": { @@ -6938,7 +6938,7 @@ func schema_pkg_apis_pingcap_v1alpha1_TiFlashSpec(ref common.ReferenceCallback) }, }, Dependencies: []string{ - "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.LogTailerSpec", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.StorageClaim", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.TiFlashConfig", "k8s.io/api/core/v1.Affinity", "k8s.io/api/core/v1.Container", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.LocalObjectReference", "k8s.io/api/core/v1.PodSecurityContext", "k8s.io/api/core/v1.Toleration", "k8s.io/api/core/v1.Volume", "k8s.io/apimachinery/pkg/api/resource.Quantity"}, + "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.LogTailerSpec", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.StorageClaim", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.TiFlashConfigWraper", "k8s.io/api/core/v1.Affinity", "k8s.io/api/core/v1.Container", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.LocalObjectReference", "k8s.io/api/core/v1.PodSecurityContext", "k8s.io/api/core/v1.Toleration", "k8s.io/api/core/v1.Volume", "k8s.io/apimachinery/pkg/api/resource.Quantity"}, } } diff --git a/pkg/apis/pingcap/v1alpha1/tiflash_config_wraper.go b/pkg/apis/pingcap/v1alpha1/tiflash_config_wraper.go new file mode 100644 index 0000000000..2fec7ee017 --- /dev/null +++ b/pkg/apis/pingcap/v1alpha1/tiflash_config_wraper.go @@ -0,0 +1,118 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1alpha1 + +import ( + stdjson "encoding/json" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb-operator/pkg/util/config" + "k8s.io/apimachinery/pkg/util/json" +) + +type TiFlashConfigWraper struct { + Common *TiFlashCommonConfigWraper `json:"config,omitempty"` + Proxy *TiFlashProxyConfigWraper `json:"proxy,omitempty"` +} + +func NewTiFlashConfig() *TiFlashConfigWraper { + return &TiFlashConfigWraper{ + Common: NewTiFlashCommonConfig(), + Proxy: NewTiFlashProxyConfig(), + } +} + +var _ stdjson.Marshaler = &TiFlashCommonConfigWraper{} +var _ stdjson.Unmarshaler = &TiFlashCommonConfigWraper{} + +func NewTiFlashCommonConfig() *TiFlashCommonConfigWraper { + return &TiFlashCommonConfigWraper{ + GenericConfig: config.New(map[string]interface{}{}), + } +} + +type TiFlashCommonConfigWraper struct { + *config.GenericConfig +} + +// MarshalJSON implements stdjson.Marshaler interface. +func (c *TiFlashCommonConfigWraper) MarshalJSON() ([]byte, error) { + toml, err := c.GenericConfig.MarshalTOML() + if err != nil { + return nil, errors.AddStack(err) + } + + return json.Marshal(string(toml)) +} + +// UnmarshalJSON implements stdjson.Unmarshaler interface. +// If the data is a object, we must use the Deprecated TiFlashCommonConfig to Unmarshal +// for compatibility, if we use a map[string]interface{} to Unmarshal directly, +// we can not distinct the type between integer and float for toml. +func (c *TiFlashCommonConfigWraper) UnmarshalJSON(data []byte) error { + deprecated := new(CommonConfig) + var err error + c.GenericConfig, err = unmarshalJSON(data, deprecated) + return err +} + +func (c *TiFlashCommonConfigWraper) MarshalTOML() ([]byte, error) { + if c == nil { + return nil, nil + } + + return c.GenericConfig.MarshalTOML() +} + +var _ stdjson.Marshaler = &TiFlashProxyConfigWraper{} +var _ stdjson.Unmarshaler = &TiFlashProxyConfigWraper{} + +func NewTiFlashProxyConfig() *TiFlashProxyConfigWraper { + return &TiFlashProxyConfigWraper{ + GenericConfig: config.New(map[string]interface{}{}), + } +} + +type TiFlashProxyConfigWraper struct { + *config.GenericConfig +} + +// MarshalJSON implements stdjson.Marshaler interface. +func (c *TiFlashProxyConfigWraper) MarshalJSON() ([]byte, error) { + toml, err := c.GenericConfig.MarshalTOML() + if err != nil { + return nil, errors.AddStack(err) + } + + return json.Marshal(string(toml)) +} + +// UnmarshalJSON implements stdjson.Unmarshaler interface. +// If the data is a object, we must use the Deprecated TiFlashProxyConfig to Unmarshal +// for compatibility, if we use a map[string]interface{} to Unmarshal directly, +// we can not distinct the type between integer and float for toml. +func (c *TiFlashProxyConfigWraper) UnmarshalJSON(data []byte) error { + deprecated := new(ProxyConfig) + var err error + c.GenericConfig, err = unmarshalJSON(data, deprecated) + return err +} + +func (c *TiFlashProxyConfigWraper) MarshalTOML() ([]byte, error) { + if c == nil { + return nil, nil + } + + return c.GenericConfig.MarshalTOML() +} diff --git a/pkg/apis/pingcap/v1alpha1/tiflash_config_wraper_test.go b/pkg/apis/pingcap/v1alpha1/tiflash_config_wraper_test.go new file mode 100644 index 0000000000..ef1f8f018d --- /dev/null +++ b/pkg/apis/pingcap/v1alpha1/tiflash_config_wraper_test.go @@ -0,0 +1,174 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1alpha1 + +import ( + "encoding/json" + "strconv" + "testing" + + "github.com/google/go-cmp/cmp" + fuzz "github.com/google/gofuzz" + . "github.com/onsi/gomega" + "github.com/pingcap/tidb-operator/pkg/util/toml" + "sigs.k8s.io/yaml" +) + +func TestTiFlashCommonConfigWraper(t *testing.T) { + g := NewGomegaWithT(t) + + f := fuzz.New().Funcs( + // the toml pkg we use do support to unmarshal a value overflow int64 + // when unmarshal to go map[string]interface{ + // just set the value in uint32 range now for + func(e *uint64, c fuzz.Continue) { + *e = uint64(c.Uint32()) + }, + func(e *uint, c fuzz.Continue) { + *e = uint(c.Uint32()) + }, + + func(e *string, c fuzz.Continue) { + *e = "s" + strconv.Itoa(c.Intn(100)) + }, + ) + for i := 0; i < 100; i++ { + var config CommonConfig + f.Fuzz(&config) + + jsonData, err := json.Marshal(&config) + t.Logf("case %d json:\n%s", i, string(jsonData)) + g.Expect(err).Should(BeNil()) + + configWraper := NewTiFlashCommonConfig() + err = json.Unmarshal(jsonData, configWraper) + g.Expect(err).Should(BeNil()) + + tomlDataBack, err := configWraper.MarshalTOML() + t.Logf("case %d toml back:\n%s", i, string(tomlDataBack)) + g.Expect(err).Should(BeNil()) + + var configBack CommonConfig + err = toml.Unmarshal(tomlDataBack, &configBack) + g.Expect(err).Should(BeNil()) + if diff := cmp.Diff(config, configBack); diff != "" { + t.Errorf("unexpected plugin configuration (-want, +got): %s", diff) + t.FailNow() + } + } +} + +func TestTiFlashProxyConfigWraper(t *testing.T) { + g := NewGomegaWithT(t) + + f := fuzz.New().Funcs( + // the toml pkg we use do support to unmarshal a value overflow int64 + // when unmarshal to go map[string]interface{ + // just set the value in uint32 range now for + func(e *uint64, c fuzz.Continue) { + *e = uint64(c.Uint32()) + }, + func(e *uint, c fuzz.Continue) { + *e = uint(c.Uint32()) + }, + + func(e *string, c fuzz.Continue) { + *e = "s" + strconv.Itoa(c.Intn(100)) + }, + ) + for i := 0; i < 100; i++ { + var config ProxyConfig + f.Fuzz(&config) + + jsonData, err := json.Marshal(&config) + t.Logf("case %d json:\n%s", i, string(jsonData)) + g.Expect(err).Should(BeNil()) + + configWraper := NewTiFlashProxyConfig() + err = json.Unmarshal(jsonData, configWraper) + g.Expect(err).Should(BeNil()) + + tomlDataBack, err := configWraper.MarshalTOML() + t.Logf("case %d toml back:\n%s", i, string(tomlDataBack)) + g.Expect(err).Should(BeNil()) + + var configBack ProxyConfig + err = toml.Unmarshal(tomlDataBack, &configBack) + g.Expect(err).Should(BeNil()) + if diff := cmp.Diff(config, configBack); diff != "" { + t.Errorf("unexpected plugin configuration (-want, +got): %s", diff) + t.FailNow() + } + } +} + +func TestTiFlashConfigToml(t *testing.T) { + var data = []byte(`tiflash: + config: + config: | + [logger] + level = "warn" + count = 9 + proxy: | + log-level = "warn" + [gc] + batch-keys = 501 +`) + + g := NewGomegaWithT(t) + var err error + data, err = yaml.YAMLToJSON(data) + g.Expect(err).Should(BeNil()) + + tc := &TidbClusterSpec{} + err = json.Unmarshal(data, tc) + g.Expect(err).Should(BeNil()) + + config := tc.TiFlash.Config + g.Expect(config.Common.Get("logger.level").MustString()).Should(Equal("warn")) + g.Expect(config.Common.Get("logger.count").MustInt()).Should(Equal(int64(9))) + g.Expect(config.Proxy.Get("log-level").MustString()).Should(Equal("warn")) + g.Expect(config.Proxy.Get("gc.batch-keys").MustInt()).Should(Equal(int64(501))) +} + +func TestTiFlashConfigJson(t *testing.T) { + var data = []byte(`tiflash: + config: + config: + logger: + level: warn + count: 9 + proxy: + log-level: warn + gc: + batch-keys: 501 +`) + + t.Log(string(data)) + + g := NewGomegaWithT(t) + var err error + data, err = yaml.YAMLToJSON(data) + g.Expect(err).Should(BeNil()) + + tc := &TidbClusterSpec{} + err = json.Unmarshal(data, tc) + g.Expect(err).Should(BeNil()) + + config := tc.TiFlash.Config + g.Expect(config.Common.Get("logger.level").MustString()).Should(Equal("warn")) + g.Expect(config.Common.Get("logger.count").MustInt()).Should(Equal(int64(9))) + g.Expect(config.Proxy.Get("log-level").MustString()).Should(Equal("warn")) + g.Expect(config.Proxy.Get("gc.batch-keys").MustInt()).Should(Equal(int64(501))) +} diff --git a/pkg/apis/pingcap/v1alpha1/types.go b/pkg/apis/pingcap/v1alpha1/types.go index 27c38c3da0..b04c52d6f7 100644 --- a/pkg/apis/pingcap/v1alpha1/types.go +++ b/pkg/apis/pingcap/v1alpha1/types.go @@ -464,7 +464,7 @@ type TiFlashSpec struct { // Config is the Configuration of TiFlash // +optional - Config *TiFlashConfig `json:"config,omitempty"` + Config *TiFlashConfigWraper `json:"config,omitempty"` // LogTailer is the configurations of the log tailers for TiFlash // +optional diff --git a/pkg/apis/pingcap/v1alpha1/validation/validation.go b/pkg/apis/pingcap/v1alpha1/validation/validation.go index 2c6f42a532..b1f02f403e 100644 --- a/pkg/apis/pingcap/v1alpha1/validation/validation.go +++ b/pkg/apis/pingcap/v1alpha1/validation/validation.go @@ -146,65 +146,54 @@ func validateTiCDCSpec(spec *v1alpha1.TiCDCSpec, fldPath *field.Path) field.Erro return allErrs } -func validateTiFlashConfig(config *v1alpha1.TiFlashConfig, path *field.Path) field.ErrorList { +func validateTiFlashConfig(config *v1alpha1.TiFlashConfigWraper, path *field.Path) field.ErrorList { allErrs := field.ErrorList{} if config == nil { return allErrs } - if config.CommonConfig != nil { - if config.CommonConfig.Flash != nil { - if config.CommonConfig.Flash.OverlapThreshold != nil { - if *config.CommonConfig.Flash.OverlapThreshold < 0 || *config.CommonConfig.Flash.OverlapThreshold > 1 { + if config.Common != nil { + if v := config.Common.Get("flash.overlap_threshold"); v != nil { + if value, err := v.AsFloat(); err == nil { + if value < 0 || value > 1 { allErrs = append(allErrs, field.Invalid(path.Child("config.config.flash.overlap_threshold"), - config.CommonConfig.Flash.OverlapThreshold, + value, "overlap_threshold must be in the range of [0,1].")) } + } else { + allErrs = append(allErrs, field.Invalid(path.Child("config.config.flash.overlap_threshold"), + v.Interface(), + fmt.Sprintf("should be float type, but is: %v", reflect.TypeOf(v.Interface())), + )) } - if config.CommonConfig.Flash.FlashCluster != nil { - if config.CommonConfig.Flash.FlashCluster.ClusterLog != nil { - splitPath := strings.Split(*config.CommonConfig.Flash.FlashCluster.ClusterLog, string(os.PathSeparator)) - // The log path should be at least /dir/base.log - if len(splitPath) < 3 { - allErrs = append(allErrs, field.Invalid(path.Child("config.config.flash.flash_cluster.log"), - config.CommonConfig.Flash.FlashCluster.ClusterLog, - "log path should include at least one level dir.")) - } - } - } - if config.CommonConfig.Flash.FlashProxy != nil { - if config.CommonConfig.Flash.FlashProxy.LogFile != nil { - splitPath := strings.Split(*config.CommonConfig.Flash.FlashProxy.LogFile, string(os.PathSeparator)) + } + + var fields = []string{ + "flash.flash_cluster.log", + "flash.proxy.log-file", + "logger.log", + "logger.errorlog", + } + for _, pathField := range fields { + if v := config.Common.Get(pathField); v != nil { + if value, err := v.AsString(); err == nil { + splitPath := strings.Split(value, string(os.PathSeparator)) // The log path should be at least /dir/base.log if len(splitPath) < 3 { - allErrs = append(allErrs, field.Invalid(path.Child("config.config.flash.flash_proxy.log-file"), - config.CommonConfig.Flash.FlashProxy.LogFile, + allErrs = append(allErrs, field.Invalid(path.Child("config.config."+pathField), + value, "log path should include at least one level dir.")) } - } - } - } - if config.CommonConfig.FlashLogger != nil { - if config.CommonConfig.FlashLogger.ServerLog != nil { - splitPath := strings.Split(*config.CommonConfig.FlashLogger.ServerLog, string(os.PathSeparator)) - // The log path should be at least /dir/base.log - if len(splitPath) < 3 { - allErrs = append(allErrs, field.Invalid(path.Child("config.config.logger.log"), - config.CommonConfig.FlashLogger.ServerLog, - "log path should include at least one level dir.")) - } - } - if config.CommonConfig.FlashLogger.ErrorLog != nil { - splitPath := strings.Split(*config.CommonConfig.FlashLogger.ErrorLog, string(os.PathSeparator)) - // The log path should be at least /dir/base.log - if len(splitPath) < 3 { - allErrs = append(allErrs, field.Invalid(path.Child("config.config.logger.errorlog"), - config.CommonConfig.FlashLogger.ErrorLog, - "log path should include at least one level dir.")) + } else { + allErrs = append(allErrs, field.Invalid(path.Child("config.config"+pathField), + v.Interface(), + fmt.Sprintf("should be string type, but is: %v", reflect.TypeOf(v.Interface())), + )) } } } } + return allErrs } diff --git a/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go index c6b4206d03..c0620ac09d 100644 --- a/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go @@ -4957,6 +4957,26 @@ func (in *TiDBTLSClient) DeepCopy() *TiDBTLSClient { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TiFlashCommonConfigWraper) DeepCopyInto(out *TiFlashCommonConfigWraper) { + *out = *in + if in.GenericConfig != nil { + in, out := &in.GenericConfig, &out.GenericConfig + *out = (*in).DeepCopy() + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TiFlashCommonConfigWraper. +func (in *TiFlashCommonConfigWraper) DeepCopy() *TiFlashCommonConfigWraper { + if in == nil { + return nil + } + out := new(TiFlashCommonConfigWraper) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TiFlashConfig) DeepCopyInto(out *TiFlashConfig) { *out = *in @@ -4983,6 +5003,52 @@ func (in *TiFlashConfig) DeepCopy() *TiFlashConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TiFlashConfigWraper) DeepCopyInto(out *TiFlashConfigWraper) { + *out = *in + if in.Common != nil { + in, out := &in.Common, &out.Common + *out = new(TiFlashCommonConfigWraper) + (*in).DeepCopyInto(*out) + } + if in.Proxy != nil { + in, out := &in.Proxy, &out.Proxy + *out = new(TiFlashProxyConfigWraper) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TiFlashConfigWraper. +func (in *TiFlashConfigWraper) DeepCopy() *TiFlashConfigWraper { + if in == nil { + return nil + } + out := new(TiFlashConfigWraper) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TiFlashProxyConfigWraper) DeepCopyInto(out *TiFlashProxyConfigWraper) { + *out = *in + if in.GenericConfig != nil { + in, out := &in.GenericConfig, &out.GenericConfig + *out = (*in).DeepCopy() + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TiFlashProxyConfigWraper. +func (in *TiFlashProxyConfigWraper) DeepCopy() *TiFlashProxyConfigWraper { + if in == nil { + return nil + } + out := new(TiFlashProxyConfigWraper) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TiFlashSpec) DeepCopyInto(out *TiFlashSpec) { *out = *in @@ -5007,7 +5073,7 @@ func (in *TiFlashSpec) DeepCopyInto(out *TiFlashSpec) { } if in.Config != nil { in, out := &in.Config, &out.Config - *out = new(TiFlashConfig) + *out = new(TiFlashConfigWraper) (*in).DeepCopyInto(*out) } if in.LogTailer != nil { diff --git a/pkg/manager/member/pd_member_manager.go b/pkg/manager/member/pd_member_manager.go index 947b0aa19a..1115e70fe4 100644 --- a/pkg/manager/member/pd_member_manager.go +++ b/pkg/manager/member/pd_member_manager.go @@ -394,7 +394,10 @@ func (pmm *pdMemberManager) syncPDConfigMap(tc *v1alpha1.TidbCluster, set *apps. }) } - updateConfigMapIfNeed(pmm.deps.ConfigMapLister, tc.BaseTiDBSpec().ConfigUpdateStrategy(), inUseName, newCm) + err = updateConfigMapIfNeed(pmm.deps.ConfigMapLister, tc.BaseTiDBSpec().ConfigUpdateStrategy(), inUseName, newCm) + if err != nil { + return nil, err + } return pmm.deps.TypedControl.CreateOrUpdateConfigMap(tc, newCm) } diff --git a/pkg/manager/member/pump_member_manager.go b/pkg/manager/member/pump_member_manager.go index 1d938caf77..88cf8a40cc 100644 --- a/pkg/manager/member/pump_member_manager.go +++ b/pkg/manager/member/pump_member_manager.go @@ -183,19 +183,18 @@ func (pmm *pumpMemberManager) syncConfigMap(tc *v1alpha1.TidbCluster, set *appsv if err != nil { return nil, err } - // In-place update should pick the name of currently in-use configmap if exists to avoid rolling-update if: - // - user switch strategy from RollingUpdate to In-place - // - the statefulset and configmap is created by other clients (e.g. helm) - if set != nil && basePumpSpec.ConfigUpdateStrategy() == v1alpha1.ConfigUpdateStrategyInPlace { - inUseName := FindConfigMapVolume(&set.Spec.Template.Spec, func(name string) bool { + + var inUseName string + if set != nil { + inUseName = FindConfigMapVolume(&set.Spec.Template.Spec, func(name string) bool { return strings.HasPrefix(name, controller.PumpMemberName(tc.Name)) }) - // find an in-use configmap, will update it in-place - if inUseName != "" { - newCm.Name = inUseName - } } + err = updateConfigMapIfNeed(pmm.deps.ConfigMapLister, basePumpSpec.ConfigUpdateStrategy(), inUseName, newCm) + if err != nil { + return nil, err + } return pmm.deps.TypedControl.CreateOrUpdateConfigMap(tc, newCm) } @@ -227,7 +226,7 @@ func getNewPumpHeadlessService(tc *v1alpha1.TidbCluster) *corev1.Service { // getNewPumpConfigMap returns a configMap for pump func getNewPumpConfigMap(tc *v1alpha1.TidbCluster) (*corev1.ConfigMap, error) { - basePumpSpec, createPump := tc.BasePumpSpec() + _, createPump := tc.BasePumpSpec() if !createPump { return nil, nil } @@ -256,14 +255,6 @@ func getNewPumpConfigMap(tc *v1alpha1.TidbCluster) (*corev1.ConfigMap, error) { "pump-config": confTextStr, } - if basePumpSpec.ConfigUpdateStrategy() == v1alpha1.ConfigUpdateStrategyRollingUpdate { - sum, err := Sha256Sum(data) - if err != nil { - return nil, err - } - suffix := fmt.Sprintf("%x", sum)[0:7] - name = fmt.Sprintf("%s-%s", name, suffix) - } objMeta.Name = name return &corev1.ConfigMap{ diff --git a/pkg/manager/member/tidb_member_manager.go b/pkg/manager/member/tidb_member_manager.go index 5810c5d551..850587afda 100644 --- a/pkg/manager/member/tidb_member_manager.go +++ b/pkg/manager/member/tidb_member_manager.go @@ -333,7 +333,10 @@ func (tmm *tidbMemberManager) syncTiDBConfigMap(tc *v1alpha1.TidbCluster, set *a klog.V(3).Info("get tidb in use config map name: ", inUseName) - updateConfigMapIfNeed(tmm.deps.ConfigMapLister, tc.BaseTiDBSpec().ConfigUpdateStrategy(), inUseName, newCm) + err = updateConfigMapIfNeed(tmm.deps.ConfigMapLister, tc.BaseTiDBSpec().ConfigUpdateStrategy(), inUseName, newCm) + if err != nil { + return nil, err + } return tmm.deps.TypedControl.CreateOrUpdateConfigMap(tc, newCm) } diff --git a/pkg/manager/member/tiflash_member_manager.go b/pkg/manager/member/tiflash_member_manager.go index 35f7c36381..6d63ac754b 100644 --- a/pkg/manager/member/tiflash_member_manager.go +++ b/pkg/manager/member/tiflash_member_manager.go @@ -238,15 +238,18 @@ func (tfmm *tiflashMemberManager) syncConfigMap(tc *v1alpha1.TidbCluster, set *a if err != nil { return nil, err } - if set != nil && tc.BaseTiFlashSpec().ConfigUpdateStrategy() == v1alpha1.ConfigUpdateStrategyInPlace { - inUseName := FindConfigMapVolume(&set.Spec.Template.Spec, func(name string) bool { + + var inUseName string + if set != nil { + inUseName = FindConfigMapVolume(&set.Spec.Template.Spec, func(name string) bool { return strings.HasPrefix(name, controller.TiFlashMemberName(tc.Name)) }) - if inUseName != "" { - newCm.Name = inUseName - } } + err = updateConfigMapIfNeed(tfmm.deps.ConfigMapLister, tc.BaseTiDBSpec().ConfigUpdateStrategy(), inUseName, newCm) + if err != nil { + return nil, err + } return tfmm.deps.TypedControl.CreateOrUpdateConfigMap(tc, newCm) } @@ -501,7 +504,11 @@ func getNewStatefulSet(tc *v1alpha1.TidbCluster, cm *corev1.ConfigMap) (*apps.St podSpec.Volumes = append(vols, baseTiFlashSpec.AdditionalVolumes()...) podSpec.SecurityContext = podSecurityContext podSpec.InitContainers = initContainers - podSpec.Containers = append([]corev1.Container{tiflashContainer}, buildTiFlashSidecarContainers(tc)...) + containers, err := buildTiFlashSidecarContainers(tc) + if err != nil { + return nil, err + } + podSpec.Containers = append([]corev1.Container{tiflashContainer}, containers...) podSpec.Containers = append(podSpec.Containers, baseTiFlashSpec.AdditionalContainers()...) podSpec.ServiceAccountName = tc.Spec.TiFlash.ServiceAccount if podSpec.ServiceAccountName == "" { @@ -561,11 +568,11 @@ func flashVolumeClaimTemplate(storageClaims []v1alpha1.StorageClaim) ([]corev1.P func getTiFlashConfigMap(tc *v1alpha1.TidbCluster) (*corev1.ConfigMap, error) { config := getTiFlashConfig(tc) - configText, err := MarshalTOML(config.CommonConfig) + configText, err := config.Common.MarshalTOML() if err != nil { return nil, err } - proxyText, err := MarshalTOML(config.ProxyConfig) + proxyText, err := config.Proxy.MarshalTOML() if err != nil { return nil, err } @@ -585,12 +592,6 @@ func getTiFlashConfigMap(tc *v1alpha1.TidbCluster) (*corev1.ConfigMap, error) { }, } - if tc.BaseTiFlashSpec().ConfigUpdateStrategy() == v1alpha1.ConfigUpdateStrategyRollingUpdate { - if err := AddConfigMapDigestSuffix(cm); err != nil { - return nil, err - } - } - return cm, nil } diff --git a/pkg/manager/member/tiflash_util.go b/pkg/manager/member/tiflash_util.go index c56ef008da..89afea2a24 100644 --- a/pkg/manager/member/tiflash_util.go +++ b/pkg/manager/member/tiflash_util.go @@ -22,7 +22,6 @@ import ( "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1" "github.com/pingcap/tidb-operator/pkg/controller" corev1 "k8s.io/api/core/v1" - "k8s.io/utils/pointer" ) const ( @@ -31,7 +30,7 @@ const ( defaultServerLog = "/data0/logs/server.log" ) -func buildTiFlashSidecarContainers(tc *v1alpha1.TidbCluster) []corev1.Container { +func buildTiFlashSidecarContainers(tc *v1alpha1.TidbCluster) ([]corev1.Container, error) { spec := tc.Spec.TiFlash config := spec.Config.DeepCopy() image := tc.HelperImage() @@ -42,13 +41,26 @@ func buildTiFlashSidecarContainers(tc *v1alpha1.TidbCluster) []corev1.Container resource = controller.ContainerResource(spec.LogTailer.ResourceRequirements) } if config == nil { - config = &v1alpha1.TiFlashConfig{} + config = v1alpha1.NewTiFlashConfig() } setTiFlashLogConfigDefault(config) - containers = append(containers, buildSidecarContainer("serverlog", *config.CommonConfig.FlashLogger.ServerLog, image, pullPolicy, resource)) - containers = append(containers, buildSidecarContainer("errorlog", *config.CommonConfig.FlashLogger.ErrorLog, image, pullPolicy, resource)) - containers = append(containers, buildSidecarContainer("clusterlog", *config.CommonConfig.Flash.FlashCluster.ClusterLog, image, pullPolicy, resource)) - return containers + + path, err := config.Common.Get("logger.log").AsString() + if err != nil { + return nil, err + } + containers = append(containers, buildSidecarContainer("serverlog", path, image, pullPolicy, resource)) + path, err = config.Common.Get("logger.errorlog").AsString() + if err != nil { + return nil, err + } + containers = append(containers, buildSidecarContainer("errorlog", path, image, pullPolicy, resource)) + path, err = config.Common.Get("flash.flash_cluster.log").AsString() + if err != nil { + return nil, err + } + containers = append(containers, buildSidecarContainer("clusterlog", path, image, pullPolicy, resource)) + return containers, nil } func buildSidecarContainer(name, path, image string, @@ -87,23 +99,24 @@ func buildSidecarContainer(name, path, image string, } } -func getTiFlashConfig(tc *v1alpha1.TidbCluster) *v1alpha1.TiFlashConfig { +func getTiFlashConfig(tc *v1alpha1.TidbCluster) *v1alpha1.TiFlashConfigWraper { config := tc.Spec.TiFlash.Config.DeepCopy() if config == nil { - config = &v1alpha1.TiFlashConfig{} + config = v1alpha1.NewTiFlashConfig() } - if config.CommonConfig == nil { - config.CommonConfig = &v1alpha1.CommonConfig{} + if config.Common == nil { + config.Common = v1alpha1.NewTiFlashCommonConfig() } - if config.CommonConfig.FlashDataPath == nil { + + if config.Common.Get("path") == nil { var paths []string for k := range tc.Spec.TiFlash.StorageClaims { paths = append(paths, fmt.Sprintf("/data%d/db", k)) } if len(paths) > 0 { dataPath := strings.Join(paths, ",") - config.CommonConfig.FlashDataPath = pointer.StringPtr(dataPath) + config.Common.Set("path", dataPath) } } @@ -113,379 +126,150 @@ func getTiFlashConfig(tc *v1alpha1.TidbCluster) *v1alpha1.TiFlashConfig { setTiFlashConfigDefault(config, "", tc.Name, tc.Namespace) } + // Note the config of tiflash use "_" by convention, others(proxy) use "-". if tc.IsTLSClusterEnabled() { - if config.CommonConfig.Security == nil { - config.CommonConfig.Security = &v1alpha1.FlashSecurity{} - } - if config.ProxyConfig.Security == nil { - config.ProxyConfig.Security = &v1alpha1.TiKVSecurityConfig{} - } - config.ProxyConfig.Security.CAPath = pointer.StringPtr(path.Join(tiflashCertPath, corev1.ServiceAccountRootCAKey)) - config.ProxyConfig.Security.CertPath = pointer.StringPtr(path.Join(tiflashCertPath, corev1.TLSCertKey)) - config.ProxyConfig.Security.KeyPath = pointer.StringPtr(path.Join(tiflashCertPath, corev1.TLSPrivateKeyKey)) - config.CommonConfig.Security.CAPath = pointer.StringPtr(path.Join(tiflashCertPath, corev1.ServiceAccountRootCAKey)) - config.CommonConfig.Security.CertPath = pointer.StringPtr(path.Join(tiflashCertPath, corev1.TLSCertKey)) - config.CommonConfig.Security.KeyPath = pointer.StringPtr(path.Join(tiflashCertPath, corev1.TLSPrivateKeyKey)) - if len(config.CommonConfig.Security.CertAllowedCN) > 0 && len(config.ProxyConfig.Security.CertAllowedCN) == 0 { - config.ProxyConfig.Security.CertAllowedCN = config.CommonConfig.Security.CertAllowedCN + config.Proxy.Set("security.ca-path", path.Join(tiflashCertPath, corev1.ServiceAccountRootCAKey)) + config.Proxy.Set("security.cert-path", path.Join(tiflashCertPath, corev1.TLSCertKey)) + config.Proxy.Set("security.key-path", path.Join(tiflashCertPath, corev1.TLSPrivateKeyKey)) + config.Common.Set("security.ca_path", path.Join(tiflashCertPath, corev1.ServiceAccountRootCAKey)) + config.Common.Set("security.cert_path", path.Join(tiflashCertPath, corev1.TLSCertKey)) + config.Common.Set("security.key_path", path.Join(tiflashCertPath, corev1.TLSPrivateKeyKey)) + + common := config.Common.Get("security.cert_allowed_cn") + proxy := config.Proxy.Get("security.cert-allowed-cn") + if common != nil && proxy == nil { + config.Proxy.Set("security.cert-allowed-cn", common.Interface()) } + // unset the http ports - config.CommonConfig.HTTPPort = nil - config.CommonConfig.TCPPort = nil + config.Common.Del("http_port") + config.Common.Del("tcp_port") } else { // unset the https ports - config.CommonConfig.HTTPSPort = nil - config.CommonConfig.TCPPortSecure = nil + config.Common.Del("https_port") + config.Common.Del("tcp_port_secure") } + return config } -func setTiFlashLogConfigDefault(config *v1alpha1.TiFlashConfig) { - if config.CommonConfig == nil { - config.CommonConfig = &v1alpha1.CommonConfig{} - } - if config.CommonConfig.Flash == nil { - config.CommonConfig.Flash = &v1alpha1.Flash{} - } - if config.CommonConfig.Flash.FlashCluster == nil { - config.CommonConfig.Flash.FlashCluster = &v1alpha1.FlashCluster{} - } - if config.CommonConfig.Flash.FlashCluster.ClusterLog == nil { - config.CommonConfig.Flash.FlashCluster.ClusterLog = pointer.StringPtr(defaultClusterLog) - } - if config.CommonConfig.Flash.FlashProxy == nil { - config.CommonConfig.Flash.FlashProxy = &v1alpha1.FlashProxy{} - } - - if config.CommonConfig.FlashLogger == nil { - config.CommonConfig.FlashLogger = &v1alpha1.FlashLogger{} - } - if config.CommonConfig.FlashLogger.ErrorLog == nil { - config.CommonConfig.FlashLogger.ErrorLog = pointer.StringPtr(defaultErrorLog) - } - if config.CommonConfig.FlashLogger.ServerLog == nil { - config.CommonConfig.FlashLogger.ServerLog = pointer.StringPtr(defaultServerLog) +func setTiFlashLogConfigDefault(config *v1alpha1.TiFlashConfigWraper) { + if config.Common == nil { + config.Common = v1alpha1.NewTiFlashCommonConfig() } + config.Common.SetIfNil("flash.flash_cluster.log", defaultClusterLog) + config.Common.SetIfNil("logger.errorlog", defaultErrorLog) + config.Common.SetIfNil("logger.log", defaultServerLog) } // setTiFlashConfigDefault sets default configs for TiFlash -func setTiFlashConfigDefault(config *v1alpha1.TiFlashConfig, externalClusterName, clusterName, ns string) { - if config.CommonConfig == nil { - config.CommonConfig = &v1alpha1.CommonConfig{} +func setTiFlashConfigDefault(config *v1alpha1.TiFlashConfigWraper, externalClusterName, clusterName, ns string) { + if config.Common == nil { + config.Common = v1alpha1.NewTiFlashCommonConfig() } - setTiFlashCommonConfigDefault(config.CommonConfig, externalClusterName, clusterName, ns) - if config.ProxyConfig == nil { - config.ProxyConfig = &v1alpha1.ProxyConfig{} - } - setTiFlashProxyConfigDefault(config.ProxyConfig, clusterName, ns) -} + setTiFlashCommonConfigDefault(config.Common, externalClusterName, clusterName, ns) -func setTiFlashProxyConfigDefault(config *v1alpha1.ProxyConfig, clusterName, ns string) { - if config.LogLevel == nil { - config.LogLevel = pointer.StringPtr("info") - } - if config.Server == nil { - config.Server = &v1alpha1.FlashServerConfig{} - } - if config.Server.EngineAddr == nil { - config.Server.EngineAddr = pointer.StringPtr(fmt.Sprintf("%s-POD_NUM.%s.%s.svc:3930", controller.TiFlashMemberName(clusterName), controller.TiFlashPeerMemberName(clusterName), ns)) - } - if config.Server.StatusAddr == nil { - config.Server.StatusAddr = pointer.StringPtr("0.0.0.0:20292") - } - if config.Server.AdvertiseStatusAddr == nil { - config.Server.AdvertiseStatusAddr = pointer.StringPtr(fmt.Sprintf("%s-POD_NUM.%s.%s.svc:20292", controller.TiFlashMemberName(clusterName), controller.TiFlashPeerMemberName(clusterName), ns)) + if config.Proxy == nil { + config.Proxy = v1alpha1.NewTiFlashProxyConfig() } + setTiFlashProxyConfigDefault(config.Proxy, clusterName, ns) } -func setTiFlashCommonConfigDefault(config *v1alpha1.CommonConfig, externalClusterName string, clusterName, ns string) { - if config.TmpPath == nil { - config.TmpPath = pointer.StringPtr("/data0/tmp") - } - if config.DisplayName == nil { - config.DisplayName = pointer.StringPtr("TiFlash") - } - if config.DefaultProfile == nil { - config.DefaultProfile = pointer.StringPtr("default") - } - if config.FlashDataPath == nil { - config.FlashDataPath = pointer.StringPtr("/data0/db") - } - if config.PathRealtimeMode == nil { - b := false - config.PathRealtimeMode = &b - } - if config.MarkCacheSize == nil { - var m int64 = 5368709120 - config.MarkCacheSize = &m - } - if config.MinmaxIndexCacheSize == nil { - var m int64 = 5368709120 - config.MinmaxIndexCacheSize = &m - } - if config.ListenHost == nil { - config.ListenHost = pointer.StringPtr("0.0.0.0") - } - if config.TCPPort == nil { - var p int32 = 9000 - config.TCPPort = &p - } - if config.TCPPortSecure == nil { - var p int32 = 9000 - config.TCPPortSecure = &p - } - if config.HTTPSPort == nil { - var p int32 = 8123 - config.HTTPSPort = &p - } - if config.HTTPPort == nil { - var p int32 = 8123 - config.HTTPPort = &p - } - if config.InternalServerHTTPPort == nil { - var p int32 = 9009 - config.InternalServerHTTPPort = &p - } - if config.Flash == nil { - config.Flash = &v1alpha1.Flash{} - } - setTiFlashFlashConfigDefault(config.Flash, externalClusterName, clusterName, ns) - if config.FlashLogger == nil { - config.FlashLogger = &v1alpha1.FlashLogger{} - } - setTiFlashLoggerConfigDefault(config.FlashLogger) - if config.FlashApplication == nil { - config.FlashApplication = &v1alpha1.FlashApplication{} - } - setTiFlashApplicationConfigDefault(config.FlashApplication) - if config.FlashRaft == nil { - config.FlashRaft = &v1alpha1.FlashRaft{} - } +func setTiFlashProxyConfigDefault(config *v1alpha1.TiFlashProxyConfigWraper, clusterName, ns string) { + config.SetIfNil("log-level", "info") + config.SetIfNil("server.engine-addr", fmt.Sprintf("%s-POD_NUM.%s.%s.svc:3930", controller.TiFlashMemberName(clusterName), controller.TiFlashPeerMemberName(clusterName), ns)) + config.SetIfNil("server.status-addr", "0.0.0.0:20292") + config.SetIfNil("server.advertise-status-addr", fmt.Sprintf("%s-POD_NUM.%s.%s.svc:20292", controller.TiFlashMemberName(clusterName), controller.TiFlashPeerMemberName(clusterName), ns)) +} +func setTiFlashCommonConfigDefault(config *v1alpha1.TiFlashCommonConfigWraper, externalClusterName string, clusterName, ns string) { + config.SetIfNil("tmp_path", "/data0/tmp") + config.SetIfNil("display_name", "TiFlash") + config.SetIfNil("default_profile", "default") + config.SetIfNil("path", "/data0/db") + config.SetIfNil("path_realtime_mode", false) + config.SetIfNil("mark_cache_size", int64(5368709120)) + config.SetIfNil("minmax_index_cache_size", int64(5368709120)) + config.SetIfNil("listen_host", "0.0.0.0") + config.SetIfNil("tcp_port", int64(9000)) + config.SetIfNil("tcp_port_secure", int64(9000)) + config.SetIfNil("https_port", int64(8123)) + config.SetIfNil("http_port", int64(8123)) + config.SetIfNil("interserver_http_port", int64(9009)) + setTiFlashFlashConfigDefault(config, externalClusterName, clusterName, ns) + setTiFlashLoggerConfigDefault(config) + setTiFlashApplicationConfigDefault(config) if len(externalClusterName) > 0 { - setTiFlashRaftConfigDefault(config.FlashRaft, externalClusterName, ns) + setTiFlashRaftConfigDefault(config, externalClusterName, ns) } else { - setTiFlashRaftConfigDefault(config.FlashRaft, clusterName, ns) + setTiFlashRaftConfigDefault(config, clusterName, ns) } - if config.FlashStatus == nil { - config.FlashStatus = &v1alpha1.FlashStatus{} - } - setTiFlashStatusConfigDefault(config.FlashStatus) - if config.FlashQuota == nil { - config.FlashQuota = &v1alpha1.FlashQuota{} - } - setTiFlashQuotasConfigDefault(config.FlashQuota) - if config.FlashUser == nil { - config.FlashUser = &v1alpha1.FlashUser{} - } - setTiFlashUsersConfigDefault(config.FlashUser) - if config.FlashProfile == nil { - config.FlashProfile = &v1alpha1.FlashProfile{} - } - setTiFlashProfilesConfigDefault(config.FlashProfile) -} + config.SetIfNil("status.metrics_port", int64(8234)) -func setTiFlashFlashConfigDefault(config *v1alpha1.Flash, externalClusterName string, clusterName, ns string) { - if config.TiDBStatusAddr == nil { - if len(externalClusterName) > 0 { - config.TiDBStatusAddr = pointer.StringPtr(fmt.Sprintf("%s.%s.svc:10080", controller.TiDBMemberName(externalClusterName), ns)) - } else { - config.TiDBStatusAddr = pointer.StringPtr(fmt.Sprintf("%s.%s.svc:10080", controller.TiDBMemberName(clusterName), ns)) - } - } - if config.ServiceAddr == nil { - config.ServiceAddr = pointer.StringPtr("0.0.0.0:3930") - } - if config.OverlapThreshold == nil { - o := 0.6 - config.OverlapThreshold = &o - } - if config.CompactLogMinPeriod == nil { - var o int32 = 200 - config.CompactLogMinPeriod = &o - } - if config.FlashCluster == nil { - config.FlashCluster = &v1alpha1.FlashCluster{} - } - setTiFlashFlashClusterConfigDefault(config.FlashCluster) - if config.FlashProxy == nil { - config.FlashProxy = &v1alpha1.FlashProxy{} - } - setTiFlashFlashProxyConfigDefault(config.FlashProxy, clusterName, ns) -} + config.SetIfNil("quotas.default.interval.duration", int64(3600)) + config.SetIfNil("quotas.default.interval.queries", int64(0)) + config.SetIfNil("quotas.default.interval.errors", int64(0)) + config.SetIfNil("quotas.default.interval.result_rows", int64(0)) + config.SetIfNil("quotas.default.interval.read_rows", int64(0)) + config.SetIfNil("quotas.default.interval.execution_time", int64(0)) -func setTiFlashFlashProxyConfigDefault(config *v1alpha1.FlashProxy, clusterName, ns string) { - if config.Addr == nil { - config.Addr = pointer.StringPtr("0.0.0.0:20170") - } - if config.AdvertiseAddr == nil { - config.AdvertiseAddr = pointer.StringPtr(fmt.Sprintf("%s-POD_NUM.%s.%s.svc:20170", controller.TiFlashMemberName(clusterName), controller.TiFlashPeerMemberName(clusterName), ns)) - } - if config.DataDir == nil { - config.DataDir = pointer.StringPtr("/data0/proxy") - } - if config.Config == nil { - config.Config = pointer.StringPtr("/data0/proxy.toml") - } -} + config.SetIfNil("users.readonly.profile", "readonly") + config.SetIfNil("users.readonly.quota", "default") + config.SetIfNil("users.readonly.networks.ip", "::/0") + config.SetIfNil("users.readonly.password", "") + config.SetIfNil("users.default.profile", "default") + config.SetIfNil("users.default.quota", "default") + config.SetIfNil("users.default.networks.ip", "::/0") + config.SetIfNil("users.default.password", "") -func setTiFlashFlashClusterConfigDefault(config *v1alpha1.FlashCluster) { - if config.ClusterManagerPath == nil { - config.ClusterManagerPath = pointer.StringPtr("/tiflash/flash_cluster_manager") - } - if config.ClusterLog == nil { - config.ClusterLog = pointer.StringPtr(defaultClusterLog) - } - if config.RefreshInterval == nil { - var r int32 = 20 - config.RefreshInterval = &r - } - if config.UpdateRuleInterval == nil { - var r int32 = 10 - config.UpdateRuleInterval = &r - } - if config.MasterTTL == nil { - var r int32 = 60 - config.MasterTTL = &r - } + config.SetIfNil("profiles.readonly.readonly", int64(1)) + config.SetIfNil("profiles.default.max_memory_usage", int64(10000000000)) + config.SetIfNil("profiles.default.load_balancing", "random") + config.SetIfNil("profiles.default.use_uncompressed_cache", int64(0)) } -func setTiFlashLoggerConfigDefault(config *v1alpha1.FlashLogger) { - if config.ErrorLog == nil { - config.ErrorLog = pointer.StringPtr(defaultErrorLog) - } - if config.Size == nil { - config.Size = pointer.StringPtr("100M") - } - if config.ServerLog == nil { - config.ServerLog = pointer.StringPtr(defaultServerLog) - } - if config.Level == nil { - config.Level = pointer.StringPtr("information") - } - if config.Count == nil { - var c int32 = 10 - config.Count = &c +func setTiFlashFlashConfigDefault(config *v1alpha1.TiFlashCommonConfigWraper, externalClusterName string, clusterName, ns string) { + var tidbStatusAddr string + if len(externalClusterName) > 0 { + tidbStatusAddr = fmt.Sprintf("%s.%s.svc:10080", controller.TiDBMemberName(externalClusterName), ns) + } else { + tidbStatusAddr = fmt.Sprintf("%s.%s.svc:10080", controller.TiDBMemberName(clusterName), ns) } -} + config.SetIfNil("flash.tidb_status_addr", tidbStatusAddr) + config.SetIfNil("flash.service_addr", "0.0.0.0:3930") + config.SetIfNil("flash.overlap_threshold", 0.6) + config.SetIfNil("flash.compact_log_min_period", int64(200)) -func setTiFlashApplicationConfigDefault(config *v1alpha1.FlashApplication) { - if config.RunAsDaemon == nil { - r := true - config.RunAsDaemon = &r - } -} + // set flash_cluster + config.SetIfNil("flash.flash_cluster.cluster_manager_path", "/tiflash/flash_cluster_manager") + config.SetIfNil("flash.flash_cluster.log", defaultClusterLog) + config.SetIfNil("flash.flash_cluster.refresh_interval", int64(20)) + config.SetIfNil("flash.flash_cluster.update_rule_interval", int64(10)) + config.SetIfNil("flash.flash_cluster.master_ttl", int64(60)) -func setTiFlashRaftConfigDefault(config *v1alpha1.FlashRaft, clusterName, ns string) { - if config.PDAddr == nil { - config.PDAddr = pointer.StringPtr(fmt.Sprintf("%s.%s.svc:2379", controller.PDMemberName(clusterName), ns)) - } - if config.KVStorePath == nil { - config.KVStorePath = pointer.StringPtr("/data0/kvstore") - } - if config.StorageEngine == nil { - config.StorageEngine = pointer.StringPtr("dt") - } + // set proxy + config.SetIfNil("flash.proxy.addr", "0.0.0.0:20170") + config.SetIfNil("flash.proxy.advertise-addr", fmt.Sprintf("%s-POD_NUM.%s.%s.svc:20170", controller.TiFlashMemberName(clusterName), controller.TiFlashPeerMemberName(clusterName), ns)) + config.SetIfNil("flash.proxy.data-dir", "/data0/proxy") + config.SetIfNil("flash.proxy.config", "/data0/proxy.toml") } -func setTiFlashStatusConfigDefault(config *v1alpha1.FlashStatus) { - if config.MetricsPort == nil { - var d int32 = 8234 - config.MetricsPort = &d - } +func setTiFlashLoggerConfigDefault(config *v1alpha1.TiFlashCommonConfigWraper) { + // "logger" + config.SetIfNil("logger.errorlog", defaultErrorLog) + config.SetIfNil("logger.size", "100M") + config.SetIfNil("logger.log", defaultServerLog) + config.SetIfNil("logger.level", "information") + config.SetIfNil("logger.count", int64(10)) } -func setTiFlashQuotasConfigDefault(config *v1alpha1.FlashQuota) { - if config.Default == nil { - config.Default = &v1alpha1.Quota{} - } - if config.Default.Interval == nil { - config.Default.Interval = &v1alpha1.Interval{} - } - if config.Default.Interval.Duration == nil { - var d int32 = 3600 - config.Default.Interval.Duration = &d - } - if config.Default.Interval.Queries == nil { - var d int32 = 0 - config.Default.Interval.Queries = &d - } - if config.Default.Interval.Errors == nil { - var d int32 = 0 - config.Default.Interval.Errors = &d - } - if config.Default.Interval.ResultRows == nil { - var d int32 = 0 - config.Default.Interval.ResultRows = &d - } - if config.Default.Interval.ReadRows == nil { - var d int32 = 0 - config.Default.Interval.ReadRows = &d - } - if config.Default.Interval.ExecutionTime == nil { - var d int32 = 0 - config.Default.Interval.ExecutionTime = &d - } +func setTiFlashApplicationConfigDefault(config *v1alpha1.TiFlashCommonConfigWraper) { + config.SetIfNil("application.runAsDaemon", true) } -func setTiFlashNetworksConfigDefault(config *v1alpha1.Networks) { - if config.IP == nil { - config.IP = pointer.StringPtr("::/0") - } -} - -func setTiFlashUsersConfigDefault(config *v1alpha1.FlashUser) { - if config.Readonly == nil { - config.Readonly = &v1alpha1.User{} - } - if config.Readonly.Profile == nil { - config.Readonly.Profile = pointer.StringPtr("readonly") - } - if config.Readonly.Quota == nil { - config.Readonly.Quota = pointer.StringPtr("default") - } - if config.Readonly.Networks == nil { - config.Readonly.Networks = &v1alpha1.Networks{} - } - setTiFlashNetworksConfigDefault(config.Readonly.Networks) - - if config.Default == nil { - config.Default = &v1alpha1.User{} - } - if config.Default.Profile == nil { - config.Default.Profile = pointer.StringPtr("default") - } - if config.Default.Quota == nil { - config.Default.Quota = pointer.StringPtr("default") - } - if config.Default.Networks == nil { - config.Default.Networks = &v1alpha1.Networks{} - } - setTiFlashNetworksConfigDefault(config.Default.Networks) -} - -func setTiFlashProfilesConfigDefault(config *v1alpha1.FlashProfile) { - if config.Readonly == nil { - config.Readonly = &v1alpha1.Profile{} - } - if config.Readonly.Readonly == nil { - var r int32 = 1 - config.Readonly.Readonly = &r - } - if config.Default == nil { - config.Default = &v1alpha1.Profile{} - } - if config.Default.MaxMemoryUsage == nil { - var m int64 = 10000000000 - config.Default.MaxMemoryUsage = &m - } - if config.Default.UseUncompressedCache == nil { - var u int32 = 0 - config.Default.UseUncompressedCache = &u - } - if config.Default.LoadBalancing == nil { - l := "random" - config.Default.LoadBalancing = &l - } +func setTiFlashRaftConfigDefault(config *v1alpha1.TiFlashCommonConfigWraper, clusterName, ns string) { + config.SetIfNil("raft.pd_addr", fmt.Sprintf("%s.%s.svc:2379", controller.PDMemberName(clusterName), ns)) + config.SetIfNil("raft.kvstore_path", "/data0/kvstore") + config.SetIfNil("raft.storage_engine", "dt") } diff --git a/pkg/manager/member/tiflash_util_test.go b/pkg/manager/member/tiflash_util_test.go index 65e5363fed..284ef7966c 100644 --- a/pkg/manager/member/tiflash_util_test.go +++ b/pkg/manager/member/tiflash_util_test.go @@ -14,12 +14,14 @@ package member import ( + "encoding/json" "path" "testing" "github.com/google/go-cmp/cmp" . "github.com/onsi/gomega" "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1" + "github.com/pingcap/tidb-operator/pkg/util/toml" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -361,6 +363,7 @@ var ( TiDBStatusAddr: pointer.StringPtr("test-tidb.test.svc:10081"), }, HTTPPort: pointer.Int32Ptr(8121), + HTTPSPort: pointer.Int32Ptr(9999), InternalServerHTTPPort: pointer.Int32Ptr(9001), ListenHost: pointer.StringPtr("0.0.0.1"), FlashLogger: &v1alpha1.FlashLogger{ @@ -404,8 +407,9 @@ var ( FlashStatus: &v1alpha1.FlashStatus{ MetricsPort: pointer.Int32Ptr(8235), }, - TCPPort: pointer.Int32Ptr(9001), - TmpPath: pointer.StringPtr("/data1/tmp"), + TCPPort: pointer.Int32Ptr(9001), + TCPPortSecure: pointer.Int32Ptr(9002), + TmpPath: pointer.StringPtr("/data1/tmp"), FlashUser: &v1alpha1.FlashUser{ Default: &v1alpha1.User{ Networks: &v1alpha1.Networks{ @@ -432,20 +436,6 @@ var ( }, }, } - defaultTiFlashLogConfig = v1alpha1.TiFlashConfig{ - CommonConfig: &v1alpha1.CommonConfig{ - Flash: &v1alpha1.Flash{ - FlashCluster: &v1alpha1.FlashCluster{ - ClusterLog: pointer.StringPtr("/data0/logs/flash_cluster_manager.log"), - }, - FlashProxy: &v1alpha1.FlashProxy{}, - }, - FlashLogger: &v1alpha1.FlashLogger{ - ErrorLog: pointer.StringPtr("/data0/logs/error.log"), - ServerLog: pointer.StringPtr("/data0/logs/server.log"), - }, - }, - } customTiFlashLogConfig = v1alpha1.TiFlashConfig{ CommonConfig: &v1alpha1.CommonConfig{ Flash: &v1alpha1.Flash{ @@ -643,11 +633,9 @@ func newTidbCluster() *v1alpha1.TidbCluster { } func TestBuildTiFlashSidecarContainers(t *testing.T) { - g := NewGomegaWithT(t) - type testcase struct { name string - flashConfig *v1alpha1.TiFlashConfig + flashConfig *v1alpha1.TiFlashConfigWraper expect []corev1.Container resource bool } @@ -660,17 +648,17 @@ func TestBuildTiFlashSidecarContainers(t *testing.T) { }, { name: "empty config", - flashConfig: &v1alpha1.TiFlashConfig{}, + flashConfig: v1alpha1.NewTiFlashConfig(), expect: defaultSideCarContainers, }, { name: "custom config", - flashConfig: &customTiFlashLogConfig, + flashConfig: mustFromOldConfig(&customTiFlashLogConfig), expect: customSideCarContainers, }, { name: "custom resource config", - flashConfig: &customTiFlashLogConfig, + flashConfig: mustFromOldConfig(&customTiFlashLogConfig), expect: customResourceSideCarContainers, resource: true, }, @@ -690,67 +678,45 @@ func TestBuildTiFlashSidecarContainers(t *testing.T) { }, } } - cs := buildTiFlashSidecarContainers(tc) - g.Expect(cs).To(Equal(test.expect)) - }) - } -} -func TestSetTiFlashConfigDefault(t *testing.T) { - g := NewGomegaWithT(t) - - type testcase struct { - name string - config v1alpha1.TiFlashConfig - expect v1alpha1.TiFlashConfig - } - - tests := []*testcase{ - { - name: "nil config", - config: v1alpha1.TiFlashConfig{}, - expect: defaultTiFlashConfig, - }, - { - name: "custom config", - config: customTiFlashConfig, - expect: customTiFlashConfig, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - setTiFlashConfigDefault(&test.config, "", "test", "test") - g.Expect(test.config).To(Equal(test.expect)) + cs, err := buildTiFlashSidecarContainers(tc) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(test.expect, cs); diff != "" { + t.Fatalf("test %s unexpected configuration (-want, +got): %s", test.name, diff) + } }) } } -func TestSetTiFlashLogConfigDefault(t *testing.T) { - g := NewGomegaWithT(t) - +func TestSetTiFlashConfigDefault(t *testing.T) { type testcase struct { name string - config v1alpha1.TiFlashConfig - expect v1alpha1.TiFlashConfig + config *v1alpha1.TiFlashConfigWraper + expect *v1alpha1.TiFlashConfigWraper } tests := []*testcase{ { name: "nil config", - config: v1alpha1.TiFlashConfig{}, - expect: defaultTiFlashLogConfig, + config: v1alpha1.NewTiFlashConfig(), + expect: mustFromOldConfig(&defaultTiFlashConfig), }, { name: "custom config", - config: customTiFlashLogConfig, - expect: customTiFlashLogConfig, + config: mustFromOldConfig(&customTiFlashConfig), + expect: mustFromOldConfig(&customTiFlashConfig), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - setTiFlashLogConfigDefault(&test.config) - g.Expect(test.config).To(Equal(test.expect)) + // g := NewGomegaWithT(t) + setTiFlashConfigDefault(test.config, "", "test", "test") + // g.Expect(test.config).To(Equal(test.expect)) + if diff := cmp.Diff(*test.expect, *test.config); diff != "" { + t.Fatalf("unexpected configuration (-want, +got): %s", diff) + } }) } } @@ -789,7 +755,7 @@ func TestGetTiFlashConfig(t *testing.T) { }, Spec: v1alpha1.TidbClusterSpec{ TiFlash: &v1alpha1.TiFlashSpec{ - Config: &v1alpha1.TiFlashConfig{ + Config: mustFromOldConfig(&v1alpha1.TiFlashConfig{ CommonConfig: &v1alpha1.CommonConfig{ Security: &v1alpha1.FlashSecurity{ CertAllowedCN: []string{ @@ -797,7 +763,7 @@ func TestGetTiFlashConfig(t *testing.T) { }, }, }, - }, + }), }, TLSCluster: &v1alpha1.TLSCluster{ Enabled: true, @@ -842,10 +808,42 @@ func TestGetTiFlashConfig(t *testing.T) { for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { + g := NewGomegaWithT(t) config := getTiFlashConfig(&tt.tc) - if diff := cmp.Diff(*tt.expected, *config); diff != "" { + flashConfig := &v1alpha1.TiFlashConfig{ + CommonConfig: new(v1alpha1.CommonConfig), + ProxyConfig: new(v1alpha1.ProxyConfig), + } + + data, err := config.Common.MarshalTOML() + g.Expect(err).Should(BeNil()) + err = toml.Unmarshal(data, flashConfig.CommonConfig) + g.Expect(err).Should(BeNil()) + + data, err = config.Proxy.MarshalTOML() + g.Expect(err).Should(BeNil()) + err = toml.Unmarshal(data, flashConfig.ProxyConfig) + g.Expect(err).Should(BeNil()) + + if diff := cmp.Diff(*tt.expected, *flashConfig); diff != "" { t.Fatalf("unexpected configuration (-want, +got): %s", diff) } }) } } + +func mustFromOldConfig(old *v1alpha1.TiFlashConfig) *v1alpha1.TiFlashConfigWraper { + config := v1alpha1.NewTiFlashConfig() + + data, err := json.Marshal(old) + if err != nil { + panic(err) + } + + err = json.Unmarshal(data, config) + if err != nil { + panic(err) + } + + return config +} diff --git a/pkg/manager/member/tikv_member_manager.go b/pkg/manager/member/tikv_member_manager.go index 0385752633..48ebcd0619 100644 --- a/pkg/manager/member/tikv_member_manager.go +++ b/pkg/manager/member/tikv_member_manager.go @@ -250,15 +250,18 @@ func (tkmm *tikvMemberManager) syncTiKVConfigMap(tc *v1alpha1.TidbCluster, set * if err != nil { return nil, err } - if set != nil && tc.BaseTiKVSpec().ConfigUpdateStrategy() == v1alpha1.ConfigUpdateStrategyInPlace { - inUseName := FindConfigMapVolume(&set.Spec.Template.Spec, func(name string) bool { + + var inUseName string + if set != nil { + inUseName = FindConfigMapVolume(&set.Spec.Template.Spec, func(name string) bool { return strings.HasPrefix(name, controller.TiKVMemberName(tc.Name)) }) - if inUseName != "" { - newCm.Name = inUseName - } } + err = updateConfigMapIfNeed(tkmm.deps.ConfigMapLister, tc.BaseTiDBSpec().ConfigUpdateStrategy(), inUseName, newCm) + if err != nil { + return nil, err + } return tkmm.deps.TypedControl.CreateOrUpdateConfigMap(tc, newCm) } @@ -607,11 +610,6 @@ func getTikVConfigMap(tc *v1alpha1.TidbCluster) (*corev1.ConfigMap, error) { OwnerReferences: []metav1.OwnerReference{controller.GetOwnerRef(tc)}, } - if tc.BaseTiKVSpec().ConfigUpdateStrategy() == v1alpha1.ConfigUpdateStrategyRollingUpdate { - if err := AddConfigMapDigestSuffix(cm); err != nil { - return nil, err - } - } return cm, nil } diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index f29c0f9ba3..281362bf0e 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -123,6 +123,18 @@ func (c *GenericConfig) Set(key string, value interface{}) { set(c.MP, key, value) } +func (c *GenericConfig) Del(key string) { + del(c.MP, key) +} + +func (c *GenericConfig) SetIfNil(key string, value interface{}) { + v := c.Get(key) + if v != nil { + return + } + set(c.MP, key, value) +} + func (c *GenericConfig) Get(key string) (value *Value) { if c == nil { return nil @@ -246,6 +258,26 @@ func (v *Value) AsFloat() (float64, error) { } } +func del(ms map[string]interface{}, key string) { + ks := strings.SplitN(key, ".", 2) + if len(ks) == 1 { + delete(ms, key) + return + } + + v := strKeyMap(ms[ks[0]]) + if v == nil { + return + } + + vMap, ok := v.(map[string]interface{}) + if !ok { + panic(v) + } + + del(vMap, ks[1]) +} + func set(ms map[string]interface{}, key string, value interface{}) { ks := strings.SplitN(key, ".", 2) if len(ks) == 1 { diff --git a/pkg/util/config/config_test.go b/pkg/util/config/config_test.go index fd444e2202..8aba1560a8 100644 --- a/pkg/util/config/config_test.go +++ b/pkg/util/config/config_test.go @@ -97,6 +97,52 @@ func TestGetSet(t *testing.T) { } } +func TestDel(t *testing.T) { + g := NewGomegaWithT(t) + kv := map[string]int64{ + "a.b.c1": 1, + "a.b.c2": 2, + "a.b1": 1, + "a.b2": 2, + "a1": 1, + "a2": 2, + } + + c := New(map[string]interface{}{}) + + for k, v := range kv { + c.Set(k, v) + } + for k, v := range kv { + g.Expect(c.Get(k).MustInt()).Should(Equal(v)) + } + + // delete bottom level item + c.Del("a.b.c1") + delete(kv, "a.b.c1") + c.Del("a.b1") + delete(kv, "a.b1") + c.Del("a1") + delete(kv, "a1") + for k, v := range kv { + g.Expect(c.Get(k).MustInt()).Should(Equal(v)) + } + + // delete non-bottom level item + c.Del("a") + delete(kv, "a.b.c2") + delete(kv, "a.b2") + for k, v := range kv { + g.Expect(c.Get(k).MustInt()).Should(Equal(v)) + } + + // delete non-exist item + c.Del("what") + for k, v := range kv { + g.Expect(c.Get(k).MustInt()).Should(Equal(v)) + } +} + func TestDeepCopyJsonObject(t *testing.T) { g := NewGomegaWithT(t) diff --git a/tests/pkg/fixture/fixture.go b/tests/pkg/fixture/fixture.go index 154f6c2cea..527df887df 100644 --- a/tests/pkg/fixture/fixture.go +++ b/tests/pkg/fixture/fixture.go @@ -88,7 +88,7 @@ func GetTidbCluster(ns, name, version string) *v1alpha1.TidbCluster { // We assume all unparsable versions are greater or equal to v4.0.0-beta, // e.g. nightly. if v, err := semver.NewVersion(version); err == nil && v.LessThan(tikvV4Beta) { - tikvConfig.Set("storage", nil) + tikvConfig.Del("storage") } deletePVP := corev1.PersistentVolumeReclaimDelete