From c1e30c3a4725258030a09a471154cf370655948e Mon Sep 17 00:00:00 2001 From: "chunshao.rcs" Date: Wed, 13 Mar 2024 15:33:00 +0800 Subject: [PATCH 1/5] chore: add some dependency project descriptions in notice (#1499) ## Rationale Add some dependency project descriptions in `NOTICE`. ## Detailed Changes 1. Add some dependency project descriptions in `NOTICE`. 2. Add `DEPENDENCIES` file. ## Test Plan No need. --- DEPENDENCIES.tsv | 726 +++++++++++++++++++++ Makefile | 6 + NOTICE | 40 ++ horaemeta/DEPENDENCIES.csv | 77 +++ licenserc.toml | 15 +- licenses/LICENSE-consistent.txt | 21 + src/components/future_ext/src/cancel.rs | 17 - src/components/size_ext/src/lib.rs | 17 - src/components/skiplist/Cargo.toml | 17 - src/components/skiplist/benches/bench.rs | 17 - src/components/skiplist/src/key.rs | 17 - src/components/skiplist/src/lib.rs | 17 - src/components/skiplist/src/list.rs | 17 - src/components/skiplist/tests/tests.rs | 17 - src/components/tracing_util/Cargo.toml | 17 - src/components/tracing_util/src/lib.rs | 17 - src/components/tracing_util/src/logging.rs | 17 - src/server/src/federated.rs | 21 +- src/server/src/session.rs | 21 +- 19 files changed, 888 insertions(+), 226 deletions(-) create mode 100644 DEPENDENCIES.tsv create mode 100644 horaemeta/DEPENDENCIES.csv create mode 100644 licenses/LICENSE-consistent.txt diff --git a/DEPENDENCIES.tsv b/DEPENDENCIES.tsv new file mode 100644 index 0000000000..629ce2bf0e --- /dev/null +++ b/DEPENDENCIES.tsv @@ -0,0 +1,726 @@ +crate 0BSD Apache-2.0 Apache-2.0 WITH LLVM-exception BSD-2-Clause BSD-3-Clause BSL-1.0 CC0-1.0 CDDL-1.0 ISC MIT MIT-0 MPL-2.0 MulanPSL-2.0 Unicode-DFS-2016 Unlicense Zlib Unlicensed +addr2line@0.19.0 X X +adler@1.0.2 X X X +ahash@0.7.6 X X +ahash@0.8.3 X X +aho-corasick@1.0.1 X X +alloc-no-stdlib@2.0.4 X +alloc-stdlib@0.2.2 X +alloc_tracker@2.0.0 X +allocator-api2@0.2.16 X X +analytic_engine@2.0.0 X +android-tzdata@0.1.1 X X +android_system_properties@0.1.5 X X +anes@0.1.6 X X +ansi_term@0.12.1 X +anstream@0.6.13 X X +anstyle@1.0.1 X X +anstyle-parse@0.2.3 X X +anstyle-query@1.0.2 X X +anstyle-wincon@3.0.2 X X +anyhow@1.0.70 X X +arc-swap@0.4.8 X X +arc-swap@1.6.0 X X +arena@2.0.0 X +array-init@2.1.0 X X +arrayref@0.3.7 X +arrayvec@0.7.2 X X +arrow@38.0.0 X +arrow@49.0.0 X +arrow-arith@38.0.0 X +arrow-arith@49.0.0 X +arrow-array@38.0.0 X +arrow-array@49.0.0 X +arrow-buffer@38.0.0 X +arrow-buffer@49.0.0 X +arrow-cast@38.0.0 X +arrow-cast@49.0.0 X +arrow-csv@38.0.0 X +arrow-csv@49.0.0 X +arrow-data@38.0.0 X +arrow-data@49.0.0 X +arrow-ipc@38.0.0 X +arrow-ipc@49.0.0 X +arrow-json@38.0.0 X +arrow-json@49.0.0 X +arrow-ord@38.0.0 X +arrow-ord@49.0.0 X +arrow-row@38.0.0 X +arrow-row@49.0.0 X +arrow-schema@38.0.0 X +arrow-schema@49.0.0 X +arrow-select@38.0.0 X +arrow-select@49.0.0 X +arrow-string@38.0.0 X +arrow-string@49.0.0 X +arrow_ext@2.0.0 X +arrow_util@0.1.0 X X +async-compression@0.4.1 X X +async-io@1.13.0 X X +async-lock@2.7.0 X X +async-recursion@1.0.4 X X +async-stream@0.3.4 X +async-stream-impl@0.3.4 X +async-trait@0.1.77 X X +atomic_enum@0.2.0 X +atty@0.2.14 X +autocfg@1.1.0 X X +axum@0.6.12 X +axum-core@0.3.3 X +backtrace@0.3.67 X X +base64@0.13.1 X X +base64@0.21.0 X X +bcder@0.7.3 X +benchmarks@2.0.0 X +bigdecimal@0.3.0 X X +bincode@1.3.3 X +bindgen@0.59.2 X +bindgen@0.65.1 X +bitflags@1.3.2 X X +bitflags@2.3.3 X X +bitvec@1.0.1 X +blake2@0.10.6 X X +blake3@1.3.3 X X +block-buffer@0.10.4 X X +brotli@3.3.4 X X +brotli-decompressor@2.3.4 X X +buf_redux@0.8.4 X X +bufstream@0.1.4 X X +bumpalo@3.12.0 X X +bytecount@0.6.3 X X +bytemuck@1.13.1 X X X +byteorder@1.4.3 X X +bytes@1.5.0 X +bytes_ext@2.0.0 X +bzip2@0.4.4 X X +bzip2-sys@0.1.11+1.0.8 X X +camino@1.1.4 X X +cargo-platform@0.1.2 X X +cargo_metadata@0.14.2 X +cast@0.3.0 X X +catalog@2.0.0 X +catalog_impls@2.0.0 X +cc@1.0.83 X X +cexpr@0.6.0 X X +cfg-if@0.1.10 X X +cfg-if@1.0.0 X X +chrono@0.4.31 X X +chrono-tz@0.8.1 X X +chrono-tz-build@0.1.0 X X +ciborium@0.2.1 X +ciborium-io@0.2.1 X +ciborium-ll@0.2.1 X +clang-sys@1.6.1 X +clap@4.5.1 X X +clap_builder@4.5.1 X X +clap_derive@4.5.0 X X +clap_lex@0.7.0 X X +clru@0.6.1 X +cluster@2.0.0 X +cmake@0.1.50 X X +codec@2.0.0 X +codespan-reporting@0.11.1 X +colorchoice@1.0.0 X X +comfy-table@6.1.4 X +comfy-table@7.0.1 X +common_types@2.0.0 X +concurrent-queue@2.1.0 X X +console-api@0.5.0 X +console-subscriber@0.1.9 X +const-oid@0.9.4 X X +constant_time_eq@0.2.5 X X X +core-foundation-sys@0.8.3 X X +cpp_demangle@0.4.2 X X +cpufeatures@0.2.6 X X +crc@3.0.1 X X +crc-catalog@2.2.0 X X +crc32c@0.6.3 X X +crc32fast@1.3.2 X X +criterion@0.5.1 X X +criterion-plot@0.5.0 X X +crossbeam@0.8.2 X X +crossbeam-channel@0.5.7 X X +crossbeam-deque@0.8.3 X X +crossbeam-epoch@0.9.14 X X +crossbeam-queue@0.3.8 X X +crossbeam-utils@0.8.15 X X +crunchy@0.2.2 X +crypto-common@0.1.6 X X +csv@1.2.1 X X +csv-core@0.1.10 X X +cxx@1.0.94 X X +cxx-build@1.0.94 X X +cxxbridge-flags@1.0.94 X X +cxxbridge-macro@1.0.94 X X +darling@0.14.4 X +darling@0.20.3 X +darling_core@0.14.4 X +darling_core@0.20.3 X +darling_macro@0.14.4 X +darling_macro@0.20.3 X +dashmap@5.5.3 X +datafusion@33.0.0 X +datafusion-common@33.0.0 X +datafusion-execution@33.0.0 X +datafusion-expr@33.0.0 X +datafusion-optimizer@33.0.0 X +datafusion-physical-expr@33.0.0 X +datafusion-physical-plan@33.0.0 X +datafusion-proto@33.0.0 X +datafusion-sql@33.0.0 X +datafusion_util@0.1.0 X X +debugid@0.8.0 X +der@0.7.8 X X +derive-new@0.6.0 X +derive_builder@0.11.2 X X +derive_builder@0.12.0 X X +derive_builder_core@0.11.2 X X +derive_builder_core@0.12.0 X X +derive_builder_macro@0.11.2 X X +derive_builder_macro@0.12.0 X X +derive_utils@0.13.2 X X +df_engine_extensions@2.0.0 X +df_operator@2.0.0 X +digest@0.10.7 X X +dirs-next@2.0.0 X X +dirs-sys-next@0.1.2 X X +doc-comment@0.3.3 X +dotenvy@0.15.7 X +dtoa@1.0.6 X X +either@1.8.1 X X +encoding_rs@0.8.32 X X X +env_logger@0.6.2 X X +equivalent@1.0.1 X X +error-chain@0.12.4 X X +etcd-client@0.10.4 X +event-listener@2.5.3 X X +fallible-iterator@0.2.0 X X +fastrand@1.9.0 X X +findshlibs@0.10.2 X X +fixedbitset@0.4.2 X X +flatbuffers@23.1.21 X +flate2@1.0.25 X X +fnv@1.0.7 X X +form_urlencoded@1.1.0 X X +frunk@0.4.1 X +frunk_core@0.4.1 X +frunk_derives@0.4.1 X +frunk_proc_macro_helpers@0.1.1 X +frunk_proc_macros@0.1.1 X +frunk_proc_macros_impl@0.1.1 X +fs_extra@1.3.0 X +fuchsia-cprng@0.1.1 X +funty@2.0.0 X +future_ext@2.0.0 X +futures@0.1.31 X X +futures@0.3.28 X X +futures-channel@0.3.28 X X +futures-core@0.3.28 X X +futures-cpupool@0.1.8 X X +futures-executor@0.3.28 X X +futures-io@0.3.28 X X +futures-lite@1.12.0 X X +futures-macro@0.3.28 X X +futures-sink@0.3.28 X X +futures-task@0.3.28 X X +futures-util@0.3.28 X X +gcc@0.3.55 X X +generated_types@0.1.0 X X +generic-array@0.14.7 X +generic_error@2.0.0 X +getrandom@0.2.12 X X +gimli@0.27.2 X X +glob@0.3.1 X X +h2@0.3.24 X +half@1.8.2 X X +half@2.2.1 X X +hash_ext@2.0.0 X +hashbrown@0.12.3 X X +hashbrown@0.13.2 X X +hashbrown@0.14.0 X X +hdrhistogram@7.5.2 X X +headers@0.3.8 X +headers-core@0.2.0 X +heck@0.4.1 X X +hermit-abi@0.1.19 X X +hermit-abi@0.2.6 X X +hermit-abi@0.3.1 X X +hex@0.4.3 X X +hmac@0.12.1 X X +horaedb@2.0.0 X +horaedb-client@1.0.2 X +horaedb-test@2.0.0 X +horaedbproto@1.0.24 X +horaedbproto@2.0.0 X +http@0.2.9 X X +http-body@0.4.5 X +httparse@1.8.0 X X +httpdate@1.0.2 X X +humantime@1.3.0 X X +humantime@2.1.0 X X +hyper@0.14.25 X +hyper-rustls@0.23.2 X X X +hyper-timeout@0.4.1 X X +hyperloglog@1.0.2 X +iana-time-zone@0.1.55 X X +iana-time-zone-haiku@0.1.1 X X +id_allocator@2.0.0 X +ident_case@1.0.1 X X +idna@0.3.0 X X +indexmap@1.9.3 X X +indexmap@2.0.0 X X +inferno@0.11.15 X +influxdb-line-protocol@1.0.0 X X +influxdb_influxql_parser@0.1.0 X X +instant@0.1.12 X +integer-encoding@3.0.4 X +interpreters@2.0.0 X +io-enum@1.1.1 X X +io-lifetimes@1.0.9 X X X +iox_query@0.1.0 X X +iox_query_influxql@0.1.0 X X +ipnet@2.7.2 X X +is-terminal@0.4.6 X +itertools@0.10.5 X X +itertools@0.11.0 X X +itertools@0.12.0 X X +itoa@1.0.6 X X +jemalloc-ctl@0.3.3 X X +jemalloc-sys@0.3.2 X X +jemallocator@0.3.2 X X +jobserver@0.1.26 X X +js-sys@0.3.61 X X +lazy_static@1.4.0 X X +lazycell@1.3.0 X X +lexical@6.1.1 X X +lexical-core@0.8.5 X X +lexical-parse-float@0.8.5 X X +lexical-parse-integer@0.8.6 X X +lexical-util@0.8.5 X X +lexical-write-float@0.8.5 X X +lexical-write-integer@0.8.5 X X +libc@0.2.152 X X +libloading@0.7.4 X +libm@0.2.6 X X +librocksdb_sys@0.1.0 X +libtitan_sys@0.0.1 X +libz-sys@1.1.8 X X +link-cplusplus@1.0.8 X X +linux-raw-sys@0.3.1 X X X +local-ip-address@0.5.4 X X +lock_api@0.4.11 X X +log@0.4.17 X X +logger@2.0.0 X +lru@0.10.1 X +lru@0.7.8 X +lz4@1.24.0 X +lz4-sys@1.9.4 X +lz4_flex@0.11.1 X +lzma-sys@0.1.20 X X +mach@0.3.2 X +macros@2.0.0 X +matchers@0.1.0 X +matchit@0.7.0 X +md-5@0.10.5 X X +md5@0.7.0 X X +memchr@2.5.0 X X +memmap2@0.5.10 X X +memoffset@0.8.0 X +message_queue@2.0.0 X +meta_client@2.0.0 X +metric_ext@2.0.0 X +mime@0.3.17 X X +mime_guess@2.0.4 X +minimal-lexical@0.2.1 X X +miniz_oxide@0.6.2 X X X +mio@0.8.11 X +moka@0.10.1 X X +multimap@0.8.3 X X +multipart@0.18.0 X X +murmur2@0.1.0 X +murmur3@0.4.1 X X +mysql@24.0.0 X X +mysql-common-derive@0.30.2 X X +mysql_common@0.29.2 X X +mysql_common@0.30.6 X X +named_pipe@0.4.1 X X +neli@0.6.4 X +neli-proc-macros@0.1.3 X +net2@0.2.38 X X +nix@0.26.2 X +nom@7.1.3 X +notifier@2.0.0 X +ntapi@0.4.1 X X +nu-ansi-term@0.46.0 X +num@0.4.1 X X +num-bigint@0.4.3 X X +num-complex@0.4.3 X X +num-format@0.4.4 X X +num-integer@0.1.45 X X +num-iter@0.1.43 X X +num-rational@0.4.1 X X +num-traits@0.2.15 X X +num_cpus@1.15.0 X X +num_threads@0.1.6 X X +object@0.30.3 X X +object_store@0.5.6 X X +object_store@0.8.0 X X +object_store@2.0.0 X +obkv-table-client-rs@0.1.0 X +observability_deps@0.1.0 X X +once_cell@1.19.0 X X +oorandom@11.1.3 X +opensrv-mysql@0.1.0 X +ordered-float@2.10.0 X +overload@0.1.1 X +panic_ext@2.0.0 X +parking@2.0.0 X X +parking_lot@0.11.2 X X +parking_lot@0.12.1 X X +parking_lot_core@0.8.6 X X +parking_lot_core@0.9.9 X X +parquet@49.0.0 X +parquet_ext@2.0.0 X +parse-zoneinfo@0.3.0 X +partition_table_engine@2.0.0 X +partitioned_lock@2.0.0 X +paste@0.1.18 X X +paste@1.0.12 X X +paste-impl@0.1.18 X X +pbjson@0.5.1 X +pbjson-build@0.5.1 X +pbjson-types@0.5.1 X +peeking_take_while@0.1.2 X X +pem@2.0.1 X +pem@3.0.3 X +percent-encoding@2.2.0 X X +petgraph@0.6.3 X X +pgwire@0.19.1 X X +phf@0.11.1 X +phf_codegen@0.11.1 X +phf_generator@0.11.1 X +phf_shared@0.11.1 X +pin-project@1.0.12 X X +pin-project-internal@1.0.12 X X +pin-project-lite@0.2.9 X X +pin-utils@0.1.0 X X +pkg-config@0.3.26 X X +plotters@0.3.4 X +plotters-backend@0.3.4 X +plotters-svg@0.3.3 X +polling@2.6.0 X X +postgres-protocol@0.6.5 X X +postgres-types@0.2.5 X X +pprof@0.12.1 X +ppv-lite86@0.2.17 X X +prettydiff@0.6.2 X +prettyplease@0.1.25 X X +prettyplease@0.2.12 X X +proc-macro-crate@1.3.1 X X +proc-macro-error@1.0.4 X X +proc-macro-error-attr@1.0.4 X X +proc-macro-hack@0.5.20+deprecated X X +proc-macro2@1.0.76 X X +profile@2.0.0 X +prom-remote-api@0.2.2 X +prometheus@0.12.0 X +prometheus-client@0.21.1 X X +prometheus-client-derive-encode@0.4.1 X X +prometheus-static-metric@0.5.1 X +prost@0.11.8 X +prost@0.12.3 X +prost-build@0.11.7 X +prost-derive@0.11.8 X +prost-derive@0.12.3 X +prost-types@0.11.8 X +protobuf@2.28.0 X +protoc-bin-vendored@3.0.0 X +protoc-bin-vendored-linux-aarch_64@3.0.0 X +protoc-bin-vendored-linux-ppcle_64@3.0.0 X +protoc-bin-vendored-linux-x86_32@3.0.0 X +protoc-bin-vendored-linux-x86_64@3.0.0 X +protoc-bin-vendored-macos-x86_64@3.0.0 X +protoc-bin-vendored-win32@3.0.0 X +proxy@2.0.0 X +pulldown-cmark@0.9.2 X +quanta@0.10.1 X +query_engine@2.0.0 X +query_frontend@2.0.0 X +query_functions@0.1.0 X X +quick-error@1.2.3 X X +quick-xml@0.26.0 X +quick-xml@0.28.2 X +quote@1.0.35 X X +r2d2@0.8.10 X X +radium@0.7.0 X +rand@0.3.23 X X +rand@0.4.6 X X +rand@0.8.5 X X +rand_chacha@0.3.1 X X +rand_core@0.3.1 X X +rand_core@0.4.2 X X +rand_core@0.6.4 X X +raw-cpuid@10.7.0 X +rayon@1.8.0 X X +rayon-core@1.12.0 X X +rdrand@0.4.0 X +redox_syscall@0.2.16 X +redox_syscall@0.3.5 X +redox_syscall@0.4.1 X +redox_users@0.4.3 X +regex@1.8.1 X X +regex-automata@0.1.10 X X +regex-syntax@0.6.29 X X +regex-syntax@0.7.1 X X +regex-syntax@0.8.2 X X +remote_engine_client@2.0.0 X +reqwest@0.11.16 X X +rgb@0.8.36 X +ring@0.16.20 X +ring@0.17.7 X +rocksdb@0.3.0 X +router@2.0.0 X +rskafka@0.4.0 X X +runtime@2.0.0 X +rust-crypto@0.2.36 X X +rust-sdk-test@2.0.0 X +rust_decimal@1.29.1 X +rustc-demangle@0.1.22 X X +rustc-hash@1.1.0 X X +rustc-serialize@0.3.25 X X +rustc_version@0.4.0 X X +rustix@0.37.5 X X X +rustls@0.20.8 X X X +rustls@0.21.6 X X X +rustls@0.22.2 X X X +rustls-pemfile@0.2.1 X X X +rustls-pemfile@1.0.2 X X X +rustls-pki-types@1.1.0 X X +rustls-webpki@0.100.2 X +rustls-webpki@0.101.2 X +rustls-webpki@0.102.1 X +rustversion@1.0.12 X X +ryu@1.0.13 X X +safemem@0.3.3 X X +same-file@1.0.6 X X +sampling_cache@2.0.0 X +saturating@0.1.0 X +scheduled-thread-pool@0.2.7 X X +schema@0.1.0 X X +scoped-tls@1.0.1 X X +scopeguard@1.1.0 X X +scratch@1.0.5 X X +sct@0.7.0 X X X +seahash@4.1.0 X +semver@1.0.17 X X +seq-macro@0.3.3 X X +serde@1.0.159 X X +serde_bytes@0.11.9 X X +serde_derive@1.0.159 X X +serde_json@1.0.95 X X +serde_spanned@0.6.1 X X +serde_urlencoded@0.7.1 X X +server@2.0.0 X +sha-1@0.10.1 X X +sha1@0.10.5 X X +sha2@0.10.6 X X +sharded-slab@0.1.4 X +shlex@1.3.0 X X +signal-hook@0.3.15 X X +signal-hook-registry@1.4.1 X X +signature@2.1.0 X X +siphasher@0.3.10 X X +size_ext@2.0.0 X +skeptic@0.13.7 X X +skiplist@2.0.0 X +slab@0.4.8 X +slog@2.7.0 X X X +slog-async@2.7.0 X X X +slog-global@0.1.0 X +slog-term@2.9.0 X X X +smallvec@1.10.0 X X +snafu@0.6.10 X X +snafu@0.7.4 X X +snafu-derive@0.6.10 X X +snafu-derive@0.7.4 X X +snap@1.1.0 X +snappy-sys@0.1.0 X +socket2@0.4.9 X X +socket2@0.5.3 X X +spin@0.5.2 X +spin@0.9.8 X +spki@0.7.2 X X +sqlness@0.5.0 X +sqlparser@0.39.0 X +sqlparser_derive@0.1.1 X +stable_deref_trait@1.2.0 X X +static_assertions@1.1.0 X X +str_stack@0.1.0 X X +stringprep@0.1.3 X X +strsim@0.10.0 X +strsim@0.11.0 X +strum@0.24.1 X +strum@0.25.0 X +strum_macros@0.24.3 X +strum_macros@0.25.1 X +subprocess@0.2.9 X X +subtle@2.5.0 X +symbolic-common@12.3.0 X +symbolic-demangle@12.3.0 X +syn@1.0.109 X X +syn@2.0.48 X X +sync_wrapper@0.1.2 X +sysinfo@0.30.5 X +system_catalog@2.0.0 X +system_stats@2.0.0 X +table_engine@2.0.0 X +table_kv@2.0.0 X +tagptr@0.2.0 X X +take_mut@0.2.2 X +tap@1.0.1 X +tempfile@3.5.0 X X +term@0.7.0 X X +termcolor@1.2.0 X X +test_helpers@0.1.0 X X +test_util@2.0.0 X +thiserror@1.0.56 X X +thiserror-impl@1.0.56 X X +thread_local@1.1.7 X X +thrift@0.17.0 X +time@0.1.43 X X +time@0.3.20 X X +time-core@0.1.0 X X +time-macros@0.2.8 X X +time_ext@2.0.0 X +timed_task@2.0.0 X +tinytemplate@1.2.1 X X +tinyvec@1.6.0 X X X +tinyvec_macros@0.1.1 X X X +tokio@1.29.1 X +tokio-io-timeout@1.2.0 X X +tokio-macros@2.1.0 X +tokio-rustls@0.23.4 X X +tokio-rustls@0.25.0 X X +tokio-stream@0.1.12 X +tokio-tungstenite@0.17.2 X +tokio-util@0.7.7 X +toml@0.5.11 X X +toml@0.7.3 X X +toml_datetime@0.6.1 X X +toml_edit@0.19.8 X X +toml_ext@2.0.0 X +tonic@0.8.3 X +tonic@0.9.2 X +tonic-build@0.8.4 X +tools@2.0.0 X +tower@0.4.13 X +tower-layer@0.3.2 X +tower-service@0.3.2 X +trace_metric@2.0.0 X +trace_metric_derive@2.0.0 X +trace_metric_derive_tests@2.0.0 X +tracing@0.1.37 X +tracing-appender@0.2.2 X +tracing-attributes@0.1.23 X +tracing-core@0.1.30 X +tracing-futures@0.2.5 X +tracing-log@0.1.3 X +tracing-subscriber@0.3.17 X +tracing_util@2.0.0 X +triomphe@0.1.8 X X +try-lock@0.2.4 X +tungstenite@0.17.3 X X +twoway@0.1.8 X X +twox-hash@1.6.3 X +typenum@1.16.0 X X +unicase@2.6.0 X X +unicode-bidi@0.3.13 X X +unicode-ident@1.0.8 X X X +unicode-normalization@0.1.22 X X +unicode-segmentation@1.10.1 X X +unicode-width@0.1.10 X X +untrusted@0.7.1 X +untrusted@0.9.0 X +url@2.3.1 X X +utf-8@0.7.6 X X +utf8parse@0.2.1 X X +uuid@1.6.1 X X +uuid-macro-internal@1.6.1 X X +valuable@0.1.0 X +vcpkg@0.2.15 X X +vergen@8.2.1 X X +version_check@0.9.4 X X +waker-fn@1.1.0 X X +wal@2.0.0 X +walkdir@2.3.3 X X +want@0.3.0 X +warp@0.3.3 X +wasi@0.10.2+wasi-snapshot-preview1 X X X +wasi@0.11.0+wasi-snapshot-preview1 X X X +wasm-bindgen@0.2.84 X X +wasm-bindgen-backend@0.2.84 X X +wasm-bindgen-futures@0.4.34 X X +wasm-bindgen-macro@0.2.84 X X +wasm-bindgen-macro-support@0.2.84 X X +wasm-bindgen-shared@0.2.84 X X +wasm-streams@0.2.3 X X +web-sys@0.3.61 X X +webpki@0.22.2 X +webpki-roots@0.22.6 X +webpki-roots@0.23.1 X +which@4.4.0 X +winapi@0.3.9 X X +winapi-i686-pc-windows-gnu@0.4.0 X X +winapi-util@0.1.5 X X +winapi-x86_64-pc-windows-gnu@0.4.0 X X +windows@0.47.0 X X +windows@0.52.0 X X +windows-core@0.52.0 X X +windows-sys@0.45.0 X X +windows-sys@0.48.0 X X +windows-sys@0.52.0 X X +windows-targets@0.42.2 X X +windows-targets@0.47.0 X X +windows-targets@0.48.1 X X +windows-targets@0.52.0 X X +windows_aarch64_gnullvm@0.42.2 X X +windows_aarch64_gnullvm@0.47.0 X X +windows_aarch64_gnullvm@0.48.0 X X +windows_aarch64_gnullvm@0.52.0 X X +windows_aarch64_msvc@0.42.2 X X +windows_aarch64_msvc@0.47.0 X X +windows_aarch64_msvc@0.48.0 X X +windows_aarch64_msvc@0.52.0 X X +windows_i686_gnu@0.42.2 X X +windows_i686_gnu@0.47.0 X X +windows_i686_gnu@0.48.0 X X +windows_i686_gnu@0.52.0 X X +windows_i686_msvc@0.42.2 X X +windows_i686_msvc@0.47.0 X X +windows_i686_msvc@0.48.0 X X +windows_i686_msvc@0.52.0 X X +windows_x86_64_gnu@0.42.2 X X +windows_x86_64_gnu@0.47.0 X X +windows_x86_64_gnu@0.48.0 X X +windows_x86_64_gnu@0.52.0 X X +windows_x86_64_gnullvm@0.42.2 X X +windows_x86_64_gnullvm@0.47.0 X X +windows_x86_64_gnullvm@0.48.0 X X +windows_x86_64_gnullvm@0.52.0 X X +windows_x86_64_msvc@0.42.2 X X +windows_x86_64_msvc@0.47.0 X X +windows_x86_64_msvc@0.48.0 X X +windows_x86_64_msvc@0.52.0 X X +winnow@0.4.1 X +winreg@0.10.1 X +wyz@0.5.1 X +x509-certificate@0.23.1 X +xorfilter-rs@0.6.0 X +xz2@0.1.7 X X +zeroize@1.6.0 X X +zeroize_derive@1.4.2 X X +zstd@0.12.3+zstd.1.5.2 X +zstd@0.13.0 X +zstd-safe@6.0.4+zstd.1.5.4 X X +zstd-safe@7.0.0 X X +zstd-sys@2.0.7+zstd.1.5.4 X X diff --git a/Makefile b/Makefile index 9d4bcb4f55..6569ebf0ac 100644 --- a/Makefile +++ b/Makefile @@ -152,3 +152,9 @@ fix: cargo fmt cargo sort --workspace cargo clippy --fix --allow-staged --all-targets --all-features --workspace -- -D warnings + +update-licenses: + # Update Horaedb dependencies + cargo install --locked cargo-deny && cargo deny list -f tsv -l crate > DEPENDENCIES.tsv + # Update Horaemeta dependencies + cd $(DIR)/horaemeta; go install github.com/google/go-licenses@latest && go-licenses report ./... > DEPENDENCIES.csv diff --git a/NOTICE b/NOTICE index cd5de63d68..0914029dd4 100644 --- a/NOTICE +++ b/NOTICE @@ -3,3 +3,43 @@ Copyright 2024 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). + +================================================================ + +This product includes a number of Dependencies with separate copyright notices +and license terms. Your use of these submodules is subject to the terms and +conditions of the following licenses. + +================================================================ + +================================================================ +Apache-2.0 licenses +================================================================ +The following components are provided under the Apache-2.0 License.See project link for details. +The text of each license is the standard Apache 2.0 license. + +* prometheus-common(https://github.com/prometheus/common) +* greptimedb(https://github.com/GreptimeTeam/greptimedb) +* agatedb(https://github.com/tikv/agatedb) +* tikv(https://github.com/tikv/tikv) +* influxdb(https://github.com/influxdata/influxdb) +* databend(https://github.com/datafuselabs/databend) + +File horaemeta/server/service/http/route.go is modified from Prometheus-common. +Files src/server/src/federated.rs, src/server/src/session.rs are modified from greptimedb. +Files src/components/skiplist/benches/bench.rs, src/components/skiplist/src/lib.rs, src/components/skiplist/src/key.rs, +src/components/skiplist/src/list.rs, src/components/skiplist/tests/tests.rs, src/components/skiplist/Cargo.toml are modified from agatedb. +File src/components/size_ext/src/lib.rs is modified from tikv. +File src/components/future_ext/src/cancel.rs is modified from influxdb. +Files src/components/tracing_util/src/lib.rs, src/components/tracing_util/src/logging.rs, src/components/tracing_util/Cargo.toml are modified from databend. + +================================================================ +MIT licenses +================================================================ +The following components are provided under the MIT License. See project link for details. +The text of each license is also included in licenses/LICENSE-[project].txt + +* consistent(https://github.com/buraksezer/consistent) + +Files horaemeta/server/coordinator/scheduler/nodepicker/hash/consistent_uniform.go, +horaemeta/server/coordinator/scheduler/nodepicker/hash/consistent_uniform_test.go are modified from consistent. diff --git a/horaemeta/DEPENDENCIES.csv b/horaemeta/DEPENDENCIES.csv new file mode 100644 index 0000000000..bd0189b283 --- /dev/null +++ b/horaemeta/DEPENDENCIES.csv @@ -0,0 +1,77 @@ +github.com/apache/incubator-horaedb-meta,https://github.com/apache/incubator-horaedb-meta/blob/HEAD/licenserc.toml,Apache-2.0 +github.com/apache/incubator-horaedb-proto/golang/pkg,https://github.com/apache/incubator-horaedb-proto/blob/92152841fc8a/golang/LICENSE,Apache-2.0 +github.com/beorn7/perks/quantile,https://github.com/beorn7/perks/blob/v1.0.1/LICENSE,MIT +github.com/caarlos0/env/v6,https://github.com/caarlos0/env/blob/v6.10.1/LICENSE.md,MIT +github.com/cenkalti/backoff/v4,https://github.com/cenkalti/backoff/blob/v4.2.1/LICENSE,MIT +github.com/cespare/xxhash/v2,https://github.com/cespare/xxhash/blob/v2.2.0/LICENSE.txt,MIT +github.com/coreos/go-semver/semver,https://github.com/coreos/go-semver/blob/v0.3.1/LICENSE,Apache-2.0 +github.com/coreos/go-systemd/v22/journal,https://github.com/coreos/go-systemd/blob/v22.5.0/LICENSE,Apache-2.0 +github.com/davecgh/go-spew/spew,https://github.com/davecgh/go-spew/blob/v1.1.1/LICENSE,ISC +github.com/dustin/go-humanize,https://github.com/dustin/go-humanize/blob/v1.0.1/LICENSE,MIT +github.com/go-logr/logr,https://github.com/go-logr/logr/blob/v1.4.1/LICENSE,Apache-2.0 +github.com/go-logr/stdr,https://github.com/go-logr/stdr/blob/v1.2.2/LICENSE,Apache-2.0 +github.com/gogo/protobuf,https://github.com/gogo/protobuf/blob/v1.3.2/LICENSE,BSD-3-Clause +github.com/golang-jwt/jwt/v4,https://github.com/golang-jwt/jwt/blob/v4.5.0/LICENSE,MIT +github.com/golang/protobuf,https://github.com/golang/protobuf/blob/v1.5.4/LICENSE,BSD-3-Clause +github.com/google/btree,https://github.com/google/btree/blob/v1.1.2/LICENSE,Apache-2.0 +github.com/gorilla/websocket,https://github.com/gorilla/websocket/blob/v1.5.1/LICENSE,BSD-3-Clause +github.com/grpc-ecosystem/go-grpc-middleware,https://github.com/grpc-ecosystem/go-grpc-middleware/blob/v1.4.0/LICENSE,Apache-2.0 +github.com/grpc-ecosystem/go-grpc-prometheus,https://github.com/grpc-ecosystem/go-grpc-prometheus/blob/v1.2.0/LICENSE,Apache-2.0 +github.com/grpc-ecosystem/grpc-gateway,https://github.com/grpc-ecosystem/grpc-gateway/blob/v1.16.0/LICENSE.txt,BSD-3-Clause +github.com/grpc-ecosystem/grpc-gateway/v2,https://github.com/grpc-ecosystem/grpc-gateway/blob/v2.19.1/LICENSE,BSD-3-Clause +github.com/jonboulle/clockwork,https://github.com/jonboulle/clockwork/blob/v0.4.0/LICENSE,Apache-2.0 +github.com/json-iterator/go,https://github.com/json-iterator/go/blob/v1.1.12/LICENSE,MIT +github.com/julienschmidt/httprouter,https://github.com/julienschmidt/httprouter/blob/v1.3.0/LICENSE,BSD-3-Clause +github.com/looplab/fsm,https://github.com/looplab/fsm/blob/v0.3.0/LICENSE,Apache-2.0 +github.com/modern-go/concurrent,https://github.com/modern-go/concurrent/blob/bacd9c7ef1dd/LICENSE,Apache-2.0 +github.com/modern-go/reflect2,https://github.com/modern-go/reflect2/blob/v1.0.2/LICENSE,Apache-2.0 +github.com/pelletier/go-toml/v2,https://github.com/pelletier/go-toml/blob/v2.0.6/LICENSE,MIT +github.com/pingcap/log,https://github.com/pingcap/log/blob/v1.1.0/LICENSE,Apache-2.0 +github.com/pkg/errors,https://github.com/pkg/errors/blob/v0.9.1/LICENSE,BSD-2-Clause +github.com/pmezard/go-difflib/difflib,https://github.com/pmezard/go-difflib/blob/v1.0.0/LICENSE,BSD-3-Clause +github.com/prometheus/client_golang/prometheus,https://github.com/prometheus/client_golang/blob/v1.19.0/LICENSE,Apache-2.0 +github.com/prometheus/client_model/go,https://github.com/prometheus/client_model/blob/v0.6.0/LICENSE,Apache-2.0 +github.com/prometheus/common,https://github.com/prometheus/common/blob/v0.50.0/LICENSE,Apache-2.0 +github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg,https://github.com/prometheus/common/blob/v0.50.0/internal/bitbucket.org/ww/goautoneg/README.txt,BSD-3-Clause +github.com/prometheus/procfs,https://github.com/prometheus/procfs/blob/v0.13.0/LICENSE,Apache-2.0 +github.com/sirupsen/logrus,https://github.com/sirupsen/logrus/blob/v1.9.3/LICENSE,MIT +github.com/soheilhy/cmux,https://github.com/soheilhy/cmux/blob/v0.1.5/LICENSE,Apache-2.0 +github.com/spaolacci/murmur3,https://github.com/spaolacci/murmur3/blob/v1.1.0/LICENSE,BSD-3-Clause +github.com/spf13/pflag,https://github.com/spf13/pflag/blob/v1.0.5/LICENSE,BSD-3-Clause +github.com/stretchr/testify,https://github.com/stretchr/testify/blob/v1.8.4/LICENSE,MIT +github.com/tikv/pd/pkg/tempurl,https://github.com/tikv/pd/blob/v2.1.19/LICENSE,Apache-2.0 +github.com/tmc/grpc-websocket-proxy/wsproxy,https://github.com/tmc/grpc-websocket-proxy/blob/673ab2c3ae75/LICENSE,MIT +github.com/xiang90/probing,https://github.com/xiang90/probing/blob/a49e3df8f510/LICENSE,MIT +go.etcd.io/bbolt,https://github.com/etcd-io/bbolt/blob/v1.3.9/LICENSE,MIT +go.etcd.io/etcd/api/v3,https://github.com/etcd-io/etcd/blob/api/v3.5.12/api/LICENSE,Apache-2.0 +go.etcd.io/etcd/client/pkg/v3,https://github.com/etcd-io/etcd/blob/client/pkg/v3.5.12/client/pkg/LICENSE,Apache-2.0 +go.etcd.io/etcd/client/v2,https://github.com/etcd-io/etcd/blob/client/v2.305.12/client/v2/LICENSE,Apache-2.0 +go.etcd.io/etcd/client/v3,https://github.com/etcd-io/etcd/blob/client/v3.5.12/client/v3/LICENSE,Apache-2.0 +go.etcd.io/etcd/pkg/v3,https://github.com/etcd-io/etcd/blob/pkg/v3.5.12/pkg/LICENSE,Apache-2.0 +go.etcd.io/etcd/raft/v3,https://github.com/etcd-io/etcd/blob/raft/v3.5.12/raft/LICENSE,Apache-2.0 +go.etcd.io/etcd/server/v3,https://github.com/etcd-io/etcd/blob/server/v3.5.12/server/LICENSE,Apache-2.0 +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc,https://github.com/open-telemetry/opentelemetry-go-contrib/blob/instrumentation/google.golang.org/grpc/otelgrpc/v0.49.0/instrumentation/google.golang.org/grpc/otelgrpc/LICENSE,Apache-2.0 +go.opentelemetry.io/otel,https://github.com/open-telemetry/opentelemetry-go/blob/v1.24.0/LICENSE,Apache-2.0 +go.opentelemetry.io/otel/exporters/otlp/otlptrace,https://github.com/open-telemetry/opentelemetry-go/blob/exporters/otlp/otlptrace/v1.24.0/exporters/otlp/otlptrace/LICENSE,Apache-2.0 +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc,https://github.com/open-telemetry/opentelemetry-go/blob/exporters/otlp/otlptrace/otlptracegrpc/v1.24.0/exporters/otlp/otlptrace/otlptracegrpc/LICENSE,Apache-2.0 +go.opentelemetry.io/otel/metric,https://github.com/open-telemetry/opentelemetry-go/blob/metric/v1.24.0/metric/LICENSE,Apache-2.0 +go.opentelemetry.io/otel/sdk,https://github.com/open-telemetry/opentelemetry-go/blob/sdk/v1.24.0/sdk/LICENSE,Apache-2.0 +go.opentelemetry.io/otel/trace,https://github.com/open-telemetry/opentelemetry-go/blob/trace/v1.24.0/trace/LICENSE,Apache-2.0 +go.opentelemetry.io/proto/otlp,https://github.com/open-telemetry/opentelemetry-proto-go/blob/otlp/v1.1.0/otlp/LICENSE,Apache-2.0 +go.uber.org/multierr,https://github.com/uber-go/multierr/blob/v1.11.0/LICENSE.txt,MIT +go.uber.org/zap,https://github.com/uber-go/zap/blob/v1.27.0/LICENSE,MIT +golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/v0.21.0:LICENSE,BSD-3-Clause +golang.org/x/net,https://cs.opensource.google/go/x/net/+/v0.22.0:LICENSE,BSD-3-Clause +golang.org/x/sync/errgroup,https://cs.opensource.google/go/x/sync/+/v0.6.0:LICENSE,BSD-3-Clause +golang.org/x/sys/unix,https://cs.opensource.google/go/x/sys/+/v0.18.0:LICENSE,BSD-3-Clause +golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.14.0:LICENSE,BSD-3-Clause +golang.org/x/time/rate,https://cs.opensource.google/go/x/time/+/v0.5.0:LICENSE,BSD-3-Clause +google.golang.org/genproto/googleapis/api,https://github.com/googleapis/go-genproto/blob/29370a3891b7/googleapis/api/LICENSE,Apache-2.0 +google.golang.org/genproto/googleapis/rpc,https://github.com/googleapis/go-genproto/blob/29370a3891b7/googleapis/rpc/LICENSE,Apache-2.0 +google.golang.org/genproto/protobuf/field_mask,https://github.com/googleapis/go-genproto/blob/29370a3891b7/LICENSE,Apache-2.0 +google.golang.org/grpc,https://github.com/grpc/grpc-go/blob/v1.62.1/LICENSE,Apache-2.0 +google.golang.org/protobuf,https://github.com/protocolbuffers/protobuf-go/blob/v1.33.0/LICENSE,BSD-3-Clause +gopkg.in/natefinch/lumberjack.v2,https://github.com/natefinch/lumberjack/blob/v2.2.1/LICENSE,MIT +gopkg.in/yaml.v3,https://github.com/go-yaml/yaml/blob/v3.0.1/LICENSE,MIT +sigs.k8s.io/yaml,https://github.com/kubernetes-sigs/yaml/blob/v1.4.0/LICENSE,Apache-2.0 +sigs.k8s.io/yaml/goyaml.v2,https://github.com/kubernetes-sigs/yaml/blob/v1.4.0/goyaml.v2/LICENSE,Apache-2.0 diff --git a/licenserc.toml b/licenserc.toml index d8310c504f..e08f40f95d 100644 --- a/licenserc.toml +++ b/licenserc.toml @@ -21,5 +21,18 @@ excludes = [ # Derived "horaemeta/server/coordinator/scheduler/nodepicker/hash/consistent_uniform_test.go", "horaemeta/server/coordinator/scheduler/nodepicker/hash/consistent_uniform.go", - "horaemeta/server/service/http/route.go" + "horaemeta/server/service/http/route.go", + "src/server/src/federated.rs", + "src/server/src/session.rs", + "src/components/skiplist/benches/bench.rs", + "src/components/skiplist/src/lib.rs", + "src/components/skiplist/src/key.rs", + "src/components/skiplist/src/list.rs", + "src/components/skiplist/tests/tests.rs", + "src/components/skiplist/Cargo.toml", + "src/components/size_ext/src/lib.rs", + "src/components/future_ext/src/cancel.rs", + "src/components/tracing_util/src/lib.rs", + "src/components/tracing_util/src/logging.rs", + "src/components/tracing_util/Cargo.toml" ] diff --git a/licenses/LICENSE-consistent.txt b/licenses/LICENSE-consistent.txt new file mode 100644 index 0000000000..9b28a31ac8 --- /dev/null +++ b/licenses/LICENSE-consistent.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018-2021 Burak Sezer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/components/future_ext/src/cancel.rs b/src/components/future_ext/src/cancel.rs index 56df39f7a5..ab223b0466 100644 --- a/src/components/future_ext/src/cancel.rs +++ b/src/components/future_ext/src/cancel.rs @@ -1,20 +1,3 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - //! A future wrapper to ensure the wrapped future must be polled. //! //! This implementation is forked from: https://github.com/influxdata/influxdb_iox/blob/885767aa0a6010de592bde9992945b01389eb994/cache_system/src/cancellation_safe_future.rs diff --git a/src/components/size_ext/src/lib.rs b/src/components/size_ext/src/lib.rs index 1b8e8ead2e..e35f113593 100644 --- a/src/components/size_ext/src/lib.rs +++ b/src/components/size_ext/src/lib.rs @@ -1,20 +1,3 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - // Copyright 2016 TiKV Project Authors. Licensed under Apache-2.0. //! Configure utils diff --git a/src/components/skiplist/Cargo.toml b/src/components/skiplist/Cargo.toml index 78e3430cd5..5953c15144 100644 --- a/src/components/skiplist/Cargo.toml +++ b/src/components/skiplist/Cargo.toml @@ -1,20 +1,3 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - [package] name = "skiplist" authors = ["Jay Lee ", "HoraeDB Authors"] diff --git a/src/components/skiplist/benches/bench.rs b/src/components/skiplist/benches/bench.rs index b048f73727..a3b5f392a3 100644 --- a/src/components/skiplist/benches/bench.rs +++ b/src/components/skiplist/benches/bench.rs @@ -1,20 +1,3 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - use std::{ collections::*, sync::{atomic::*, *}, diff --git a/src/components/skiplist/src/key.rs b/src/components/skiplist/src/key.rs index db1c6f2fec..cda4ded0ce 100644 --- a/src/components/skiplist/src/key.rs +++ b/src/components/skiplist/src/key.rs @@ -1,20 +1,3 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - use std::cmp::Ordering; use bytes::Bytes; diff --git a/src/components/skiplist/src/lib.rs b/src/components/skiplist/src/lib.rs index 02d6cecbb5..0bd650b782 100644 --- a/src/components/skiplist/src/lib.rs +++ b/src/components/skiplist/src/lib.rs @@ -1,20 +1,3 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - //! Forked from //! //! Differences: diff --git a/src/components/skiplist/src/list.rs b/src/components/skiplist/src/list.rs index 1fb1312b82..4e4114c16f 100644 --- a/src/components/skiplist/src/list.rs +++ b/src/components/skiplist/src/list.rs @@ -1,20 +1,3 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - use std::{ alloc::Layout, convert::TryInto, diff --git a/src/components/skiplist/tests/tests.rs b/src/components/skiplist/tests/tests.rs index f2b60837bc..f152acc615 100644 --- a/src/components/skiplist/tests/tests.rs +++ b/src/components/skiplist/tests/tests.rs @@ -1,20 +1,3 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - use std::{ str, sync::{atomic::*, *}, diff --git a/src/components/tracing_util/Cargo.toml b/src/components/tracing_util/Cargo.toml index cdd6a41581..4992e5424a 100644 --- a/src/components/tracing_util/Cargo.toml +++ b/src/components/tracing_util/Cargo.toml @@ -1,20 +1,3 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - [package] name = "tracing_util" authors = ["Databend Authors ", "HoraeDB Authors"] diff --git a/src/components/tracing_util/src/lib.rs b/src/components/tracing_util/src/lib.rs index 638e593949..2fcad4b5a3 100644 --- a/src/components/tracing_util/src/lib.rs +++ b/src/components/tracing_util/src/lib.rs @@ -1,20 +1,3 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - // Copyright 2020 Datafuse Labs. // fork from:https://github.com/datafuselabs/databend/tree/master/common/tracing diff --git a/src/components/tracing_util/src/logging.rs b/src/components/tracing_util/src/logging.rs index 9770569ba9..9fd477f951 100644 --- a/src/components/tracing_util/src/logging.rs +++ b/src/components/tracing_util/src/logging.rs @@ -1,20 +1,3 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - // Copyright 2020 Datafuse Labs. use std::{ diff --git a/src/server/src/federated.rs b/src/server/src/federated.rs index f1636445af..1b2df5e197 100644 --- a/src/server/src/federated.rs +++ b/src/server/src/federated.rs @@ -1,22 +1,3 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -// Forked from https://github.com/GreptimeTeam/greptimedb/blob/702ea32538a99e2d163fb1fbd3e75b1ce4ec4232/src/servers/src/mysql/federated.rs. - // Copyright 2023 Greptime Team // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Forked from https://github.com/GreptimeTeam/greptimedb/blob/702ea32538a99e2d163fb1fbd3e75b1ce4ec4232/src/servers/src/mysql/federated.rs. + //! Use regex to filter out some MySQL federated components' emitted statements. //! Inspired by Databend's "[mysql_federated.rs](https://github.com/datafuselabs/databend/blob/ac706bf65845e6895141c96c0a10bad6fdc2d367/src/query/service/src/servers/mysql/mysql_federated.rs)". diff --git a/src/server/src/session.rs b/src/server/src/session.rs index d095999ed7..907dd8a1a3 100644 --- a/src/server/src/session.rs +++ b/src/server/src/session.rs @@ -1,22 +1,3 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -// Forked from https://github.com/GreptimeTeam/greptimedb/blob/ca4d690424b03806ea0f8bd5e491585224bbf220/src/session/src/lib.rs - // Copyright 2023 Greptime Team // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Forked from https://github.com/GreptimeTeam/greptimedb/blob/ca4d690424b03806ea0f8bd5e491585224bbf220/src/session/src/lib.rs + use std::{ fmt::{Display, Formatter}, net::SocketAddr, From 1674091568c53b6f79d79770dde9b99ce2f09766 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 10:58:37 +0800 Subject: [PATCH 2/5] chore(deps): bump google.golang.org/protobuf from 1.30.0 to 1.33.0 in /integration_tests/sdk/go (#1500) Bumps google.golang.org/protobuf from 1.30.0 to 1.33.0. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google.golang.org/protobuf&package-manager=go_modules&previous-version=1.30.0&new-version=1.33.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/apache/incubator-horaedb/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration_tests/sdk/go/go.mod | 2 +- integration_tests/sdk/go/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integration_tests/sdk/go/go.mod b/integration_tests/sdk/go/go.mod index 58250f84a6..41228fb5a1 100644 --- a/integration_tests/sdk/go/go.mod +++ b/integration_tests/sdk/go/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/grpc v1.56.3 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect ) // TODO: remove this when a new version is released. diff --git a/integration_tests/sdk/go/go.sum b/integration_tests/sdk/go/go.sum index 1df3a2c0d0..11810dd05a 100644 --- a/integration_tests/sdk/go/go.sum +++ b/integration_tests/sdk/go/go.sum @@ -217,8 +217,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 629bf39bea932aa048001ff374255c80892212c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B2=8D=E9=87=91=E6=97=A5?= Date: Fri, 15 Mar 2024 17:25:51 +0800 Subject: [PATCH 3/5] feat(horaectl): impl horaectl in rs (#1481) ## Rationale Implement horaectl using rust ## Detailed Changes - Support `cluster list`, `cluster diagnose`, `cluster schedule` ``` $ target/debug/horaectl -h HoraeCTL is a command line tool for HoraeDB Usage: horaectl [OPTIONS] [COMMAND] Commands: cluster Operations on cluster help Print this message or the help of the given subcommand(s) Options: -m, --meta Meta addr [env: HORAECTL_META_ADDR=] [default: 127.0.0.1:8080] -c, --cluster Cluster name [env: HORAECTL_CLUSTER=] [default: defaultCluster] -i, --interactive Enter interactive mode -h, --help Print help $ target/debug/horaectl cluster -h Operations on cluster Usage: horaectl cluster [OPTIONS] Commands: list List cluster diagnose Diagnose cluster schedule Schedule cluster help Print this message or the help of the given subcommand(s) Options: -m, --meta Meta addr [env: HORAECTL_META_ADDR=] [default: 127.0.0.1:8080] -c, --cluster Cluster name [env: HORAECTL_CLUSTER=] [default: defaultCluster] -h, --help Print help ``` ## Test Plan - Manual tests --------- Co-authored-by: jiacai2050 --- Cargo.lock | 191 +++++++++++++++++++++--------- Cargo.toml | 4 +- horaectl/Cargo.toml | 39 ++++++ horaectl/src/cmd/cluster.rs | 67 +++++++++++ horaectl/src/cmd/mod.rs | 140 ++++++++++++++++++++++ horaectl/src/main.rs | 54 +++++++++ horaectl/src/operation/cluster.rs | 147 +++++++++++++++++++++++ horaectl/src/operation/mod.rs | 80 +++++++++++++ horaectl/src/util/mod.rs | 60 ++++++++++ src/tools/Cargo.toml | 2 +- 10 files changed, 728 insertions(+), 56 deletions(-) create mode 100644 horaectl/Cargo.toml create mode 100644 horaectl/src/cmd/cluster.rs create mode 100644 horaectl/src/cmd/mod.rs create mode 100644 horaectl/src/main.rs create mode 100644 horaectl/src/operation/cluster.rs create mode 100644 horaectl/src/operation/mod.rs create mode 100644 horaectl/src/util/mod.rs diff --git a/Cargo.lock b/Cargo.lock index fca1cab21f..d6c3ead858 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1330,9 +1330,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1340,7 +1340,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.1", + "windows-targets 0.52.0", ] [[package]] @@ -1405,9 +1405,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" dependencies = [ "clap_builder", "clap_derive", @@ -1415,9 +1415,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -1571,7 +1571,7 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" dependencies = [ - "encode_unicode", + "encode_unicode 0.3.6", "lazy_static", "libc", "windows-sys 0.45.0", @@ -1647,11 +1647,21 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpp_demangle" @@ -2411,6 +2421,12 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "encoding_rs" version = "0.8.32" @@ -3019,6 +3035,21 @@ dependencies = [ "digest", ] +[[package]] +name = "horaectl" +version = "2.0.0" +dependencies = [ + "anyhow", + "chrono", + "clap", + "lazy_static", + "prettytable", + "reqwest", + "serde", + "shell-words", + "tokio", +] + [[package]] name = "horaedb" version = "2.0.0" @@ -3185,15 +3216,16 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.2" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ + "futures-util", "http", "hyper", - "rustls 0.20.8", + "rustls 0.21.6", "tokio", - "tokio-rustls 0.23.4", + "tokio-rustls 0.24.1", ] [[package]] @@ -3551,9 +3583,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -5084,6 +5116,20 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "prettytable" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46480520d1b77c9a3482d39939fcf96831537a250ec62d4fd8fbdf8e0302e781" +dependencies = [ + "csv", + "encode_unicode 1.0.0", + "is-terminal", + "lazy_static", + "term", + "unicode-width", +] + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -5815,9 +5861,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.16" +version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ "base64 0.21.0", "bytes", @@ -5836,13 +5882,15 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.20.8", + "rustls 0.21.6", "rustls-pemfile 1.0.2", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", + "system-configuration", "tokio", - "tokio-rustls 0.23.4", + "tokio-rustls 0.24.1", "tokio-util", "tower-service", "url", @@ -5850,7 +5898,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.22.6", + "webpki-roots 0.25.4", "winreg", ] @@ -6268,9 +6316,9 @@ checksum = "e6b44e8fc93a14e66336d230954dda83d18b4605ccace8fe09bc7514a71ad0bc" [[package]] name = "serde" -version = "1.0.159" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] @@ -6286,9 +6334,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.159" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", @@ -6432,6 +6480,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "shlex" version = "1.3.0" @@ -6879,6 +6933,27 @@ dependencies = [ "windows 0.52.0", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system_catalog" version = "2.0.0" @@ -7220,6 +7295,16 @@ dependencies = [ "webpki", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.6", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.25.0" @@ -7872,9 +7957,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -7882,24 +7967,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -7909,9 +7994,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7919,28 +8004,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-streams" -version = "0.2.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" dependencies = [ "futures-util", "js-sys", @@ -7951,9 +8036,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ "js-sys", "wasm-bindgen", @@ -7971,21 +8056,18 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.6" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" dependencies = [ - "webpki", + "rustls-webpki 0.100.2", ] [[package]] name = "webpki-roots" -version = "0.23.1" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" -dependencies = [ - "rustls-webpki 0.100.2", -] +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "which" @@ -8323,11 +8405,12 @@ dependencies = [ [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if 1.0.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index ec6fcd4e23..77277e084f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ license = "Apache-2.0" resolver = "2" # In alphabetical order members = [ + "horaectl", "integration_tests", "integration_tests/sdk/rust", "src/analytic_engine", @@ -89,6 +90,7 @@ arrow = { version = "49.0.0", features = ["prettyprint"] } arrow_ipc = { version = "49.0.0" } arrow_ext = { path = "src/components/arrow_ext" } analytic_engine = { path = "src/analytic_engine" } +anyhow = { version = "1.0" } arena = { path = "src/components/arena" } async-stream = "0.3.4" async-trait = "0.1.72" @@ -101,7 +103,7 @@ catalog_impls = { path = "src/catalog_impls" } horaedbproto = { git = "https://github.com/apache/incubator-horaedb-proto.git", rev = "19ece8f771fc0b3e8e734072cc3d8040de6c74cb" } codec = { path = "src/components/codec" } chrono = "0.4" -clap = "4.5.1" +clap = { version = "4.5.1", features = ["derive"] } clru = "0.6.1" cluster = { path = "src/cluster" } criterion = "0.5" diff --git a/horaectl/Cargo.toml b/horaectl/Cargo.toml new file mode 100644 index 0000000000..580c0e7946 --- /dev/null +++ b/horaectl/Cargo.toml @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +[package] +name = "horaectl" + +[package.license] +workspace = true + +[package.version] +workspace = true + +[package.edition] +workspace = true + +[dependencies] +anyhow = { workspace = true, features = ["backtrace"] } +chrono = { workspace = true } +clap = { workspace = true, features = ["env", "derive"] } +lazy_static = { workspace = true } +prettytable = "0.10.0" +reqwest = { workspace = true } +serde = { workspace = true } +shell-words = "1.1.0" +tokio = { workspace = true } diff --git a/horaectl/src/cmd/cluster.rs b/horaectl/src/cmd/cluster.rs new file mode 100644 index 0000000000..cd22c0ccc3 --- /dev/null +++ b/horaectl/src/cmd/cluster.rs @@ -0,0 +1,67 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +use anyhow::Result; +use clap::Subcommand; + +use crate::operation::cluster::ClusterOp; + +#[derive(Subcommand)] +pub enum ClusterCommand { + /// List cluster + List, + + /// Diagnose cluster + Diagnose, + + /// Schedule cluster + Schedule { + #[clap(subcommand)] + cmd: Option, + }, +} + +#[derive(Subcommand)] +pub enum ScheduleCommand { + /// Get the schedule status + Get, + + /// Enable schedule + On, + + /// Disable schedule + Off, +} + +pub async fn run(cmd: ClusterCommand) -> Result<()> { + let op = ClusterOp::try_new()?; + match cmd { + ClusterCommand::List => op.list().await, + ClusterCommand::Diagnose => op.diagnose().await, + ClusterCommand::Schedule { cmd } => { + if let Some(cmd) = cmd { + match cmd { + ScheduleCommand::Get => op.get_schedule_status().await, + ScheduleCommand::On => op.update_schedule_status(true).await, + ScheduleCommand::Off => op.update_schedule_status(false).await, + } + } else { + op.get_schedule_status().await + } + } + } +} diff --git a/horaectl/src/cmd/mod.rs b/horaectl/src/cmd/mod.rs new file mode 100644 index 0000000000..5906ef1822 --- /dev/null +++ b/horaectl/src/cmd/mod.rs @@ -0,0 +1,140 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +mod cluster; +use std::{io, io::Write}; + +use anyhow::Result; +use clap::{Args, Parser, Subcommand}; + +use crate::{ + cmd::cluster::ClusterCommand, + util::{CLUSTER_NAME, META_ADDR}, +}; + +#[derive(Parser)] +#[clap(name = "horaectl")] +#[clap(about = "HoraeCTL is a command line tool for HoraeDB", version)] +pub struct App { + #[clap(flatten)] + pub global_opts: GlobalOpts, + + /// Enter interactive mode + #[clap(short, long, default_value_t = false)] + pub interactive: bool, + + #[clap(subcommand)] + pub command: Option, +} + +#[derive(Debug, Args)] +pub struct GlobalOpts { + /// Meta addr + #[clap( + short, + long = "meta", + global = true, + env = "HORAECTL_META_ADDR", + default_value = "127.0.0.1:8080" + )] + pub meta_addr: String, + + /// Cluster name + #[clap( + short, + long = "cluster", + global = true, + env = "HORAECTL_CLUSTER", + default_value = "defaultCluster" + )] + pub cluster_name: String, +} + +#[derive(Subcommand)] +pub enum SubCommand { + /// Operations on cluster + #[clap(alias = "c")] + Cluster { + #[clap(subcommand)] + commands: ClusterCommand, + }, +} + +pub async fn run_command(cmd: SubCommand) -> Result<()> { + match cmd { + SubCommand::Cluster { commands } => cluster::run(commands).await, + } +} + +pub async fn repl_loop() { + loop { + print_prompt( + META_ADDR.lock().unwrap().as_str(), + CLUSTER_NAME.lock().unwrap().as_str(), + ); + + let args = match read_args() { + Ok(args) => args, + Err(e) => { + println!("Read input failed, err:{}", e); + continue; + } + }; + + if let Some(cmd) = args.get(1) { + if ["quit", "exit", "q"].iter().any(|v| v == cmd) { + break; + } + } + + match App::try_parse_from(args) { + Ok(horaectl) => { + if let Some(cmd) = horaectl.command { + if let Err(e) = match cmd { + SubCommand::Cluster { commands } => cluster::run(commands).await, + } { + println!("Run command failed, err:{e}"); + } + } + } + Err(e) => { + println!("Parse command failed, err:{e}"); + } + } + } +} + +fn read_args() -> Result, String> { + io::stdout().flush().unwrap(); + let mut input = String::new(); + io::stdin() + .read_line(&mut input) + .map_err(|e| e.to_string())?; + + let input = input.trim(); + if input.is_empty() { + return Err("No arguments provided".into()); + } + + let mut args = vec!["horaectl".to_string()]; + args.extend(shell_words::split(input).map_err(|e| e.to_string())?); + Ok(args) +} + +fn print_prompt(address: &str, cluster: &str) { + print!("{}({}) > ", address, cluster); +} diff --git a/horaectl/src/main.rs b/horaectl/src/main.rs new file mode 100644 index 0000000000..24658ab626 --- /dev/null +++ b/horaectl/src/main.rs @@ -0,0 +1,54 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +mod cmd; +mod operation; +mod util; + +use clap::{CommandFactory, Parser}; + +use crate::{ + cmd::{repl_loop, run_command, App}, + util::{CLUSTER_NAME, META_ADDR}, +}; + +#[tokio::main] +async fn main() { + let app = App::parse(); + { + let mut meta_addr = META_ADDR.lock().unwrap(); + *meta_addr = app.global_opts.meta_addr; + } + { + let mut cluster_name = CLUSTER_NAME.lock().unwrap(); + *cluster_name = app.global_opts.cluster_name; + } + + if app.interactive { + repl_loop().await; + return; + } + + if let Some(cmd) = app.command { + if let Err(e) = run_command(cmd).await { + println!("Run command failed, err:{e}"); + std::process::exit(1); + } + } else { + App::command().print_help().expect("print help failed"); + } +} diff --git a/horaectl/src/operation/cluster.rs b/horaectl/src/operation/cluster.rs new file mode 100644 index 0000000000..709d44be26 --- /dev/null +++ b/horaectl/src/operation/cluster.rs @@ -0,0 +1,147 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +use std::time::Duration; + +use anyhow::Result; +use prettytable::row; +use reqwest::Client; + +use crate::{ + operation::{ + ClusterResponse, DiagnoseShardResponse, EnableScheduleRequest, EnableScheduleResponse, + }, + util::{ + format_time_milli, table_writer, API, CLUSTERS, CLUSTERS_DIAGNOSE_HEADER, + CLUSTERS_ENABLE_SCHEDULE_HEADER, CLUSTERS_LIST_HEADER, CLUSTER_NAME, DEBUG, HTTP, + META_ADDR, + }, +}; + +fn list_url() -> String { + HTTP.to_string() + META_ADDR.lock().unwrap().as_str() + API + CLUSTERS +} + +fn diagnose_url() -> String { + HTTP.to_string() + + META_ADDR.lock().unwrap().as_str() + + DEBUG + + "/diagnose" + + "/" + + CLUSTER_NAME.lock().unwrap().as_str() + + "/shards" +} + +fn schedule_url() -> String { + HTTP.to_string() + + META_ADDR.lock().unwrap().as_str() + + DEBUG + + CLUSTERS + + "/" + + CLUSTER_NAME.lock().unwrap().as_str() + + "/enableSchedule" +} + +pub struct ClusterOp { + http_client: Client, +} + +impl ClusterOp { + pub fn try_new() -> Result { + let hc = Client::builder() + .timeout(Duration::from_secs(30)) + .user_agent("horaectl") + .build()?; + + Ok(Self { http_client: hc }) + } + + pub async fn list(&self) -> Result<()> { + let res = self.http_client.get(list_url()).send().await?; + let response: ClusterResponse = res.json().await?; + + let mut table = table_writer(&CLUSTERS_LIST_HEADER); + for cluster in response.data { + table.add_row(row![ + cluster.id, + cluster.name, + cluster.shard_total.to_string(), + cluster.topology_type, + cluster.procedure_executing_batch_size.to_string(), + format_time_milli(cluster.created_at), + format_time_milli(cluster.modified_at) + ]); + } + table.printstd(); + + Ok(()) + } + + pub async fn diagnose(&self) -> Result<()> { + let res = self.http_client.get(diagnose_url()).send().await?; + let response: DiagnoseShardResponse = res.json().await?; + let mut table = table_writer(&CLUSTERS_DIAGNOSE_HEADER); + table.add_row(row![response + .data + .unregistered_shards + .iter() + .map(|shard_id| shard_id.to_string()) + .collect::>() + .join(", ")]); + for (shard_id, data) in response.data.unready_shards { + table.add_row(row!["", shard_id, data.node_name, data.status]); + } + table.printstd(); + + Ok(()) + } + + pub async fn get_schedule_status(&self) -> Result<()> { + let res = self.http_client.get(schedule_url()).send().await?; + let response: EnableScheduleResponse = res.json().await?; + let mut table = table_writer(&CLUSTERS_ENABLE_SCHEDULE_HEADER); + let row = match response.data { + Some(data) => row![data], + None => row!["topology should in dynamic mode"], + }; + table.add_row(row); + table.printstd(); + + Ok(()) + } + + pub async fn update_schedule_status(&self, enable: bool) -> Result<()> { + let request = EnableScheduleRequest { enable }; + + let res = self + .http_client + .put(schedule_url()) + .json(&request) + .send() + .await?; + let response: EnableScheduleResponse = res.json().await?; + let mut table = table_writer(&CLUSTERS_ENABLE_SCHEDULE_HEADER); + let row = match response.data { + Some(data) => row![data], + None => row!["topology should in dynamic mode"], + }; + table.add_row(row); + table.printstd(); + + Ok(()) + } +} diff --git a/horaectl/src/operation/mod.rs b/horaectl/src/operation/mod.rs new file mode 100644 index 0000000000..f872346700 --- /dev/null +++ b/horaectl/src/operation/mod.rs @@ -0,0 +1,80 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +pub mod cluster; + +use std::collections::HashMap; + +use serde::{Deserialize, Serialize}; +#[derive(Deserialize, Debug)] +pub struct Cluster { + #[serde(rename = "ID")] + id: u32, + #[serde(rename = "Name")] + name: String, + #[serde(rename = "ShardTotal")] + shard_total: u32, + #[serde(rename = "TopologyType")] + topology_type: String, + #[serde(rename = "ProcedureExecutingBatchSize")] + procedure_executing_batch_size: u32, + #[serde(rename = "CreatedAt")] + created_at: i64, + #[serde(rename = "ModifiedAt")] + modified_at: i64, +} + +#[derive(Deserialize, Debug)] +pub struct ClusterResponse { + #[allow(unused)] + status: String, + data: Vec, +} + +#[derive(Deserialize, Debug)] +pub struct DiagnoseShardStatus { + #[serde(rename = "nodeName")] + node_name: String, + status: String, +} + +#[derive(Deserialize, Debug)] +pub struct DiagnoseShard { + #[serde(rename = "unregisteredShards")] + unregistered_shards: Vec, + #[serde(rename = "unreadyShards")] + unready_shards: HashMap, +} + +#[derive(Deserialize, Debug)] +pub struct DiagnoseShardResponse { + #[allow(unused)] + status: String, + data: DiagnoseShard, +} + +#[derive(Serialize)] +pub struct EnableScheduleRequest { + enable: bool, +} + +#[derive(Deserialize)] +pub struct EnableScheduleResponse { + #[allow(unused)] + status: String, + data: Option, +} diff --git a/horaectl/src/util/mod.rs b/horaectl/src/util/mod.rs new file mode 100644 index 0000000000..d6a4311365 --- /dev/null +++ b/horaectl/src/util/mod.rs @@ -0,0 +1,60 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +use std::sync::Mutex; + +use chrono::{TimeZone, Utc}; +use lazy_static::lazy_static; +use prettytable::{Cell, Row, Table}; + +lazy_static! { + pub static ref META_ADDR: Mutex = Mutex::new(String::new()); + pub static ref CLUSTER_NAME: Mutex = Mutex::new(String::new()); +} + +pub const HTTP: &str = "http://"; +pub const API: &str = "/api/v1"; +pub const DEBUG: &str = "/debug"; +pub const CLUSTERS: &str = "/clusters"; +pub static CLUSTERS_LIST_HEADER: [&str; 7] = [ + "ID", + "Name", + "ShardTotal", + "TopologyType", + "ProcedureExecutingBatchSize", + "CreatedAt", + "ModifiedAt", +]; +pub static CLUSTERS_DIAGNOSE_HEADER: [&str; 4] = [ + "unregistered_shards", + "unready_shards:shard_id", + "unready_shards:node_name", + "unready_shards:status", +]; +pub static CLUSTERS_ENABLE_SCHEDULE_HEADER: [&str; 1] = ["enable_schedule"]; + +pub fn table_writer(header: &[&str]) -> Table { + let mut table = Table::new(); + let header_row = Row::from_iter(header.iter().map(|&entry| Cell::new(entry))); + table.add_row(header_row); + table +} + +pub fn format_time_milli(milli: i64) -> String { + let datetime = Utc.timestamp_millis_opt(milli).single().unwrap(); + datetime.format("%Y-%m-%d %H:%M:%S%.3f").to_string() +} diff --git a/src/tools/Cargo.toml b/src/tools/Cargo.toml index fb3910665e..1a3231cb8f 100644 --- a/src/tools/Cargo.toml +++ b/src/tools/Cargo.toml @@ -32,7 +32,7 @@ workspace = true [dependencies] analytic_engine = { workspace = true } -anyhow = { version = "1.0", features = ["backtrace"] } +anyhow = { workspace = true, features = ["backtrace"] } clap = { workspace = true, features = ["derive"] } common_types = { workspace = true } futures = { workspace = true } From 9291dfc5ab8fca30b5bfeba4799de2db0ae5768a Mon Sep 17 00:00:00 2001 From: CooooolFrog Date: Mon, 18 Mar 2024 15:47:51 +0800 Subject: [PATCH 4/5] feat(horaemeta): add node inspector (#1483) ## Rationale In some extreme scenarios, etcd events may be lost or update failures may occur, which may cause the mapping between nodes and shards to fail to be updated correctly. We need to add a cover-up mechanism to ensure that the mapping relationship is always correct. ## Detailed Changes * Add `NodeInspector`, it will start when the cluster start, running in he background and detect the status of nodes. ## Test Plan Pass CI. --------- Co-authored-by: xikai.wxk --- horaemeta/server/cluster/cluster.go | 11 ++ .../cluster/metadata/cluster_metadata.go | 2 +- .../cluster/metadata/cluster_metadata_test.go | 2 +- .../coordinator/inspector/node_inspector.go | 147 ++++++++++++++++++ .../inspector/node_inspector_test.go | 145 +++++++++++++++++ .../scheduler/manager/scheduler_manager.go | 2 +- .../server/coordinator/shard_picker_test.go | 2 +- horaemeta/server/service/http/api.go | 2 +- 8 files changed, 308 insertions(+), 5 deletions(-) create mode 100644 horaemeta/server/coordinator/inspector/node_inspector.go create mode 100644 horaemeta/server/coordinator/inspector/node_inspector_test.go diff --git a/horaemeta/server/cluster/cluster.go b/horaemeta/server/cluster/cluster.go index 951361774a..48ff07abb6 100644 --- a/horaemeta/server/cluster/cluster.go +++ b/horaemeta/server/cluster/cluster.go @@ -26,6 +26,7 @@ import ( "github.com/apache/incubator-horaedb-meta/server/cluster/metadata" "github.com/apache/incubator-horaedb-meta/server/coordinator" "github.com/apache/incubator-horaedb-meta/server/coordinator/eventdispatch" + "github.com/apache/incubator-horaedb-meta/server/coordinator/inspector" "github.com/apache/incubator-horaedb-meta/server/coordinator/procedure" "github.com/apache/incubator-horaedb-meta/server/coordinator/scheduler/manager" "github.com/apache/incubator-horaedb-meta/server/id" @@ -47,6 +48,7 @@ type Cluster struct { procedureFactory *coordinator.Factory procedureManager procedure.Manager schedulerManager manager.SchedulerManager + nodeInspector *inspector.NodeInspector } func NewCluster(logger *zap.Logger, metadata *metadata.ClusterMetadata, client *clientv3.Client, rootPath string) (*Cluster, error) { @@ -62,12 +64,15 @@ func NewCluster(logger *zap.Logger, metadata *metadata.ClusterMetadata, client * schedulerManager := manager.NewManager(logger, procedureManager, procedureFactory, metadata, client, rootPath, metadata.GetTopologyType(), metadata.GetProcedureExecutingBatchSize()) + nodeInspector := inspector.NewNodeInspector(logger, metadata) + return &Cluster{ logger: logger, metadata: metadata, procedureFactory: procedureFactory, procedureManager: procedureManager, schedulerManager: schedulerManager, + nodeInspector: nodeInspector, }, nil } @@ -78,6 +83,9 @@ func (c *Cluster) Start(ctx context.Context) error { if err := c.schedulerManager.Start(ctx); err != nil { return errors.WithMessage(err, "start scheduler manager") } + if err := c.nodeInspector.Start(ctx); err != nil { + return errors.WithMessage(err, "start node inspector") + } return nil } @@ -88,6 +96,9 @@ func (c *Cluster) Stop(ctx context.Context) error { if err := c.schedulerManager.Stop(ctx); err != nil { return errors.WithMessage(err, "stop scheduler manager") } + if err := c.nodeInspector.Stop(ctx); err != nil { + return errors.WithMessage(err, "stop node inspector") + } return nil } diff --git a/horaemeta/server/cluster/metadata/cluster_metadata.go b/horaemeta/server/cluster/metadata/cluster_metadata.go index 0ae03b6a48..d68b4d9b36 100644 --- a/horaemeta/server/cluster/metadata/cluster_metadata.go +++ b/horaemeta/server/cluster/metadata/cluster_metadata.go @@ -685,7 +685,7 @@ func (c *ClusterMetadata) UpdateClusterViewByNode(ctx context.Context, shardNode return nil } -func (c *ClusterMetadata) DropShardNode(ctx context.Context, shardNodes []storage.ShardNode) error { +func (c *ClusterMetadata) DropShardNodes(ctx context.Context, shardNodes []storage.ShardNode) error { if err := c.topologyManager.DropShardNodes(ctx, shardNodes); err != nil { return errors.WithMessage(err, "drop shard nodes") } diff --git a/horaemeta/server/cluster/metadata/cluster_metadata_test.go b/horaemeta/server/cluster/metadata/cluster_metadata_test.go index 907dbbf507..e29761491c 100644 --- a/horaemeta/server/cluster/metadata/cluster_metadata_test.go +++ b/horaemeta/server/cluster/metadata/cluster_metadata_test.go @@ -213,7 +213,7 @@ func testShardOperation(ctx context.Context, re *require.Assertions, m *metadata _, err = m.GetShardNodeByTableIDs([]storage.TableID{}) re.NoError(err) - err = m.DropShardNode(ctx, []storage.ShardNode{{ + err = m.DropShardNodes(ctx, []storage.ShardNode{{ ID: shardNodeResult.NodeShards[0].ShardNode.ID, ShardRole: shardNodeResult.NodeShards[0].ShardNode.ShardRole, NodeName: shardNodeResult.NodeShards[0].ShardNode.NodeName, diff --git a/horaemeta/server/coordinator/inspector/node_inspector.go b/horaemeta/server/coordinator/inspector/node_inspector.go new file mode 100644 index 0000000000..e4a3671c8a --- /dev/null +++ b/horaemeta/server/coordinator/inspector/node_inspector.go @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package inspector + +import ( + "context" + "sync" + "time" + + "github.com/apache/incubator-horaedb-meta/pkg/coderr" + "github.com/apache/incubator-horaedb-meta/pkg/log" + "github.com/apache/incubator-horaedb-meta/server/cluster/metadata" + "github.com/apache/incubator-horaedb-meta/server/storage" + "go.uber.org/zap" +) + +var ErrStartAgain = coderr.NewCodeError(coderr.Internal, "try to start again") +var ErrStopNotStart = coderr.NewCodeError(coderr.Internal, "try to stop a not-started inspector") + +const defaultInspectInterval = time.Second * 5 + +// NodeInspector will inspect node status and remove expired data. +type NodeInspector struct { + logger *zap.Logger + clusterMetadata ClusterMetaDataManipulator + interval time.Duration + + starter sync.Once + // After `Start` is called, the following fields will be initialized + stopCtx context.Context + bgJobCancel context.CancelFunc +} + +// ClusterMetaDataManipulator provides the snapshot for NodeInspector to check and utilities of drop expired shard nodes. +type ClusterMetaDataManipulator interface { + GetClusterSnapshot() metadata.Snapshot + DropShardNodes(context.Context, []storage.ShardNode) error +} + +func NewNodeInspectorWithInterval(logger *zap.Logger, clusterMetadata ClusterMetaDataManipulator, inspectInterval time.Duration) *NodeInspector { + return &NodeInspector{ + logger: logger, + clusterMetadata: clusterMetadata, + interval: inspectInterval, + starter: sync.Once{}, + stopCtx: nil, + bgJobCancel: nil, + } +} + +func NewNodeInspector(logger *zap.Logger, clusterMetadata ClusterMetaDataManipulator) *NodeInspector { + return NewNodeInspectorWithInterval(logger, clusterMetadata, defaultInspectInterval) +} + +func (ni *NodeInspector) Start(ctx context.Context) error { + started := false + ni.starter.Do(func() { + log.Info("node inspector start") + started = true + ni.stopCtx, ni.bgJobCancel = context.WithCancel(ctx) + go func() { + for { + t := time.NewTimer(ni.interval) + select { + case <-ni.stopCtx.Done(): + ni.logger.Info("node inspector is stopped, cancel the bg inspecting") + if !t.Stop() { + <-t.C + } + return + case <-t.C: + } + + ni.inspect(ctx) + } + }() + }) + + if !started { + return ErrStartAgain + } + + return nil +} + +func (ni *NodeInspector) Stop(_ context.Context) error { + if ni.bgJobCancel != nil { + ni.bgJobCancel() + return nil + } + + return ErrStopNotStart +} + +func (ni *NodeInspector) inspect(ctx context.Context) { + // Get latest cluster snapshot. + snapshot := ni.clusterMetadata.GetClusterSnapshot() + expiredShardNodes := findExpiredShardNodes(snapshot) + if len(expiredShardNodes) == 0 { + return + } + + // Try to remove useless data if it exists. + if err := ni.clusterMetadata.DropShardNodes(ctx, expiredShardNodes); err != nil { + log.Error("drop shard node failed", zap.Error(err)) + } +} + +func findExpiredShardNodes(snapshot metadata.Snapshot) []storage.ShardNode { + // In most cases, there is no expired shard nodes so don't pre-allocate the memory here. + expiredNodes := make(map[string]struct{}, 0) + // Check node status. + now := time.Now() + for i := range snapshot.RegisteredNodes { + node := &snapshot.RegisteredNodes[i] + if node.IsExpired(now) { + expiredNodes[node.Node.Name] = struct{}{} + } + } + + expiredShardNodes := make([]storage.ShardNode, 0, len(expiredNodes)) + for _, shardNode := range snapshot.Topology.ClusterView.ShardNodes { + _, ok := expiredNodes[shardNode.NodeName] + if ok { + expiredShardNodes = append(expiredShardNodes, shardNode) + } + } + + return expiredShardNodes +} diff --git a/horaemeta/server/coordinator/inspector/node_inspector_test.go b/horaemeta/server/coordinator/inspector/node_inspector_test.go new file mode 100644 index 0000000000..f119299ed2 --- /dev/null +++ b/horaemeta/server/coordinator/inspector/node_inspector_test.go @@ -0,0 +1,145 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package inspector + +import ( + "context" + "slices" + "sync" + "testing" + "time" + + "github.com/apache/incubator-horaedb-meta/server/cluster/metadata" + "github.com/apache/incubator-horaedb-meta/server/storage" + "github.com/stretchr/testify/assert" + "go.uber.org/zap" +) + +type mockClusterMetaDataManipulator struct { + snapshot metadata.Snapshot + lock sync.Mutex + droppedShardNodes [][]storage.ShardNode +} + +func newMockClusterMetaDataManipulator(shardNodes []storage.ShardNode, registeredNodes []metadata.RegisteredNode) *mockClusterMetaDataManipulator { + var clusterView storage.ClusterView + clusterView.ShardNodes = shardNodes + topology := metadata.Topology{ + ShardViewsMapping: nil, + ClusterView: clusterView, + } + + snapshot := metadata.Snapshot{ + Topology: topology, + RegisteredNodes: registeredNodes, + } + return &mockClusterMetaDataManipulator{ + snapshot: snapshot, + lock: sync.Mutex{}, + droppedShardNodes: make([][]storage.ShardNode, 0), + } +} + +func (n *mockClusterMetaDataManipulator) GetClusterSnapshot() metadata.Snapshot { + return n.snapshot +} + +func (n *mockClusterMetaDataManipulator) DropShardNodes(_ context.Context, shardNodes []storage.ShardNode) error { + n.lock.Lock() + defer n.lock.Unlock() + + n.droppedShardNodes = append(n.droppedShardNodes, shardNodes) + newShardNodes := make([]storage.ShardNode, 0, 2) + for _, node := range n.snapshot.Topology.ClusterView.ShardNodes { + dropped := slices.ContainsFunc(shardNodes, func(droppedNode storage.ShardNode) bool { + return node.NodeName == droppedNode.NodeName + }) + if !dropped { + newShardNodes = append(newShardNodes, node) + } + } + n.snapshot.Topology.ClusterView.ShardNodes = newShardNodes + return nil +} + +func (n *mockClusterMetaDataManipulator) CheckDroppedShardNodes(check func(droppedShardNodes [][]storage.ShardNode)) { + n.lock.Lock() + defer n.lock.Unlock() + + check(n.droppedShardNodes) +} + +func TestStartStopInspector(t *testing.T) { + inspector := NewNodeInspector(zap.NewNop(), newMockClusterMetaDataManipulator(nil, nil)) + + ctx := context.Background() + assert.NoError(t, inspector.Start(ctx)) + assert.Error(t, inspector.Start(ctx)) + + assert.NoError(t, inspector.Stop(ctx)) +} + +func TestInspect(t *testing.T) { + shardNodes := []storage.ShardNode{ + {ID: storage.ShardID(0), ShardRole: storage.ShardRoleLeader, NodeName: "192.168.1.102"}, + {ID: storage.ShardID(1), ShardRole: storage.ShardRoleLeader, NodeName: "192.168.1.102"}, + {ID: storage.ShardID(2), ShardRole: storage.ShardRoleLeader, NodeName: "192.168.1.103"}, + {ID: storage.ShardID(3), ShardRole: storage.ShardRoleLeader, NodeName: "192.168.1.103"}, + } + registeredNodes := []metadata.RegisteredNode{ + { + Node: storage.Node{ + Name: "192.168.1.102", + NodeStats: storage.NodeStats{Lease: 0, Zone: "", NodeVersion: ""}, + LastTouchTime: uint64(time.Now().UnixMilli()), + State: storage.NodeStateOnline, + }, + ShardInfos: nil, + }, + { + // This node should be outdated. + Node: storage.Node{ + Name: "192.168.1.103", + NodeStats: storage.NodeStats{Lease: 0, Zone: "", NodeVersion: ""}, + LastTouchTime: uint64(time.Now().UnixMilli()) - uint64((time.Second * 20)), + State: storage.NodeStateOnline, + }, + ShardInfos: nil, + }, + } + + metadata := newMockClusterMetaDataManipulator(shardNodes, registeredNodes) + inspector := NewNodeInspectorWithInterval(zap.NewNop(), metadata, time.Millisecond*100) + ctx := context.Background() + assert.NoError(t, inspector.Start(ctx)) + + // The inspect should be triggered after 200ms. + time.Sleep(time.Millisecond * 200) + + // The outdated node should be removed by triggered. + metadata.CheckDroppedShardNodes(func(droppedShardNodes [][]storage.ShardNode) { + assert.True(t, len(droppedShardNodes) == 1) + assert.True(t, len(droppedShardNodes[0]) == 2) + assert.Equal(t, droppedShardNodes[0][0], shardNodes[2]) + assert.Equal(t, droppedShardNodes[0][1], shardNodes[3]) + }) + + assert.NoError(t, inspector.Stop(ctx)) +} diff --git a/horaemeta/server/coordinator/scheduler/manager/scheduler_manager.go b/horaemeta/server/coordinator/scheduler/manager/scheduler_manager.go index 0ed97f87db..51246a569b 100644 --- a/horaemeta/server/coordinator/scheduler/manager/scheduler_manager.go +++ b/horaemeta/server/coordinator/scheduler/manager/scheduler_manager.go @@ -203,7 +203,7 @@ func (callback *schedulerWatchCallback) OnShardRegistered(_ context.Context, _ w func (callback *schedulerWatchCallback) OnShardExpired(ctx context.Context, event watch.ShardExpireEvent) error { oldLeader := event.OldLeaderNode shardID := event.ShardID - return callback.c.DropShardNode(ctx, []storage.ShardNode{ + return callback.c.DropShardNodes(ctx, []storage.ShardNode{ { ID: shardID, ShardRole: storage.ShardRoleLeader, diff --git a/horaemeta/server/coordinator/shard_picker_test.go b/horaemeta/server/coordinator/shard_picker_test.go index 3b69d9a4d1..9cbcc4d1c0 100644 --- a/horaemeta/server/coordinator/shard_picker_test.go +++ b/horaemeta/server/coordinator/shard_picker_test.go @@ -83,7 +83,7 @@ func TestLeastTableShardPicker(t *testing.T) { // drop shard node 1, shard 1 should not be picked. for _, shardNode := range snapshot.Topology.ClusterView.ShardNodes { if shardNode.ID == 1 { - err = c.GetMetadata().DropShardNode(ctx, []storage.ShardNode{shardNode}) + err = c.GetMetadata().DropShardNodes(ctx, []storage.ShardNode{shardNode}) re.NoError(err) } } diff --git a/horaemeta/server/service/http/api.go b/horaemeta/server/service/http/api.go index 4476e81c63..5f4a36eaee 100644 --- a/horaemeta/server/service/http/api.go +++ b/horaemeta/server/service/http/api.go @@ -230,7 +230,7 @@ func (a *API) dropNodeShards(req *http.Request) apiFuncResult { } } - if err := c.GetMetadata().DropShardNode(req.Context(), targetShardNodes); err != nil { + if err := c.GetMetadata().DropShardNodes(req.Context(), targetShardNodes); err != nil { log.Error("drop node shards failed", zap.Error(err)) return errResult(ErrDropNodeShards, err.Error()) } From 54a5db725e674934ca490a64118d50df1b1f4cde Mon Sep 17 00:00:00 2001 From: Jiacai Liu Date: Mon, 18 Mar 2024 19:05:23 +0800 Subject: [PATCH 5/5] chore: remove tini binary (#1503) ## Rationale Our repo should not contain any binaries. ## Detailed Changes - Download tini instead of hard copy ## Test Plan CI Also I use command below to ensure no other binaries exists. ``` fd -t file --exclude target --exec file {} \; | grep -v ASCII | grep -v UTF-8 ``` --- .gitignore | 1 + Dockerfile | 3 ++- docker/tini | Bin 24064 -> 0 bytes horaemeta/Dockerfile | 3 ++- horaemeta/docker/tini | Bin 24064 -> 0 bytes 5 files changed, 5 insertions(+), 2 deletions(-) delete mode 100644 docker/tini delete mode 100644 horaemeta/docker/tini diff --git a/.gitignore b/.gitignore index 1cdba5be70..f3b4b08ab3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ integration_tests/dist_query/output .tools bin coverage.txt +tini diff --git a/Dockerfile b/Dockerfile index 0de3d643b4..6e94e51a70 100644 --- a/Dockerfile +++ b/Dockerfile @@ -46,7 +46,8 @@ RUN chmod +x /usr/bin/horaedb-server COPY ./docker/entrypoint.sh /entrypoint.sh COPY ./docs/minimal.toml /etc/horaedb/horaedb.toml -COPY ./docker/tini /tini +ARG TINI_VERSION=v0.19.0 +ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini RUN chmod +x /tini ARG USER=horae diff --git a/docker/tini b/docker/tini deleted file mode 100644 index 03af82f09e6484df819313cf9fec158d6b4a879d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24064 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 W>DCFp+ZcCB`+u|H=v2uo^#1{xm}Ef! diff --git a/horaemeta/Dockerfile b/horaemeta/Dockerfile index 5841c2a87e..9512582af7 100644 --- a/horaemeta/Dockerfile +++ b/horaemeta/Dockerfile @@ -44,7 +44,8 @@ RUN chmod +x /usr/bin/horaemeta-server COPY ./docker/entrypoint.sh /entrypoint.sh COPY ./config/example-standalone.toml /etc/horaemeta/horaemeta.toml -COPY ./docker/tini /tini +ARG TINI_VERSION=v0.19.0 +ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini RUN chmod +x /tini ARG USER horae diff --git a/horaemeta/docker/tini b/horaemeta/docker/tini deleted file mode 100644 index 03af82f09e6484df819313cf9fec158d6b4a879d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24064 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 W>DCFp+ZcCB`+u|H=v2uo^#1{xm}Ef!