This is an automated email from the ASF dual-hosted git repository.
wuzhiguo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/bigtop-manager.git
The following commit(s) were added to refs/heads/main by this push:
new a2bc56f0 BIGTOP-4445: Add Apache Doris to extra stack (#231)
a2bc56f0 is described below
commit a2bc56f031952ad6635c05d71238e98bbde68e90
Author: timyuer <[email protected]>
AuthorDate: Sat Jul 19 13:34:43 2025 +0800
BIGTOP-4445: Add Apache Doris to extra stack (#231)
---
.licenserc.yaml | 2 +
.../service/ComponentCommandServiceGrpcImpl.java | 5 +-
bigtop-manager-agent/src/main/resources/bin/env.sh | 4 +-
bigtop-manager-bom/pom.xml | 13 ++
.../bigtop/manager/common/constants/Constants.java | 2 +
.../bigtop/manager/common/shell/ShellResult.java | 4 +
.../src/main/resources/scripts/setup-agent.sh | 2 +
.../services/doris/configuration/doris-be-conf.xml | 181 ++++++++++++++++++
.../services/doris/configuration/doris-env.sh.xml | 56 ++++++
.../services/doris/configuration/doris-fe-conf.xml | 163 +++++++++++++++++
.../doris/configuration/doris-sysctl.conf.xml | 53 ++++++
.../services/doris/configuration/doris.conf.xml | 54 ++++++
.../stacks/extra/1.0.0/services/doris/metainfo.xml | 75 ++++++++
.../stacks/extra/1.0.0/services/doris/order.json | 8 +
.../bigtop-manager-stack-bigtop/pom.xml | 108 -----------
.../manager/stack/bigtop/utils/HdfsUtil.java | 147 ---------------
.../stack/core/utils/linux/LinuxFileUtils.java | 1 +
.../stack/core/utils/linux/LinuxOSUtils.java | 11 ++
.../bigtop-manager-stack-extra/pom.xml | 4 +
.../stack/extra/v1_0_0/doris/DorisBEScript.java | 104 +++++++++++
.../stack/extra/v1_0_0/doris/DorisFEScript.java | 124 +++++++++++++
.../stack/extra/v1_0_0/doris/DorisParams.java | 202 +++++++++++++++++++++
.../stack/extra/v1_0_0/doris/DorisService.java | 185 +++++++++++++++++++
.../stack/extra/v1_0_0/doris/DorisSetup.java | 110 +++++++++++
.../stack/extra/v1_0_0/doris/DorisTool.java | 109 +++++++++++
bigtop-manager-ui/src/assets/images/doris.png | Bin 0 -> 5456 bytes
26 files changed, 1470 insertions(+), 257 deletions(-)
diff --git a/.licenserc.yaml b/.licenserc.yaml
index d880a9c7..4276c965 100644
--- a/.licenserc.yaml
+++ b/.licenserc.yaml
@@ -50,6 +50,8 @@ dependency:
- pom.xml
- bigtop-manager-bom/pom.xml
licenses:
+ - name: org.apache.arrow:flight-sql-jdbc-driver
+ license: Apache-2.0
- name: org.apache.hadoop.thirdparty:hadoop-shaded-protobuf_3_7
license: Apache-2.0
- name: org.apache.hadoop.thirdparty:hadoop-shaded-guava
diff --git
a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/service/ComponentCommandServiceGrpcImpl.java
b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/service/ComponentCommandServiceGrpcImpl.java
index 2a091a4e..50171d76 100644
---
a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/service/ComponentCommandServiceGrpcImpl.java
+++
b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/grpc/service/ComponentCommandServiceGrpcImpl.java
@@ -18,6 +18,7 @@
*/
package org.apache.bigtop.manager.agent.grpc.service;
+import org.apache.bigtop.manager.agent.cache.Caches;
import org.apache.bigtop.manager.common.shell.ShellResult;
import org.apache.bigtop.manager.common.utils.JsonUtils;
import org.apache.bigtop.manager.grpc.generated.ComponentCommandReply;
@@ -36,8 +37,10 @@ public class ComponentCommandServiceGrpcImpl extends
ComponentCommandServiceGrpc
@Override
public void exec(ComponentCommandRequest request,
StreamObserver<ComponentCommandReply> responseObserver) {
- ComponentCommandPayload payload =
JsonUtils.readFromString(request.getPayload(), ComponentCommandPayload.class);
try {
+ log.info("Running task {}", Caches.RUNNING_TASK);
+ ComponentCommandPayload payload =
+ JsonUtils.readFromString(request.getPayload(),
ComponentCommandPayload.class);
ShellResult shellResult = StackExecutor.execute(payload);
ComponentCommandReply reply = ComponentCommandReply.newBuilder()
.setCode(shellResult.getExitCode())
diff --git a/bigtop-manager-agent/src/main/resources/bin/env.sh
b/bigtop-manager-agent/src/main/resources/bin/env.sh
index 882b68eb..20efe35f 100755
--- a/bigtop-manager-agent/src/main/resources/bin/env.sh
+++ b/bigtop-manager-agent/src/main/resources/bin/env.sh
@@ -62,5 +62,7 @@ find_java() {
find_java
-export JAVA_OPTS=""
+JAVA_OPTS="-server -Duser.timezone=${SPRING_JACKSON_TIME_ZONE} -Xms4g -Xmx4g
-Xmn2g -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGCDateStamps
-XX:+PrintGCDetails -Xloggc:gc.log -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=dump.hprof"
+JAVA_OPTS="${JAVA_OPTS}
--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED"
+export JAVA_OPTS
export JAVA_CMD
diff --git a/bigtop-manager-bom/pom.xml b/bigtop-manager-bom/pom.xml
index 4b078b9f..a361d541 100644
--- a/bigtop-manager-bom/pom.xml
+++ b/bigtop-manager-bom/pom.xml
@@ -57,6 +57,8 @@
<mybatis-spring-boot-starter.version>3.0.3</mybatis-spring-boot-starter.version>
<pagehelper-spring-boot-starter.version>2.1.0</pagehelper-spring-boot-starter.version>
<victools.version>4.29.0</victools.version>
+ <arrow.version>18.3.0</arrow.version>
+ <netty-buffer.version>4.1.123.Final</netty-buffer.version>
</properties>
<dependencyManagement>
@@ -237,7 +239,18 @@
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.arrow</groupId>
+ <artifactId>flight-sql-jdbc-driver</artifactId>
+ <version>${arrow.version}</version>
+ </dependency>
+
<!-- gRPC -->
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-netty</artifactId>
+ <version>${grpc.version}</version>
+ </dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
diff --git
a/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/constants/Constants.java
b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/constants/Constants.java
index d0dbf94c..e5ff45c7 100644
---
a/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/constants/Constants.java
+++
b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/constants/Constants.java
@@ -33,4 +33,6 @@ public final class Constants {
public static final String PERMISSION_777 = "777";
public static final String ROOT_USER = "root";
+
+ public static final String ROOT_GROUP = "root";
}
diff --git
a/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/shell/ShellResult.java
b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/shell/ShellResult.java
index eb998e1b..a5642b28 100644
---
a/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/shell/ShellResult.java
+++
b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/shell/ShellResult.java
@@ -62,4 +62,8 @@ public class ShellResult {
public static ShellResult fail() {
return fail("Run shell fail.");
}
+
+ public String formatMessage(String message) {
+ return MessageFormat.format(message + ", output: [{0}], err: [{1}]",
output, errMsg);
+ }
}
diff --git a/bigtop-manager-server/src/main/resources/scripts/setup-agent.sh
b/bigtop-manager-server/src/main/resources/scripts/setup-agent.sh
index fdeda989..a7bdaef6 100644
--- a/bigtop-manager-server/src/main/resources/scripts/setup-agent.sh
+++ b/bigtop-manager-server/src/main/resources/scripts/setup-agent.sh
@@ -38,6 +38,8 @@ error () {
}
check_sudo() {
+ # Refresh sudo privileges, currently only appears in openEuler24.03
+ sudo visudo -c 2>/dev/null || true
if ! sudo -n true 2>/dev/null; then
error "User '$USER' doesn't have sudo privileges"
exit 1
diff --git
a/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-be-conf.xml
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-be-conf.xml
new file mode 100644
index 00000000..5fed4359
--- /dev/null
+++
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-be-conf.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0"?>
+<!--
+ ~ 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.
+-->
+
+<configuration>
+ <property>
+ <name>storage_root_path</name>
+ <display-name>storage_root_path</display-name>
+ <value>${doris_be_home}/storage</value>
+ <description>
+ data root path, separate by ';'.you can specify the storage medium
of each root path, HDD or SSD.
+ you can add capacity limit at the end of each root path, separate
by ','.
+ If the user does not use a mix of SSD and HDD disks,
+ they do not need to configure the configuration methods in Example
1 and Example 2 below, but only need to specify the storage directory;
+ they also do not need to modify the default storage media
configuration of FE.
+ </description>
+ </property>
+ <property>
+ <name>be_port</name>
+ <value>9060</value>
+ <description>The port of the thrift server on BE which used to receive
requests from FE.</description>
+ </property>
+ <property>
+ <name>webserver_port</name>
+ <value>8041</value>
+ </property>
+ <property>
+ <name>heartbeat_service_port</name>
+ <value>9050</value>
+ <description>Heartbeat service port (thrift) on BE, used to receive
heartbeat from FE.</description>
+ </property>
+ <property>
+ <name>brpc_port</name>
+ <value>8060</value>
+ <description>The port of BRPC on BE, used for communication between
BEs.</description>
+ </property>
+ <property>
+ <name>be_arrow_flight_sql_port</name>
+ <value>9091</value>
+ <description>be_arrow_flight_sql_port.</description>
+ </property>
+ <property>
+ <name>content</name>
+ <value>
+ <![CDATA[
+# 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.
+
+JAVA_HOME=${java_home}
+
+CUR_DATE=`date +%Y%m%d-%H%M%S`
+
+JAVA_HOME=${java_home}
+
+# Log dir
+LOG_DIR=${doris_be_log_dir}
+PID_DIR=${doris_be_pid_dir}
+
+# For jdk 8
+JAVA_OPTS="-Dfile.encoding=UTF-8 -Xmx4096m -DlogPath=$LOG_DIR/jni.log
-Xloggc:$DORIS_HOME/log/be.gc.log.$CUR_DATE
-Djavax.security.auth.useSubjectCredsOnly=false -Dsun.security.krb5.debug=true
-Dsun.java.command=DorisBE -XX:-CriticalJNINatives"
+
+# For jdk 9+, this JAVA_OPTS will be used as default JVM options
+JAVA_OPTS_FOR_JDK_9="-Dfile.encoding=UTF-8 -Xmx4096m
-DlogPath=$DORIS_HOME/log/jni.log -Xlog:gc:$LOG_DIR/be.gc.log.$CUR_DATE
-Djavax.security.auth.useSubjectCredsOnly=false -Dsun.security.krb5.debug=true
-Dsun.java.command=DorisBE -XX:-CriticalJNINatives
--add-opens=java.base/java.nio=ALL-UNNAMED"
+
+# For jdk 17+, this JAVA_OPTS will be used as default JVM options
+JAVA_OPTS_FOR_JDK_17="-Dfile.encoding=UTF-8 -Xmx4096m
-DlogPath=$LOG_DIR/jni.log -Xlog:gc:$LOG_DIR/be.gc.log.$CUR_DATE
-Djavax.security.auth.useSubjectCredsOnly=false -Dsun.security.krb5.debug=true
-Dsun.java.command=DorisBE -XX:-CriticalJNINatives
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=java.base/java.nio=ALL-UNNAMED"
+
+# since 1.2, the JAVA_HOME need to be set to run BE process.
+# JAVA_HOME=/path/to/jdk/
+
+#
https://github.com/apache/doris/blob/master/docs/zh-CN/community/developer-guide/debug-tool.md#jemalloc-heap-profile
+# https://jemalloc.net/jemalloc.3.html
+JEMALLOC_CONF="percpu_arena:percpu,background_thread:true,metadata_thp:auto,muzzy_decay_ms:5000,dirty_decay_ms:5000,oversize_threshold:0,prof:false,lg_prof_interval:-1"
+JEMALLOC_PROF_PRFIX="jemalloc_heap_profile_"
+
+# ports for admin, web, heartbeat service
+be_port = ${be_port}
+webserver_port = ${webserver_port}
+heartbeat_service_port = ${heartbeat_service_port}
+brpc_port = ${brpc_port}
+arrow_flight_sql_port = ${be_arrow_flight_sql_port}
+
+# HTTPS configures
+enable_https = false
+# path of certificate in PEM format.
+ssl_certificate_path = "$DORIS_HOME/conf/cert.pem"
+# path of private key in PEM format.
+ssl_private_key_path = "$DORIS_HOME/conf/key.pem"
+
+
+# Choose one if there are more than one ip except loopback address.
+# Note that there should at most one ip match this list.
+# If no ip match this rule, will choose one randomly.
+# use CIDR format, e.g. 10.10.10.0/24 or IP format, e.g. 10.10.10.1
+# Default value is empty.
+# priority_networks = 10.10.10.0/24;192.168.0.0/16
+
+# data root path, separate by ';'
+# You can specify the storage type for each root path, HDD (cold data) or SSD
(hot data)
+# eg:
+# storage_root_path = /home/disk1/doris;/home/disk2/doris;/home/disk2/doris
+# storage_root_path =
/home/disk1/doris,medium:SSD;/home/disk2/doris,medium:SSD;/home/disk2/doris,medium:HDD
+# /home/disk2/doris,medium:HDD(default)
+#
+# you also can specify the properties by setting '<property>:<value>',
separate by ','
+# property 'medium' has a higher priority than the extension of path
+#
+# Default value is ${DORIS_HOME}/storage, you should create it by hand.
+# storage_root_path = ${DORIS_HOME}/storage
+storage_root_path = ${storage_root_path}
+
+# Default dirs to put jdbc drivers,default value is ${DORIS_HOME}/jdbc_drivers
+# jdbc_drivers_dir = ${DORIS_HOME}/jdbc_drivers
+
+# Advanced configurations
+# INFO, WARNING, ERROR, FATAL
+sys_log_level = INFO
+# sys_log_roll_mode = SIZE-MB-1024
+# sys_log_roll_num = 10
+# sys_log_verbose_modules = *
+# log_buffer_level = -1
+# palo_cgroups
+
+# aws sdk log level
+# Off = 0,
+# Fatal = 1,
+# Error = 2,
+# Warn = 3,
+# Info = 4,
+# Debug = 5,
+# Trace = 6
+# Default to turn off aws sdk log, because aws sdk errors that need to be
cared will be output through Doris logs
+aws_log_level=0
+## If you are not running in aws cloud, you can disable EC2 metadata
+AWS_EC2_METADATA_DISABLED=true
+
+sys_log_dir = ${doris_be_log_dir}
+
+enable_query_memory_overcommit=true
+enable_single_replica_load =true
+
+enable_token_check = false
+
+]]>
+ </value>
+ <description>Template for be.conf</description>
+ <attrs>
+ <type>longtext</type>
+ </attrs>
+ </property>
+</configuration>
diff --git
a/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-env.sh.xml
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-env.sh.xml
new file mode 100644
index 00000000..b4d9887a
--- /dev/null
+++
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-env.sh.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!--
+ ~ 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.
+-->
+
+<configuration>
+ <property>
+ <name>doris_fe_log_dir</name>
+ <value>${doris_fe_home}/log</value>
+ </property>
+ <property>
+ <name>doris_be_log_dir</name>
+ <value>${doris_be_home}/log</value>
+ </property>
+ <property>
+ <name>doris_fe_pid_dir</name>
+ <value>/var/run/doris-fe</value>
+ <display-name>doris PID dir</display-name>
+ </property>
+ <property>
+ <name>doris_be_pid_dir</name>
+ <value>/var/run/doris-be</value>
+ <display-name>doris PID dir</display-name>
+ </property>
+ <property>
+ <name>doris_user_nofile_soft</name>
+ <value>262144</value>
+ <description>Max open files limit setting for doris user.</description>
+ </property>
+ <property>
+ <name>doris_user_nofile_hard</name>
+ <value>262144</value>
+ <description>Max number of processes limit setting for doris
user.</description>
+ </property>
+ <property>
+ <name>vm_max_map_count</name>
+ <value>2000000</value>
+ <description>Max number of processes limit setting for doris
user.</description>
+ </property>
+</configuration>
+
diff --git
a/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-fe-conf.xml
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-fe-conf.xml
new file mode 100644
index 00000000..d6ee0452
--- /dev/null
+++
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-fe-conf.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0"?>
+<!--
+ ~ 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.
+-->
+
+<configuration>
+ <property>
+ <name>meta_dir</name>
+ <display-name>meta_dir</display-name>
+ <value>${doris_fe_home}/doris-meta</value>
+ <description>Default: DORIS_HOME_DIR + "/doris-meta".
+ Doris meta data will be saved here.The storage of this dir is
highly recommended as to be.</description>
+ </property>
+ <property>
+ <name>http_port</name>
+ <value>8030</value>
+ <description>HTTP bind port. All FE http ports must be same
currently.</description>
+ </property>
+ <property>
+ <name>query_port</name>
+ <value>9030</value>
+ <description>FE MySQL server port.</description>
+ </property>
+ <property>
+ <name>rpc_port</name>
+ <value>9020</value>
+ <description>FE Thrift Server port.</description>
+ </property>
+ <property>
+ <name>edit_log_port</name>
+ <value>9010</value>
+ <description>edit log port.</description>
+ </property>
+ <property>
+ <name>fe_arrow_flight_sql_port</name>
+ <value>9090</value>
+ <description>fe_arrow_flight_sql_port.</description>
+ </property>
+ <property>
+ <name>content</name>
+ <value>
+ <![CDATA[
+# 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.
+
+#####################################################################
+## The uppercase properties are read and exported by bin/start_fe.sh.
+## To see all Frontend configurations,
+## see fe/src/org/apache/doris/common/Config.java
+#####################################################################
+
+JAVA_HOME=${java_home}
+
+CUR_DATE=`date +%Y%m%d-%H%M%S`
+
+# Log dir
+LOG_DIR = ${doris_fe_log_dir}
+PID_DIR=${doris_fe_pid_dir}
+
+# CMS JAVA OPTS
+# JAVA_OPTS="-Dsun.security.krb5.debug=true
-Djavax.security.auth.useSubjectCredsOnly=false -Xss4m -Xmx8192m -XX:+UseMembar
-XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=7 -XX:+PrintGCDateStamps
-XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
-XX:+CMSClassUnloadingEnabled -XX:-CMSParallelRemarkEnabled
-XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0
-Xloggc:$DORIS_HOME/log/fe.gc.log.$CUR_DATE"
+
+# G1 JAVA OPTS
+JAVA_OPTS="-Dfile.encoding=UTF-8
-Djavax.security.auth.useSubjectCredsOnly=false -Xss4m -Xmx4096m
-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:MaxGCPauseMillis=200
-XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:$LOG_DIR/fe.gc.log.$CUR_DATE
-Dlog4j2.formatMsgNoLookups=true"
+
+# For jdk 9+, this JAVA_OPTS_FOR_JDK_9 will be used as default CMS JVM options
+# JAVA_OPTS_FOR_JDK_9="-Dsun.security.krb5.debug=true
-Djavax.security.auth.useSubjectCredsOnly=false -Xss4m -Xmx8192m
-XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=7 -XX:+CMSClassUnloadingEnabled
-XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=80
-XX:SoftRefLRUPolicyMSPerMB=0
-Xlog:gc*:$DORIS_HOME/log/fe.gc.log.$CUR_DATE:time"
+
+# For jdk 9+, this JAVA_OPTS_FOR_JDK_9 will be used as default G1 JVM options
+JAVA_OPTS_FOR_JDK_9="-Dfile.encoding=UTF-8
-Djavax.security.auth.useSubjectCredsOnly=false -Xss4m -Xmx4096m -XX:+UseG1GC
-XX:MaxGCPauseMillis=200 -Xlog:gc*:$LOG_DIR/fe.gc.log.$CUR_DATE:time
-Dlog4j2.formatMsgNoLookups=true"
+
+# For jdk 17+, this JAVA_OPTS will be used as default JVM options
+JAVA_OPTS_FOR_JDK_17="-Dfile.encoding=UTF-8
-Djavax.security.auth.useSubjectCredsOnly=false -XX:+UseZGC -Xmx4096m -Xms8192m
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$LOG_DIR/
-Xlog:gc*:$LOG_DIR/fe.gc.log.$CUR_DATE:time"
+
+##
+## the lowercase properties are read by main program.
+##
+
+# store metadata, must be created before start FE.
+# Default value is ${DORIS_HOME}/doris-meta
+# meta_dir = ${DORIS_HOME}/doris-meta
+meta_dir = ${meta_dir}
+
+# Default dirs to put jdbc drivers,default value is ${DORIS_HOME}/jdbc_drivers
+# jdbc_drivers_dir = ${DORIS_HOME}/jdbc_drivers
+
+
+http_port = ${http_port}
+rpc_port = ${rpc_port}
+query_port = ${query_port}
+edit_log_port = ${edit_log_port}
+arrow_flight_sql_port = ${fe_arrow_flight_sql_port}
+
+# Choose one if there are more than one ip except loopback address.
+# Note that there should at most one ip match this list.
+# If no ip match this rule, will choose one randomly.
+# use CIDR format, e.g. 10.10.10.0/24 or IP format, e.g. 10.10.10.1
+# Default value is empty.
+# priority_networks = 10.10.10.0/24;192.168.0.0/16
+
+# Advanced configurations
+# log_roll_size_mb = 1024
+# INFO, WARN, ERROR, FATAL
+sys_log_level = INFO
+# NORMAL, BRIEF, ASYNC
+sys_log_mode = NORMAL
+# sys_log_roll_num = 10
+# sys_log_verbose_modules = org.apache.doris
+# audit_log_dir = $LOG_DIR
+# audit_log_modules = slow_query, query
+# audit_log_roll_num = 10
+# meta_delay_toleration_second = 10
+# qe_max_connection = 1024
+# qe_query_timeout_second = 300
+# qe_slow_log_ms = 5000
+
+sys_log_dir = ${doris_fe_log_dir}
+audit_log_dir = ${doris_fe_log_dir}
+
+# FQDN
+enable_fqdn_mode = true
+
+enable_single_replica_load = true
+
+enable_token_check = false
+
+]]>
+ </value>
+ <description>Template for fe.conf</description>
+ <attrs>
+ <type>longtext</type>
+ </attrs>
+ </property>
+</configuration>
diff --git
a/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-sysctl.conf.xml
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-sysctl.conf.xml
new file mode 100644
index 00000000..d8e57eda
--- /dev/null
+++
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris-sysctl.conf.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!--
+ ~ 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.
+-->
+
+<configuration>
+ <property>
+ <name>content</name>
+ <display-name>doris-sysctl.conf template</display-name>
+ <description>This is the freemarker template for
/etc/sysctl.d/doris-sysctl.conf file</description>
+ <value><![CDATA[
+#
+# 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.
+#
+
+vm.max_map_count=${vm_max_map_count}
+
+]]>
+ </value>
+ <attrs>
+ <type>longtext</type>
+ </attrs>
+ </property>
+</configuration>
diff --git
a/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris.conf.xml
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris.conf.xml
new file mode 100644
index 00000000..2822c641
--- /dev/null
+++
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/configuration/doris.conf.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!--
+ ~ 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.
+-->
+
+<configuration>
+ <property>
+ <name>content</name>
+ <display-name>doris.conf template</display-name>
+ <description>This is the freemarker template for doris
file</description>
+ <value><![CDATA[
+#
+# 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.
+#
+
+${doris_user} - nofile ${doris_user_nofile_soft}
+${doris_user} - nproc ${doris_user_nofile_hard}
+
+]]>
+ </value>
+ <attrs>
+ <type>longtext</type>
+ </attrs>
+ </property>
+</configuration>
diff --git
a/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/metainfo.xml
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/metainfo.xml
new file mode 100644
index 00000000..8455abdf
--- /dev/null
+++
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/metainfo.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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
+ ~
+ ~ https://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.
+-->
+
+<metainfo>
+ <service>
+ <name>doris</name>
+ <display-name>Doris</display-name>
+ <desc>
+ Apache Doris is a modern data warehouse for real-time analytics.
+ It delivers lightning-fast analytics on real-time data at scale.
+ </desc>
+ <version>2.1.10</version>
+ <user>doris</user>
+ <license>Apache-2.0</license>
+
+ <components>
+ <component>
+ <name>doris_fe</name>
+ <display-name>Doris Frontend</display-name>
+ <category>server</category>
+ <cardinality>1+</cardinality>
+ </component>
+
+ <component>
+ <name>doris_be</name>
+ <display-name>Doris Backend</display-name>
+ <category>server</category>
+ <cardinality>1+</cardinality>
+ </component>
+
+ </components>
+
+ <package-specifics>
+ <package-specific>
+ <architectures>
+ <arch>x86_64</arch>
+ </architectures>
+ <packages>
+ <package>
+ <name>apache-doris-2.1.10-bin-x64-noavx2.tar.gz</name>
+
<checksum>SHA-512:4238436ad0a6eedc4918018b90a71d39b59c640a96188a007ed109a8c317357bdb6bfd3ed7a8768ebf1d72df10dffd19f5c597235da5e693bd587f4326edcc14</checksum>
+ </package>
+ </packages>
+ </package-specific>
+ <package-specific>
+ <architectures>
+ <arch>aarch64</arch>
+ </architectures>
+ <packages>
+ <package>
+ <name>apache-doris-2.1.10-bin-arm64.tar.gz</name>
+
<checksum>SHA-512:bf9140c547d7b30ff25276fb8a44e443f8518876edd60d56460bc2e60f12c4200261ece60a43909b7c0cd4758621ba9fe85a58c29fb056a43947ee1d2fb27cea</checksum>
+ </package>
+ </packages>
+ </package-specific>
+ </package-specifics>
+ </service>
+</metainfo>
diff --git
a/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/order.json
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/order.json
new file mode 100644
index 00000000..dcb838c4
--- /dev/null
+++
b/bigtop-manager-server/src/main/resources/stacks/extra/1.0.0/services/doris/order.json
@@ -0,0 +1,8 @@
+{
+ "BE-START": [
+ "FE-START"
+ ],
+ "FE-STOP": [
+ "BE-STOP"
+ ]
+}
diff --git a/bigtop-manager-stack/bigtop-manager-stack-bigtop/pom.xml
b/bigtop-manager-stack/bigtop-manager-stack-bigtop/pom.xml
index 3f5074e0..059ff7eb 100644
--- a/bigtop-manager-stack/bigtop-manager-stack-bigtop/pom.xml
+++ b/bigtop-manager-stack/bigtop-manager-stack-bigtop/pom.xml
@@ -39,114 +39,6 @@
<groupId>org.apache.bigtop</groupId>
<artifactId>bigtop-manager-stack-core</artifactId>
</dependency>
-
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-common</artifactId>
- <version>${hadoop.version}</version>
- <exclusions>
- <exclusion>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- <exclusion>
- <groupId>ch.qos.reload4j</groupId>
- <artifactId>reload4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-reload4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper-jute</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.google.protobuf</groupId>
- <artifactId>protobuf-java</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-hdfs</artifactId>
- <version>${hadoop.version}</version>
- <exclusions>
- <exclusion>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- <exclusion>
- <groupId>ch.qos.reload4j</groupId>
- <artifactId>reload4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-reload4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper-jute</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.google.protobuf</groupId>
- <artifactId>protobuf-java</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-client</artifactId>
- <version>${hadoop.version}</version>
- <exclusions>
- <exclusion>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- <exclusion>
- <groupId>ch.qos.reload4j</groupId>
- <artifactId>reload4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-reload4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper-jute</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.google.protobuf</groupId>
- <artifactId>protobuf-java</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
</dependencies>
</project>
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-bigtop/src/main/java/org/apache/bigtop/manager/stack/bigtop/utils/HdfsUtil.java
b/bigtop-manager-stack/bigtop-manager-stack-bigtop/src/main/java/org/apache/bigtop/manager/stack/bigtop/utils/HdfsUtil.java
deleted file mode 100644
index d16b54ba..00000000
---
a/bigtop-manager-stack/bigtop-manager-stack-bigtop/src/main/java/org/apache/bigtop/manager/stack/bigtop/utils/HdfsUtil.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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
- *
- * https://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 org.apache.bigtop.manager.stack.bigtop.utils;
-
-import org.apache.bigtop.manager.stack.core.exception.StackException;
-import org.apache.bigtop.manager.stack.core.utils.LocalSettings;
-
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.security.UserGroupInformation;
-
-import lombok.Data;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.File;
-import java.net.URI;
-import java.security.PrivilegedAction;
-import java.text.MessageFormat;
-import java.util.List;
-
-@Data
-@Slf4j
-public class HdfsUtil {
-
- /**
- * Create directory on hdfs if not exist
- *
- * @param user the system user to create the directory, which will
infect the directory permission
- * @param directory the directory path on hdfs
- */
- public static void createDirectory(String user, String directory) {
- UserGroupInformation ugi = UserGroupInformation.createRemoteUser(user);
- try {
- ugi.doAs((PrivilegedAction<Void>) () -> {
- try (FileSystem fs = getFileSystem()) {
- // Create dest dir if not exist
- Path destDirPath = new Path(directory);
- if (!fs.exists(destDirPath)) {
- log.info("Creating directory [{}] on hdfs",
destDirPath);
- fs.mkdirs(destDirPath);
- }
- } catch (Exception e) {
- log.error("Error while creating directory on hdfs", e);
- throw new StackException(e);
- }
-
- return null;
- });
- } catch (Exception e) {
- log.error("Error while creating directory on hdfs", e);
- throw new StackException(e);
- }
- }
-
- /**
- * Upload file to hdfs, this will keep original filename on hdfs
- *
- * @param user the system user to upload the file, which will
infect the file permission
- * @param localFilePath the local file path
- * @param destDir the destination directory on hdfs
- */
- public static void uploadFile(String user, String localFilePath, String
destDir) {
- uploadFile(user, localFilePath, destDir, null);
- }
-
- /**
- * Upload file to hdfs
- *
- * @param user the system user to upload the file, which will
infect the file permission
- * @param localFilePath the local file path
- * @param destDir the destination directory on hdfs
- * @param destFilename the destination filename on hdfs, if null, use the
original filename
- */
- public static void uploadFile(String user, String localFilePath, String
destDir, String destFilename) {
- UserGroupInformation ugi = UserGroupInformation.createRemoteUser(user);
- try {
- ugi.doAs((PrivilegedAction<Void>) () -> {
- try (FileSystem fs = getFileSystem()) {
- // Create dest dir if not exist
- Path destDirPath = new Path(destDir);
- if (!fs.exists(destDirPath)) {
- log.info("Creating directory [{}] on hdfs",
destDirPath);
- fs.mkdirs(destDirPath);
- }
-
- // upload file
- String filename = destFilename == null
- ?
localFilePath.substring(localFilePath.lastIndexOf(File.separator) + 1)
- : destFilename;
- Path destFilePath = new Path(destDir, filename);
- if (!fs.exists(destFilePath)) {
- log.info("Uploading [{}] to hdfs [{}]", localFilePath,
destFilePath);
- fs.copyFromLocalFile(new Path(localFilePath),
destFilePath);
- }
- } catch (Exception e) {
- log.error("Error while uploading file to hdfs", e);
- throw new StackException(e);
- }
-
- return null;
- });
- } catch (Exception e) {
- log.error("Error while uploading file to hdfs", e);
- throw new StackException(e);
- }
- }
-
- /**
- * Get the hdfs FileSystem instance
- *
- * @return the hdfs FileSystem instance
- * @throws Exception if any error occurs
- */
- private static FileSystem getFileSystem() throws Exception {
- Configuration conf = new Configuration();
- conf.addResource(new Path("/etc/hadoop/conf/core-site.xml"));
- conf.addResource(new Path("/etc/hadoop/conf/hdfs-site.xml"));
-
- List<String> namenodeList = LocalSettings.hosts("namenode");
- if (CollectionUtils.isEmpty(namenodeList)) {
- String msg = "No namenode found in the cluster";
- log.error(msg);
- throw new StackException(msg);
- }
-
- String hdfsUri = MessageFormat.format("hdfs://{0}:8020",
namenodeList.get(0));
- return FileSystem.get(new URI(hdfsUri), conf);
- }
-}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxFileUtils.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxFileUtils.java
index fbee45be..3d4d1b7f 100644
---
a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxFileUtils.java
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxFileUtils.java
@@ -178,6 +178,7 @@ public class LinuxFileUtils {
try {
ShellResult shellResult = sudoExecCmd(builderParameters);
if (shellResult.getExitCode() != MessageConstants.SUCCESS_CODE) {
+ log.error(shellResult.formatMessage("Failed to create
directory"));
throw new StackException(shellResult.getErrMsg());
}
} catch (IOException e) {
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxOSUtils.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxOSUtils.java
index 916dea6f..f105e659 100644
---
a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxOSUtils.java
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxOSUtils.java
@@ -39,6 +39,17 @@ import static
org.apache.bigtop.manager.common.constants.Constants.ROOT_USER;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class LinuxOSUtils {
+ /**
+ * Execute command with root user
+ *
+ * @param command command
+ * @return result of execute command
+ * @throws IOException errors
+ */
+ public static ShellResult sudoExecCmd(String command) throws IOException {
+ return sudoExecCmd(command, null);
+ }
+
/**
* Execute the sudo command
*
diff --git a/bigtop-manager-stack/bigtop-manager-stack-extra/pom.xml
b/bigtop-manager-stack/bigtop-manager-stack-extra/pom.xml
index 6666ed4f..656610e1 100644
--- a/bigtop-manager-stack/bigtop-manager-stack-extra/pom.xml
+++ b/bigtop-manager-stack/bigtop-manager-stack-extra/pom.xml
@@ -34,5 +34,9 @@
<groupId>org.apache.bigtop</groupId>
<artifactId>bigtop-manager-stack-core</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.arrow</groupId>
+ <artifactId>flight-sql-jdbc-driver</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisBEScript.java
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisBEScript.java
new file mode 100644
index 00000000..dd55b12a
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisBEScript.java
@@ -0,0 +1,104 @@
+/*
+ * 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.extra.v1_0_0.doris;
+
+import org.apache.bigtop.manager.common.constants.MessageConstants;
+import org.apache.bigtop.manager.common.shell.ShellResult;
+import org.apache.bigtop.manager.stack.core.exception.StackException;
+import org.apache.bigtop.manager.stack.core.spi.param.Params;
+import org.apache.bigtop.manager.stack.core.spi.script.AbstractServerScript;
+import org.apache.bigtop.manager.stack.core.spi.script.Script;
+import org.apache.bigtop.manager.stack.core.utils.linux.LinuxFileUtils;
+import org.apache.bigtop.manager.stack.core.utils.linux.LinuxOSUtils;
+
+import com.google.auto.service.AutoService;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Properties;
+
+@Slf4j
+@AutoService(Script.class)
+public class DorisBEScript extends AbstractServerScript {
+
+ @Override
+ public ShellResult add(Params params) {
+ Properties properties = new Properties();
+ properties.setProperty(PROPERTY_KEY_SKIP_LEVELS, "1");
+
+ return super.add(params, properties);
+ }
+
+ @Override
+ public ShellResult configure(Params params) {
+ super.configure(params);
+
+ try {
+ return DorisSetup.config(params, "doris_be");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public ShellResult start(Params params) {
+ configure(params);
+ DorisParams dorisParams = (DorisParams) params;
+ LinuxFileUtils.removeDirectories(dorisParams.dorisBePidFile());
+
+ String cmd = MessageFormat.format("{0}/start_be.sh --daemon",
dorisParams.dorisBeBinDir());
+ try {
+ ShellResult sr = LinuxOSUtils.sudoExecCmd(cmd, dorisParams.user());
+ if (sr.getExitCode() != MessageConstants.SUCCESS_CODE) {
+ throw new StackException(sr.formatMessage("Failed to start
Doris BE"));
+ }
+ } catch (Exception e) {
+ throw new StackException(e);
+ }
+
+ // Register BE
+ DorisService.registerBe(dorisParams);
+ return ShellResult.success();
+ }
+
+ @Override
+ public ShellResult stop(Params params) {
+ DorisParams dorisParams = (DorisParams) params;
+ String cmd = MessageFormat.format("{0}/stop_be.sh",
dorisParams.dorisBeBinDir());
+ try {
+ ShellResult shellResult = LinuxOSUtils.sudoExecCmd(cmd,
dorisParams.user());
+ LinuxFileUtils.removeDirectories(dorisParams.dorisBePidDir());
+ return shellResult;
+ } catch (Exception e) {
+ throw new StackException(e);
+ }
+ }
+
+ @Override
+ public ShellResult status(Params params) {
+ DorisParams dorisParams = (DorisParams) params;
+ return LinuxOSUtils.checkProcess(dorisParams.dorisBePidFile());
+ }
+
+ @Override
+ public String getComponentName() {
+ return "doris_be";
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisFEScript.java
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisFEScript.java
new file mode 100644
index 00000000..204d2e64
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisFEScript.java
@@ -0,0 +1,124 @@
+/*
+ * 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.extra.v1_0_0.doris;
+
+import org.apache.bigtop.manager.common.shell.ShellResult;
+import org.apache.bigtop.manager.stack.core.exception.StackException;
+import org.apache.bigtop.manager.stack.core.spi.param.Params;
+import org.apache.bigtop.manager.stack.core.spi.script.AbstractServerScript;
+import org.apache.bigtop.manager.stack.core.spi.script.Script;
+import org.apache.bigtop.manager.stack.core.utils.linux.LinuxFileUtils;
+import org.apache.bigtop.manager.stack.core.utils.linux.LinuxOSUtils;
+
+import org.apache.commons.lang3.tuple.Pair;
+
+import com.google.auto.service.AutoService;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.Properties;
+
+@Slf4j
+@AutoService(Script.class)
+public class DorisFEScript extends AbstractServerScript {
+
+ @Override
+ public ShellResult add(Params params) {
+ Properties properties = new Properties();
+ properties.setProperty(PROPERTY_KEY_SKIP_LEVELS, "1");
+
+ return super.add(params, properties);
+ }
+
+ @Override
+ public ShellResult configure(Params params) {
+ super.configure(params);
+
+ try {
+ return DorisSetup.config(params, "doris_fe");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public ShellResult start(Params params) {
+ configure(params);
+ DorisParams dorisParams = (DorisParams) params;
+ String hostname = dorisParams.hostname();
+ String ip = dorisParams.ip();
+ LinuxFileUtils.removeDirectories(dorisParams.dorisFePidFile());
+
+ // Check if the FE is already registered
+ Pair<String, List<String>> masterAndFeList =
DorisService.getMasterAndFeList(dorisParams);
+ List<String> feList = masterAndFeList.getRight();
+ String feMaster = masterAndFeList.getLeft();
+
+ try {
+ if (feMaster.equals(hostname) || feMaster.equals(ip) ||
feList.contains(hostname)) {
+ String cmd = MessageFormat.format("{0}/start_fe.sh --daemon",
dorisParams.dorisFeBinDir());
+ return LinuxOSUtils.sudoExecCmd(cmd, dorisParams.user());
+ } else {
+ String cmd = MessageFormat.format(
+ "{0}/start_fe.sh --helper {1}:{2,number,#} --daemon",
+ dorisParams.dorisFeBinDir(), feMaster,
dorisParams.dorisFeEditLogPort());
+
+ return LinuxOSUtils.sudoExecCmd(cmd, dorisParams.user());
+ }
+ } catch (IOException e) {
+ throw new StackException(e);
+ }
+ }
+
+ @Override
+ public ShellResult prepare(Params params) {
+ DorisParams dorisParams = (DorisParams) params;
+ // Register FE in Doris service
+ for (String dorisFeHost : dorisParams.dorisFeHosts()) {
+ DorisService.registerFollower(dorisParams, dorisFeHost);
+ }
+ return ShellResult.success();
+ }
+
+ @Override
+ public ShellResult stop(Params params) {
+ DorisParams dorisParams = (DorisParams) params;
+ String cmd = MessageFormat.format("{0}/stop_fe.sh",
dorisParams.dorisFeBinDir());
+ try {
+ ShellResult shellResult = LinuxOSUtils.sudoExecCmd(cmd,
dorisParams.user());
+ LinuxFileUtils.removeDirectories(dorisParams.dorisFePidDir());
+ return shellResult;
+ } catch (Exception e) {
+ throw new StackException(e);
+ }
+ }
+
+ @Override
+ public ShellResult status(Params params) {
+ DorisParams dorisParams = (DorisParams) params;
+ return LinuxOSUtils.checkProcess(dorisParams.dorisFePidFile());
+ }
+
+ @Override
+ public String getComponentName() {
+ return "doris_fe";
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisParams.java
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisParams.java
new file mode 100644
index 00000000..8f1f200f
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisParams.java
@@ -0,0 +1,202 @@
+/*
+ * 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.extra.v1_0_0.doris;
+
+import org.apache.bigtop.manager.grpc.payload.ComponentCommandPayload;
+import org.apache.bigtop.manager.stack.core.annotations.GlobalParams;
+import org.apache.bigtop.manager.stack.core.spi.param.Params;
+import org.apache.bigtop.manager.stack.core.utils.LocalSettings;
+import org.apache.bigtop.manager.stack.core.utils.template.BaseTemplate;
+import org.apache.bigtop.manager.stack.extra.param.ExtraParams;
+
+import com.google.auto.service.AutoService;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Getter
+@AutoService(Params.class)
+@NoArgsConstructor
+public class DorisParams extends ExtraParams {
+
+ private final String limitsConfDir = "/etc/security/limits.d";
+ private final String sysctlConfDir = "/etc/sysctl.d";
+
+ public DorisParams(ComponentCommandPayload payload) {
+ super(payload);
+ globalParamsMap.put("java_home", javaHome());
+ globalParamsMap.put("doris_user", user());
+ globalParamsMap.put("doris_group", group());
+ globalParamsMap.put("doris_home", serviceHome());
+ globalParamsMap.put("doris_fe_home", dorisFeHome());
+ globalParamsMap.put("doris_be_home", dorisBeHome());
+ }
+
+
/*================================FE===================================================*/
+ public String dorisFeHome() {
+ return serviceHome() + "/fe";
+ }
+
+ public String dorisFeBinDir() {
+ return dorisFeHome() + "/bin";
+ }
+
+ public String dorisFeConfDir() {
+ return dorisFeHome() + "/conf";
+ }
+
+ public String dorisFeMetaDir() {
+ return dorisFeConf().get("meta_dir") != null
+ ? BaseTemplate.writeCustomTemplateAsString(
+ globalParamsMap, (String)
dorisFeConf().get("meta_dir"))
+ : dorisFeHome() + "/doris-meta";
+ }
+
+ public String dorisFeLogDir() {
+ return dorisEnv().get("doris_fe_log_dir") != null
+ ? BaseTemplate.writeCustomTemplateAsString(
+ globalParamsMap, (String)
dorisEnv().get("doris_fe_log_dir"))
+ : dorisFeHome() + "/log";
+ }
+
+ public String dorisFePidDir() {
+ return (String) dorisEnv().get("doris_fe_pid_dir");
+ }
+
+ public String dorisFePidFile() {
+ return dorisFePidDir() + "/fe.pid";
+ }
+
+ public List<String> dorisFeHosts() {
+ return LocalSettings.hosts("doris_fe");
+ }
+
+ public int dorisFeHttpPort() {
+ return Integer.parseInt(dorisFeConf().get("http_port").toString());
+ }
+
+ public int dorisFeEditLogPort() {
+ return Integer.parseInt(dorisFeConf().get("edit_log_port").toString());
+ }
+
+ public int dorisFeQueryPort() {
+ return Integer.parseInt(dorisFeConf().get("query_port").toString());
+ }
+
+ public int dorisFeArrowFlightSqlPort() {
+ return
Integer.parseInt(dorisFeConf().get("fe_arrow_flight_sql_port").toString());
+ }
+
+
/*================================FE===================================================*/
+
/*================================BE===================================================*/
+ public String dorisBeHome() {
+ return serviceHome() + "/be";
+ }
+
+ public String dorisBeBinDir() {
+ return dorisBeHome() + "/bin";
+ }
+
+ public String dorisBeConfDir() {
+ return dorisBeHome() + "/conf";
+ }
+
+ public String dorisBeStorage() {
+ return dorisBeConf().get("storage_root_path") != null
+ ? BaseTemplate.writeCustomTemplateAsString(
+ globalParamsMap, (String)
dorisBeConf().get("storage_root_path"))
+ : dorisBeHome() + "/storage";
+ }
+
+ public String dorisBeLogDir() {
+ return dorisEnv().get("doris_be_log_dir") != null
+ ? BaseTemplate.writeCustomTemplateAsString(
+ globalParamsMap, (String)
dorisEnv().get("doris_be_log_dir"))
+ : dorisBeHome() + "/log";
+ }
+
+ public String dorisBePidDir() {
+ return (String) dorisEnv().get("doris_be_pid_dir");
+ }
+
+ public String dorisBePidFile() {
+ return dorisBePidDir() + "/be.pid";
+ }
+
+ public int dorisBeHeartbeatPort() {
+ return
Integer.parseInt(dorisBeConf().get("heartbeat_service_port").toString());
+ }
+
+ public int dorisBeArrowFlightSqlPort() {
+ return
Integer.parseInt(dorisBeConf().get("be_arrow_flight_sql_port").toString());
+ }
+
/*================================BE===================================================*/
+
+ public String ip() {
+ try {
+ return InetAddress.getLocalHost().getHostAddress();
+ } catch (UnknownHostException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String getServiceName() {
+ return "doris";
+ }
+
+ public String dorisConf() {
+ return (String)
+ LocalSettings.configurations(getServiceName(),
"doris.conf").get("content");
+ }
+
+ public String dorisSysctlConf() {
+ return (String) LocalSettings.configurations(getServiceName(),
"doris-sysctl.conf")
+ .get("content");
+ }
+
+ public String dorisFeConfContent() {
+ return (String) dorisFeConf().get("content");
+ }
+
+ public String dorisBeConfContent() {
+ return (String) dorisBeConf().get("content");
+ }
+
+ @GlobalParams
+ public Map<String, Object> dorisFeConf() {
+ return LocalSettings.configurations(getServiceName(), "doris-fe-conf");
+ }
+
+ @GlobalParams
+ public Map<String, Object> dorisBeConf() {
+ return LocalSettings.configurations(getServiceName(), "doris-be-conf");
+ }
+
+ @GlobalParams
+ public Map<String, Object> dorisEnv() {
+ return LocalSettings.configurations(getServiceName(), "doris-env.sh");
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisService.java
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisService.java
new file mode 100644
index 00000000..ced0d533
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisService.java
@@ -0,0 +1,185 @@
+/*
+ * 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.extra.v1_0_0.doris;
+
+import org.apache.bigtop.manager.common.shell.ShellResult;
+import org.apache.bigtop.manager.stack.core.exception.StackException;
+import org.apache.bigtop.manager.stack.core.utils.linux.LinuxOSUtils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+
+@Slf4j
+public class DorisService {
+ public static void registerBe(DorisParams dorisParams) {
+ String hostname = dorisParams.hostname();
+ log.info("Registering Doris BE: ip [{}], hostname [{}]",
dorisParams.ip(), hostname);
+ String aliveFe = getAliveFe(dorisParams);
+ if (aliveFe == null) {
+ throw new StackException("Fail to register Doris BE: No FE
alive!");
+ }
+
+ List<String> beList = DorisService.getBeList(aliveFe, dorisParams);
+ if (beList.contains(hostname)) {
+ log.info("Doris BE [{}] already registered", hostname);
+ }
+ String sql = MessageFormat.format(
+ "ALTER SYSTEM ADD BACKEND ''{0}:{1,number,#}'';", hostname,
dorisParams.dorisBeHeartbeatPort());
+ DorisTool dorisTool = new DorisTool(aliveFe, "root", "",
dorisParams.dorisFeArrowFlightSqlPort());
+ try {
+ dorisTool.executeQuery(sql);
+ } catch (Exception e) {
+ log.error("Error register Doris BE [{}] ", hostname, e);
+ throw new StackException(e);
+ }
+ }
+
+ public static List<String> getBeList(String aliveFe, DorisParams
dorisParams) {
+ String sql = "SHOW BACKENDS;";
+ DorisTool dorisTool = new DorisTool(aliveFe, "root", "",
dorisParams.dorisFeArrowFlightSqlPort());
+ List<String> beList;
+ try {
+ beList = dorisTool.executeQuery(sql).stream()
+ .map(map -> (String) map.get("Host"))
+ .collect(Collectors.toList());
+ log.info("BE hosts found: [{}]", beList);
+ } catch (Exception e) {
+ log.error("Error executing SQL query: [{}], [{}]", sql,
e.getMessage());
+ throw new StackException(e);
+ }
+
+ return beList;
+ }
+
+ public static String getAliveFe(DorisParams dorisParams) {
+ int dorisFeHttpPort = dorisParams.dorisFeHttpPort();
+ List<String> feHosts = dorisParams.dorisFeHosts();
+ String aliveFe = null;
+
+ MessageFormat messageFormat =
+ new MessageFormat("curl -s -o /dev/null -w '%{http_code}'
http://{0}:{1,number,#}/api/bootstrap");
+ try {
+ for (String host : feHosts) {
+ String cmd = messageFormat.format(new Object[] {host,
dorisFeHttpPort});
+ ShellResult shellResult;
+ int attempts = 0;
+ while (attempts < 5) {
+ shellResult = LinuxOSUtils.execCmd(cmd);
+ if (shellResult.getExitCode() == 0
+ &&
StringUtils.equals(shellResult.getOutput().trim(), "200")) {
+ aliveFe = host;
+ break;
+ }
+ attempts++;
+ try {
+ log.info("Retry [{}] to connect [{}]", attempts, host);
+ Thread.sleep(5000);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error("Error checking alive FE hosts: [{}] [{}]",
e.getMessage(), e.getMessage());
+ throw new StackException(e);
+ }
+
+ if (aliveFe == null) {
+ log.warn("No alive FE host found in the list: [{}]", feHosts);
+ } else {
+ log.info("Alive FE host: [{}]", aliveFe);
+ }
+
+ return aliveFe;
+ }
+
+ /**
+ * Return MasterFeHost and AllFeHost
+ *
+ * @param dorisParams DorisParams
+ * @return (MasterFeHost, AllFeHost)
+ */
+ public static Pair<String, List<String>> getMasterAndFeList(DorisParams
dorisParams) {
+ AtomicReference<String> masterHost =
+ new AtomicReference<>(dorisParams.dorisFeHosts().get(0));
+ String aliveFe = getAliveFe(dorisParams);
+ if (aliveFe == null) {
+ log.warn("No alive FE");
+ return Pair.of(masterHost.get(), List.of());
+ }
+ List<String> feList = new ArrayList<>();
+ String sql = "SHOW FRONTENDS;";
+ DorisTool dorisTool = new DorisTool(aliveFe, "root", "",
dorisParams.dorisFeArrowFlightSqlPort());
+ try {
+ dorisTool.executeQuery(sql).stream()
+ .map(map -> {
+ String host = (String) map.get("Host");
+ boolean isMaster = Boolean.parseBoolean((String)
map.get("IsMaster"));
+ if (isMaster) {
+ masterHost.set(host);
+ }
+ return host;
+ })
+ .forEach(feList::add);
+ } catch (Exception e) {
+ log.error("Error executing SQL query: [{}], msg: [{}]", sql,
e.getMessage());
+ throw new StackException(e);
+ }
+
+ log.info("FE hosts found: [{}]", feList);
+ return Pair.of(masterHost.get(), feList);
+ }
+
+ public static void registerFollower(DorisParams dorisParams, String
hostname) {
+ String aliveFe = getAliveFe(dorisParams);
+ if (aliveFe == null) {
+ throw new StackException("Error registering follower: No FE
alive!");
+ }
+
+ Pair<String, List<String>> masterAndFeList =
getMasterAndFeList(dorisParams);
+ List<String> feList = masterAndFeList.getRight();
+ String feMaster = masterAndFeList.getLeft();
+
+ if (feList.contains(hostname)) {
+ log.info("Doris FE [{}] already registered", hostname);
+ } else {
+ DorisTool dorisTool = new DorisTool(feMaster, "root", "",
dorisParams.dorisFeArrowFlightSqlPort());
+
+ try {
+ String sql = MessageFormat.format(
+ "ALTER SYSTEM ADD FOLLOWER ''{0}:{1,number,#}'';",
hostname, dorisParams.dorisFeEditLogPort());
+
+ dorisTool.executeQuery(sql);
+ } catch (Exception e) {
+ log.error("Error registering Doris Follower: [{}]",
e.getMessage());
+ throw new StackException(e);
+ }
+ }
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisSetup.java
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisSetup.java
new file mode 100644
index 00000000..ba7ee4d1
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisSetup.java
@@ -0,0 +1,110 @@
+/*
+ * 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.extra.v1_0_0.doris;
+
+import org.apache.bigtop.manager.common.constants.Constants;
+import org.apache.bigtop.manager.common.constants.MessageConstants;
+import org.apache.bigtop.manager.common.shell.ShellResult;
+import org.apache.bigtop.manager.stack.core.exception.StackException;
+import org.apache.bigtop.manager.stack.core.spi.param.Params;
+import org.apache.bigtop.manager.stack.core.utils.linux.LinuxFileUtils;
+import org.apache.bigtop.manager.stack.core.utils.linux.LinuxOSUtils;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+
+import static
org.apache.bigtop.manager.common.constants.Constants.PERMISSION_755;
+
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class DorisSetup {
+
+ public static ShellResult config(Params params, String type) throws
IOException {
+ DorisParams dorisParams = (DorisParams) params;
+ String user = dorisParams.user();
+ String group = dorisParams.group();
+
+ LinuxFileUtils.toFileByTemplate(
+ dorisParams.dorisConf(),
+ MessageFormat.format("{0}/doris.conf",
dorisParams.getLimitsConfDir()),
+ Constants.ROOT_USER,
+ Constants.ROOT_GROUP,
+ Constants.PERMISSION_644,
+ dorisParams.getGlobalParamsMap());
+
+ LinuxFileUtils.toFileByTemplate(
+ dorisParams.dorisSysctlConf(),
+ MessageFormat.format("{0}/doris-sysctl.conf",
dorisParams.getSysctlConfDir()),
+ Constants.ROOT_USER,
+ Constants.ROOT_GROUP,
+ Constants.PERMISSION_644,
+ dorisParams.getGlobalParamsMap());
+
+ ShellResult sr1 = LinuxOSUtils.sudoExecCmd("sysctl -p
/etc/sysctl.d/doris-sysctl.conf");
+ if (sr1.getExitCode() != MessageConstants.SUCCESS_CODE) {
+ String errMsg = sr1.formatMessage("Failed to apply sysctl
settings");
+ log.error(errMsg);
+ throw new StackException(errMsg);
+ }
+
+ ShellResult sr2 = LinuxOSUtils.sudoExecCmd("swapoff -a");
+ if (sr2.getExitCode() != MessageConstants.SUCCESS_CODE) {
+ String errMsg = sr2.formatMessage("Failed to run swapoff command");
+ log.error(errMsg);
+ throw new StackException(errMsg);
+ }
+
+ if (type.equals("doris_fe")) {
+ LinuxFileUtils.createDirectories(dorisParams.dorisFeConfDir(),
user, group, PERMISSION_755, false);
+ LinuxFileUtils.createDirectories(dorisParams.dorisFePidDir(),
user, group, PERMISSION_755, false);
+ LinuxFileUtils.createDirectories(dorisParams.dorisFeLogDir(),
user, group, PERMISSION_755, false);
+ LinuxFileUtils.createDirectories(dorisParams.dorisFeMetaDir(),
user, group, PERMISSION_755, false);
+
+ LinuxFileUtils.toFileByTemplate(
+ dorisParams.dorisFeConfContent(),
+ MessageFormat.format("{0}/fe.conf",
dorisParams.dorisFeConfDir()),
+ user,
+ group,
+ Constants.PERMISSION_644,
+ dorisParams.getGlobalParamsMap(),
+ dorisParams.getGlobalParamsMap());
+
+ } else if (type.equals("doris_be")) {
+ LinuxFileUtils.createDirectories(dorisParams.dorisBeConfDir(),
user, group, PERMISSION_755, false);
+ LinuxFileUtils.createDirectories(dorisParams.dorisBePidDir(),
user, group, PERMISSION_755, false);
+ LinuxFileUtils.createDirectories(dorisParams.dorisBeLogDir(),
user, group, PERMISSION_755, false);
+ LinuxFileUtils.createDirectories(dorisParams.dorisBeStorage(),
user, group, PERMISSION_755, false);
+
+ LinuxFileUtils.toFileByTemplate(
+ dorisParams.dorisBeConfContent(),
+ MessageFormat.format("{0}/be.conf",
dorisParams.dorisBeConfDir()),
+ user,
+ group,
+ Constants.PERMISSION_644,
+ dorisParams.getGlobalParamsMap(),
+ dorisParams.getGlobalParamsMap());
+ }
+
+ return ShellResult.success("Doris Configure success!");
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisTool.java
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisTool.java
new file mode 100644
index 00000000..bab710aa
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-extra/src/main/java/org/apache/bigtop/manager/stack/extra/v1_0_0/doris/DorisTool.java
@@ -0,0 +1,109 @@
+/*
+ * 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.extra.v1_0_0.doris;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+public class DorisTool {
+ private static final int MAX_RETRIES = 10;
+ private static final int RETRY_DELAY_MS = 10000; // milliseconds
+
+ private final String jdbcUrl;
+ private final String user;
+ private final String password;
+
+ public DorisTool(String host, String user, String password, int port) {
+ this.jdbcUrl = String.format(
+
"jdbc:arrow-flight-sql://%s:%d?useServerPrepStmts=false&cachePrepStmts=true&useSSL=false&useEncryption=false",
+ host, port);
+ this.user = user;
+ this.password = password;
+ log.info("Connecting to database: [jdbc:arrow-flight-sql://{}:{}]",
host, port);
+ }
+
+ public Connection connect() throws Exception {
+ int attempt = 0;
+ Exception lastException = null;
+
+ while (attempt < MAX_RETRIES) {
+ try {
+ Connection connection = DriverManager.getConnection(jdbcUrl,
user, password);
+ if (connection != null && !connection.isClosed()) {
+ log.info("Successfully connected to Doris");
+ return connection;
+ } else {
+ throw new Exception("Connection is null or closed");
+ }
+ } catch (Exception e) {
+ lastException = e;
+ attempt++;
+ log.warn("Connection attempt [{}] failed: [{}]", attempt,
e.getMessage());
+
+ if (attempt < MAX_RETRIES) {
+ try {
+ Thread.sleep(RETRY_DELAY_MS);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ throw new SQLException("Connection interrupted", ie);
+ }
+ }
+ }
+ }
+
+ throw new Exception("Failed to connect after " + MAX_RETRIES + "
attempts", lastException);
+ }
+
+ public List<Map<String, Object>> executeQuery(String sql) throws Exception
{
+ log.info("Executing SQL query: [{}]", sql);
+
+ List<Map<String, Object>> resultList = new ArrayList<>();
+
+ try (Connection conn = connect();
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery(sql)) {
+ ResultSetMetaData metaData = rs.getMetaData();
+ int columnCount = metaData.getColumnCount();
+
+ while (rs.next()) {
+ Map<String, Object> row = new LinkedHashMap<>();
+ for (int i = 1; i <= columnCount; i++) {
+ String columnName = metaData.getColumnLabel(i);
+ Object value = rs.getObject(i);
+ row.put(columnName, value);
+ }
+ resultList.add(row);
+ }
+
+ return resultList;
+ }
+ }
+}
diff --git a/bigtop-manager-ui/src/assets/images/doris.png
b/bigtop-manager-ui/src/assets/images/doris.png
new file mode 100644
index 00000000..46f60cf4
Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/doris.png
differ