From 8aac6c6f819ffdcff4aa6369a16a030f754273af Mon Sep 17 00:00:00 2001
From: Xinwei Xiong <3293172751@qq.com>
Date: Fri, 5 Jan 2024 11:19:40 +0800
Subject: [PATCH 01/20] Fix(main): fix openim config from mongo password env
upgrade openim build CICD (#1689)
* fix openim config mongo passwd env
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* fix openim config mongo passwd env
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* fix openim config mongo passwd env
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* fix openim config mongo passwd env
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
---------
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
---
.github/workflows/openimci.yml | 15 ++++----
docs/contrib/environment.md | 6 ++--
pkg/common/db/unrelation/mongo.go | 4 +--
scripts/install-im-server.sh | 57 ++++++++++++++++++-------------
scripts/install/dependency.sh | 4 +--
5 files changed, 48 insertions(+), 38 deletions(-)
diff --git a/.github/workflows/openimci.yml b/.github/workflows/openimci.yml
index d16e91ba4..45541f5f4 100644
--- a/.github/workflows/openimci.yml
+++ b/.github/workflows/openimci.yml
@@ -128,6 +128,8 @@ jobs:
- name: Run OpenIM make install start
run: |
sudo make install
+ sudo docker images
+ sudo docker ps
execute-scripts:
name: Execute OpenIM Script On ${{ matrix.os }}
@@ -212,14 +214,10 @@ jobs:
sudo make restart
sudo make check
- # - name: Build, Start, Check Services and Print Logs for macOS
- # if: runner.os == 'macOS'
- # run: |
- # make init && \
- # make build && \
- # make start && \
- # make check || \
- # (echo "An error occurred, printing logs:" && sudo cat ./_output/logs/* 2>/dev/null)
+ - name: Build, Start, Check Services and Print Logs for macOS
+ if: runner.os == 'macOS'
+ run: |
+ make build
openim-test-build-image:
name: Build OpenIM Docker Image
@@ -245,3 +243,4 @@ jobs:
run: |
sudo make init
sudo make image
+ sudo docker images
diff --git a/docs/contrib/environment.md b/docs/contrib/environment.md
index e52d57235..8db462688 100644
--- a/docs/contrib/environment.md
+++ b/docs/contrib/environment.md
@@ -304,8 +304,10 @@ This section involves setting up MongoDB, including its port, address, and crede
| -------------- | -------------- | ----------------------- |
| MONGO_PORT | "27017" | Port used by MongoDB. |
| MONGO_ADDRESS | [Generated IP] | IP address for MongoDB. |
-| MONGO_USERNAME | [User Defined] | Username for MongoDB. |
-| MONGO_PASSWORD | [User Defined] | Password for MongoDB. |
+| MONGO_USERNAME | [User Defined] | Admin Username for MongoDB. |
+| MONGO_PASSWORD | [User Defined] | Admin Password for MongoDB. |
+| MONGO_OPENIM_PASSWORD | [User Defined] | OpenIM Username for MongoDB. |
+| MONGO_OPENIM_PASSWORD | [User Defined] | OpenIM Password for MongoDB. |
### 2.8. Tencent Cloud COS Configuration
diff --git a/pkg/common/db/unrelation/mongo.go b/pkg/common/db/unrelation/mongo.go
index 279a7901e..b8184d767 100644
--- a/pkg/common/db/unrelation/mongo.go
+++ b/pkg/common/db/unrelation/mongo.go
@@ -78,8 +78,8 @@ func buildMongoURI() string {
return config.Config.Mongo.Uri
}
- username := os.Getenv("MONGO_USERNAME")
- password := os.Getenv("MONGO_PASSWORD")
+ username := os.Getenv("MONGO_OPENIM_USERNAME")
+ password := os.Getenv("MONGO_OPENIM_PASSWORD")
address := os.Getenv("MONGO_ADDRESS")
port := os.Getenv("MONGO_PORT")
database := os.Getenv("MONGO_DATABASE")
diff --git a/scripts/install-im-server.sh b/scripts/install-im-server.sh
index a21ae134d..16ac625ee 100755
--- a/scripts/install-im-server.sh
+++ b/scripts/install-im-server.sh
@@ -1,20 +1,18 @@
#!/usr/bin/env bash
-# Copyright © 2023 OpenIM. All rights reserved.
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# OpenIM Docker Deployment Script
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# This script automates the process of building the OpenIM server image
+# and deploying it using Docker Compose.
#
-# 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.
-
+# Variables:
+# - SERVER_IMAGE_VERSION: Version of the server image (default: test)
+# - IMAGE_REGISTRY: Docker image registry (default: openim)
+# - DOCKER_COMPOSE_FILE_URL: URL to the docker-compose.yml file
+#
+# Usage:
+# SERVER_IMAGE_VERSION=latest IMAGE_REGISTRY=myregistry ./this_script.sh
-# Common utilities, variables and checks for all build scripts.
set -o errexit
set -o nounset
set -o pipefail
@@ -28,35 +26,46 @@ chmod +x "${OPENIM_ROOT}"/scripts/*.sh
openim::util::ensure_docker_daemon_connectivity
+# Default values for variables
+: ${SERVER_IMAGE_VERSION:=test}
+: ${IMAGE_REGISTRY:=openim}
+: ${DOCKER_COMPOSE_FILE_URL:="https://raw.githubusercontent.com/openimsdk/openim-docker/main/docker-compose.yaml"}
+
DOCKER_COMPOSE_COMMAND=
# Check if docker-compose command is available
openim::util::check_docker_and_compose_versions
-
-if command -v docker compose &> /dev/null
-then
+if command -v docker compose &> /dev/null; then
openim::log::info "docker compose command is available"
DOCKER_COMPOSE_COMMAND="docker compose"
else
DOCKER_COMPOSE_COMMAND="docker-compose"
fi
+export SERVER_IMAGE_VERSION
+export IMAGE_REGISTRY
"${OPENIM_ROOT}"/scripts/init-config.sh
+
pushd "${OPENIM_ROOT}"
+docker build -t "${IMAGE_REGISTRY}/openim-server:${SERVER_IMAGE_VERSION}" .
${DOCKER_COMPOSE_COMMAND} stop
-curl https://raw.githubusercontent.com/openimsdk/openim-docker/main/docker-compose.yaml -o docker-compose.yml
+curl "${DOCKER_COMPOSE_FILE_URL}" -o docker-compose.yml
${DOCKER_COMPOSE_COMMAND} up -d
+# Function to check container status
+check_containers() {
+ if ! ${DOCKER_COMPOSE_COMMAND} ps | grep -q 'Up'; then
+ echo "Error: One or more docker containers failed to start."
+ ${DOCKER_COMPOSE_COMMAND} logs
+ return 1
+ fi
+ return 0
+}
+
# Wait for a short period to allow containers to initialize
sleep 30
+check_containers
-# Check the status of the containers
-if ! ${DOCKER_COMPOSE_COMMAND} ps | grep -q 'Up'; then
- echo "Error: One or more docker containers failed to start."
- ${DOCKER_COMPOSE_COMMAND} logs
-fi
-
-sleep 30 # Keep the original 60-second wait, adjusted for the 10-second check above
${DOCKER_COMPOSE_COMMAND} logs openim-server
${DOCKER_COMPOSE_COMMAND} ps
-popd
+popd
\ No newline at end of file
diff --git a/scripts/install/dependency.sh b/scripts/install/dependency.sh
index bfa0909e2..78995bcf9 100755
--- a/scripts/install/dependency.sh
+++ b/scripts/install/dependency.sh
@@ -35,8 +35,8 @@ docker run -d \
-e MONGO_INITDB_ROOT_USERNAME=${OPENIM_USER} \
-e MONGO_INITDB_ROOT_PASSWORD=${PASSWORD} \
-e MONGO_INITDB_DATABASE=openIM \
- -e MONGO_USERNAME=${OPENIM_USER} \
- -e MONGO_PASSWORD=${PASSWORD} \
+ -e MONGO_OPENIM_USERNAME=${OPENIM_USER} \
+ -e MONGO_OPENIM_PASSWORD=${PASSWORD} \
--restart always \
mongo:6.0.2 --wiredTigerCacheSizeGB 1 --auth
From c241f5bea1b660f13e67dc55351ebba2c02ea86d Mon Sep 17 00:00:00 2001
From: Xinwei Xiong <3293172751@qq.com>
Date: Sat, 6 Jan 2024 21:02:47 +0800
Subject: [PATCH 02/20] Update cla.yml (#1692)
---
.github/workflows/cla.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml
index 540c8a48b..ae27c8a0a 100644
--- a/.github/workflows/cla.yml
+++ b/.github/workflows/cla.yml
@@ -33,7 +33,7 @@ env:
OPEN_IM_SERVER_CLA_DOCUMENT: https://github.com/openim-sigs/cla/blob/main/README.md
OPEN_IM_SERVER_SIGNATURES_PATH: signatures/${{ github.event.repository.name }}/cla.json
- OPEN_IM_SERVER_ALLOWLIST: kubbot,bot*,bot-*,bot/*,bot-/*,bot,*[bot]
+ OPEN_IM_SERVER_ALLOWLIST: kubbot,openimbot,bot*,dependabot,sweep-ai,*bot,bot-*,bot/*,bot-/*,bot,*[bot]
jobs:
CLAAssistant:
From f27b1e43f57c2a0f49fad387fe6e486930845fce Mon Sep 17 00:00:00 2001
From: Xinwei Xiong <3293172751@qq.com>
Date: Sun, 7 Jan 2024 15:02:59 +0800
Subject: [PATCH 03/20] Enhancements to Script Variables and Logic in OpenIM,
Including dig Detection and Mongo Startup Checks (#1696)
* update openim and optimize openim docs and dig check
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim and optimize openim docs and dig check
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim and optimize openim docs and dig check
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* fix openim config mongo passwd env
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update openim environment and status
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: sava openim cicd
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim mongo logic
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
---------
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
---
.github/workflows/docker-buildx.yml | 130 ++++++++++++++++++++++++
.github/workflows/e2e-test.yml | 37 ++++++-
.github/workflows/openimci.yml | 60 +++++++++--
deployments/templates/env-template.yaml | 18 +++-
docker-compose.yml | 4 +-
docs/contrib/environment.md | 17 ++--
docs/contrib/images.md | 1 +
docs/contrib/version.md | 21 ++++
pkg/common/config/version | 2 +-
pkg/msgprocessor/conversation.go | 1 +
pkg/msgprocessor/options.go | 1 +
scripts/genconfig.sh | 12 +--
scripts/install-im-server.sh | 14 +++
scripts/install/environment.sh | 4 +-
scripts/lib/util.sh | 9 +-
scripts/make-rules/common.mk | 2 +-
scripts/mongo-init.sh | 2 -
17 files changed, 291 insertions(+), 44 deletions(-)
diff --git a/.github/workflows/docker-buildx.yml b/.github/workflows/docker-buildx.yml
index 6113cfae5..b3b0b5683 100644
--- a/.github/workflows/docker-buildx.yml
+++ b/.github/workflows/docker-buildx.yml
@@ -106,6 +106,16 @@ jobs:
ghcr.io/openimsdk/openim-api
openim/openim-api
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-api
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-api
uses: docker/build-push-action@v5
@@ -127,6 +137,16 @@ jobs:
ghcr.io/openimsdk/openim-cmdutils
openim/openim-cmdutils
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-cmdutils
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-cmdutils
uses: docker/build-push-action@v5
@@ -148,6 +168,16 @@ jobs:
ghcr.io/openimsdk/openim-crontask
openim/openim-crontask
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-crontask
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-crontask
uses: docker/build-push-action@v5
@@ -169,6 +199,16 @@ jobs:
ghcr.io/openimsdk/openim-msggateway
openim/openim-msggateway
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-msggateway
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-msggateway
uses: docker/build-push-action@v5
@@ -190,6 +230,16 @@ jobs:
ghcr.io/openimsdk/openim-msgtransfer
openim/openim-msgtransfer
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-msgtransfer
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-msgtransfer
uses: docker/build-push-action@v5
@@ -211,6 +261,16 @@ jobs:
ghcr.io/openimsdk/openim-push
openim/openim-push
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-push
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-push
uses: docker/build-push-action@v5
@@ -232,6 +292,16 @@ jobs:
ghcr.io/openimsdk/openim-rpc-auth
openim/openim-rpc-auth
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-auth
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-rpc-auth
uses: docker/build-push-action@v5
@@ -253,6 +323,16 @@ jobs:
ghcr.io/openimsdk/openim-rpc-conversation
openim/openim-rpc-conversation
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-conversation
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-rpc-conversation
uses: docker/build-push-action@v5
@@ -274,6 +354,16 @@ jobs:
ghcr.io/openimsdk/openim-rpc-friend
openim/openim-rpc-friend
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-friend
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-rpc-friend
uses: docker/build-push-action@v5
@@ -295,6 +385,16 @@ jobs:
ghcr.io/openimsdk/openim-rpc-group
openim/openim-rpc-group
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-group
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-rpc-group
uses: docker/build-push-action@v5
@@ -316,6 +416,16 @@ jobs:
ghcr.io/openimsdk/openim-rpc-msg
openim/openim-rpc-msg
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-msg
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-rpc-msg
uses: docker/build-push-action@v5
@@ -337,6 +447,16 @@ jobs:
ghcr.io/openimsdk/openim-rpc-third
openim/openim-rpc-third
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-third
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-rpc-third
uses: docker/build-push-action@v5
@@ -358,6 +478,16 @@ jobs:
ghcr.io/openimsdk/openim-rpc-user
openim/openim-rpc-user
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-user
+ tags: |
+ type=ref,event=tag
+ type=schedule
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
- name: Build and push Docker image for openim-rpc-user
uses: docker/build-push-action@v5
diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml
index 2f6d7fe05..6d8112eb4 100644
--- a/.github/workflows/e2e-test.yml
+++ b/.github/workflows/e2e-test.yml
@@ -92,11 +92,40 @@ jobs:
- name: Exec OpenIM API test
run: |
- sudo make test-api
-
- - name: Exec OpenIM E2E test
+ touch /tmp/test.md
+ echo "# OpenIM Test" >> /tmp/test.md
+ echo "## OpenIM API Test" >> /tmp/test.md
+ echo "Command Output for OpenIM API Test
" >> /tmp/test.md
+ echo "" >> /tmp/test.md
+ sudo make test-api | tee -a /tmp/test.md
+ echo "
" >> /tmp/test.md
+ echo " " >> /tmp/test.md
+
+ - name: Exec OpenIM E2E Test
run: |
- sudo make test-e2e
+ echo "" >> /tmp/test.md
+ echo "## OpenIM E2E Test" >> /tmp/test.md
+ echo "Command Output for OpenIM E2E Test
" >> /tmp/test.md
+ echo "" >> /tmp/test.md
+ sudo make test-e2e | tee -a /tmp/test.md
+ echo "
" >> /tmp/test.md
+ echo " " >> /tmp/test.md
+
+ - name: Comment PR with file
+ uses: thollander/actions-comment-pull-request@v2
+ with:
+ filePath: /tmp/test.md
+ comment_tag: nrt_file
+ reactions: eyes, rocket
+ mode: recreate
+ GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
+ continue-on-error: true
+
+ - name: Check outputs
+ run: |
+ echo "id : ${{ steps.nrt_message.outputs.id }}"
+ echo "body : ${{ steps.nrt_message.outputs.body }}"
+ echo "html_url : ${{ steps.nrt_message.outputs.html_url }}"
- name: Exec OpenIM System uninstall
run: |
diff --git a/.github/workflows/openimci.yml b/.github/workflows/openimci.yml
index 45541f5f4..96e03f214 100644
--- a/.github/workflows/openimci.yml
+++ b/.github/workflows/openimci.yml
@@ -36,21 +36,19 @@ env:
GO_VERSION: "1.19"
GOLANGCI_VERSION: "v1.50.1"
-
jobs:
openim:
name: Test with go ${{ matrix.go_version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
permissions:
contents: write
+ pull-requests: write
environment:
name: openim
-
strategy:
matrix:
go_version: ["1.19","1.20","1.21"]
os: [ubuntu-latest]
-
steps:
- name: Setup
uses: actions/checkout@v4
@@ -111,6 +109,9 @@ jobs:
openim-start:
name: Test OpenIM install/start on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
+ permissions:
+ contents: write
+ pull-requests: write
environment:
name: openim
strategy:
@@ -128,12 +129,46 @@ jobs:
- name: Run OpenIM make install start
run: |
sudo make install
- sudo docker images
- sudo docker ps
+
+ # - name: Check the OpenIM environment and status
+ # run: |
+ # sudo docker images
+ # sudo docker ps
+
+ - name: Check the OpenIM environment and status
+ id: docker_info
+ run: |
+ sleep 30
+ echo "images<> $GITHUB_ENV
+ sudo docker images >> $GITHUB_ENV
+ echo "EOF" >> $GITHUB_ENV
+ echo "containers<> $GITHUB_ENV
+ sudo docker ps >> $GITHUB_ENV
+ echo "EOF" >> $GITHUB_ENV
+
+ - name: Comment PR
+ uses: thollander/actions-comment-pull-request@v2
+ with:
+ message: |
+ > [!TIP]
+ > Run make install to check the status
+
+ ### Docker Images:
+ ```
+ ${{ env.images }}
+ ```
+ ### Docker Processes:
+ ```
+ ${{ env.containers }}
+ ```
+ GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
execute-scripts:
name: Execute OpenIM Script On ${{ matrix.os }}
runs-on: ${{ matrix.os }}
+ permissions:
+ contents: write
+ pull-requests: write
environment:
name: openim
strategy:
@@ -203,10 +238,9 @@ jobs:
- name: Build, Start, Check Services and Print Logs for Ubuntu
if: runner.os == 'Linux'
run: |
- sudo make build && \
- sudo make start && \
- sudo make check || \
- (echo "An error occurred, printing logs:" && sudo cat ./_output/logs/* 2>/dev/null)
+ sudo make build
+ sudo make start
+ sudo make check
- name: Restart Services and Print Logs for Ubuntu
if: runner.os == 'Linux'
@@ -222,6 +256,9 @@ jobs:
openim-test-build-image:
name: Build OpenIM Docker Image
runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ pull-requests: write
environment:
name: openim
steps:
@@ -243,4 +280,9 @@ jobs:
run: |
sudo make init
sudo make image
+
+ - name: Get OpenIM Docker Images Status
+ id: docker_processes
+ run: |
sudo docker images
+ sudo docker ps
\ No newline at end of file
diff --git a/deployments/templates/env-template.yaml b/deployments/templates/env-template.yaml
index 09349aab0..e7166ff2d 100644
--- a/deployments/templates/env-template.yaml
+++ b/deployments/templates/env-template.yaml
@@ -1,3 +1,17 @@
+# Copyright © 2024 OpenIM. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
# -----------------------------------------------------------------------------
# General Configuration
# This section contains general configuration options for the entire environment.
@@ -88,10 +102,6 @@ ZOOKEEPER_PORT=${ZOOKEEPER_PORT}
# Default: MONGO_PORT=37017
# MONGO_PORT=${MONGO_PORT}
-# Username for MongoDB admin user. Used for service authentication.
-# Default: MONGO_USERNAME=root
-# MONGO_USERNAME=${MONGO_USERNAME}
-
# Password for MongoDB admin user. Used for service authentication.
# Default: MONGO_PASSWORD=openIM123
MONGO_PASSWORD=${MONGO_PASSWORD}
diff --git a/docker-compose.yml b/docker-compose.yml
index b5c80188c..defc910c4 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -10,15 +10,13 @@ networks:
- subnet: '${DOCKER_BRIDGE_SUBNET:-172.28.0.0/16}'
gateway: '${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}'
-
-
services:
mongodb:
image: mongo:${MONGODB_IMAGE_VERSION-6.0.2}
ports:
- "${MONGO_PORT:-37017}:27017"
container_name: mongo
- command: --wiredTigerCacheSizeGB 1 --auth
+ command: ["/bin/bash", "-c", "/docker-entrypoint-initdb.d/mongo-init.sh || true; docker-entrypoint.sh mongod --wiredTigerCacheSizeGB 1 --auth"]
volumes:
- "${DATA_DIR:-./}/components/mongodb/data/db:/data/db"
- "${DATA_DIR:-./}/components/mongodb/data/logs:/data/logs"
diff --git a/docs/contrib/environment.md b/docs/contrib/environment.md
index 8db462688..7425c8022 100644
--- a/docs/contrib/environment.md
+++ b/docs/contrib/environment.md
@@ -104,8 +104,8 @@ Docker deployment offers a slightly more intricate template. Within the [openim-
Configuration file modifications can be made by specifying corresponding environment variables, for instance:
```bash
-export CHAT_IMAGE_VERSION="main"
-export SERVER_IMAGE_VERSION="main"
+export CHAT_IMAGE_VERSION="main"
+export SERVER_IMAGE_VERSION="main"
```
These variables are stored within the [`environment.sh`](https://github.com/OpenIMSDK/openim-docker/blob/main/scripts/install/environment.sh) configuration:
@@ -114,6 +114,9 @@ These variables are stored within the [`environment.sh`](https://github.com/Open
readonly CHAT_IMAGE_VERSION=${CHAT_IMAGE_VERSION:-'main'}
readonly SERVER_IMAGE_VERSION=${SERVER_IMAGE_VERSION:-'main'}
```
+> [!IMPORTANT]
+> Can learn to read our mirror version strategy: https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/images.md
+
Setting a variable, e.g., `export CHAT_IMAGE_VERSION="release-v1.3"`, will prioritize `CHAT_IMAGE_VERSION="release-v1.3"` as the variable value. Ultimately, the chosen image version is determined, and rendering is achieved through `make init` (or `./scripts/init-config.sh`).
@@ -127,7 +130,7 @@ For convenience, configuration through modifying environment variables is recomm
+ PASSWORD
- + **Description**: Password for mysql, mongodb, redis, and minio.
+ + **Description**: Password for mongodb, redis, and minio.
+ **Default**: `openIM123`
+ Notes:
+ Minimum password length: 8 characters.
@@ -139,20 +142,22 @@ For convenience, configuration through modifying environment variables is recomm
+ OPENIM_USER
- + **Description**: Username for mysql, mongodb, redis, and minio.
+ + **Description**: Username for redis, and minio.
+ **Default**: `root`
```bash
export OPENIM_USER="root"
```
-+ API_URL
+> mongo is `openIM`, use `export MONGO_OPENIM_USERNAME="openIM"` to modify
+
++ OPENIM_IP
+ **Description**: API address.
+ **Note**: If the server has an external IP, it will be automatically obtained. For internal networks, set this variable to the IP serving internally.
```bash
- export API_URL="http://ip:10002"
+ export OPENIM_IP="ip"
```
+ DATA_DIR
diff --git a/docs/contrib/images.md b/docs/contrib/images.md
index 44bd7b5bf..d1a83d639 100644
--- a/docs/contrib/images.md
+++ b/docs/contrib/images.md
@@ -26,6 +26,7 @@ We provide multiple versions of our images to meet different project requirement
1. `main`: This image corresponds to the latest version of the main branch in OpenIM. It is updated frequently, making it perfect for users who want to stay at the cutting edge of our features.
2. `release-v3.*`: This is the image that corresponds to the latest version of OpenIM's stable release branch. It's ideal for users who prefer a balance between new features and stability.
3. `v3.*.*`: These images are specific to each tag in OpenIM. They are preserved in their original state and are never overwritten. These are the go-to images for users who need a specific, unchanging version of OpenIM.
+4. The image versions adhere to Semantic Versioning 2.0.0 strategy. Taking the `openim-server` image as an example, available at [openim-server container package](https://github.com/openimsdk/open-im-server/pkgs/container/openim-server): upon tagging with v3.5.0, the CI automatically releases the following tags - `openim-server:3`, `openim-server:3.5`, `openim-server:3.5.0`, `openim-server:v3.5.0`, `openim-server:latest`, and `sha-e0244d9`. It's important to note that only `sha-e0244d9` is absolutely unique, whereas `openim-server:v3.5.0` and `openim-server:3.5.0` maintain a degree of uniqueness.
### Multi-Architecture Images
diff --git a/docs/contrib/version.md b/docs/contrib/version.md
index 0e03b8d8b..574badf59 100644
--- a/docs/contrib/version.md
+++ b/docs/contrib/version.md
@@ -1,6 +1,7 @@
# OpenIM Branch Management and Versioning: A Blueprint for High-Grade Software Development
[📚 **OpenIM TOC**](#openim-branch-management-and-versioning-a-blueprint-for-high-grade-software-development)
+- [OpenIM Branch Management and Versioning: A Blueprint for High-Grade Software Development](#openim-branch-management-and-versioning-a-blueprint-for-high-grade-software-development)
- [Unfolding the Mechanism of OpenIM Version Maintenance](#unfolding-the-mechanism-of-openim-version-maintenance)
- [Main Branch: The Heart of OpenIM Development](#main-branch-the-heart-of-openim-development)
- [Release Branch: The Beacon of Stability](#release-branch-the-beacon-of-stability)
@@ -8,8 +9,21 @@
- [Release Management: A Guided Tour](#release-management-a-guided-tour)
- [Milestones, Branching, and Addressing Major Bugs](#milestones-branching-and-addressing-major-bugs)
- [Version Skew Policy](#version-skew-policy)
+ - [Supported version skew](#supported-version-skew)
+ - [OpenIM Versioning, Branching, and Tag Strategy](#openim-versioning-branching-and-tag-strategy)
+ - [Supported Version Skew](#supported-version-skew-1)
+ - [openim-api](#openim-api)
+ - [openim-rpc-\* Components](#openim-rpc--components)
+ - [Other OpenIM Services](#other-openim-services)
+ - [Supported Component Upgrade Order](#supported-component-upgrade-order)
+ - [openim-api](#openim-api-1)
+ - [openim-rpc-\* Components](#openim-rpc--components-1)
+ - [Other OpenIM Services](#other-openim-services-1)
+ - [Conclusion](#conclusion)
- [Applying Principles: A Git Workflow Example](#applying-principles-a-git-workflow-example)
+ - [Release Process](#release-process)
- [Docker Images Version Management](#docker-images-version-management)
+ - [More](#more)
At OpenIM, we acknowledge the profound impact of implementing a robust and efficient version management system, hence we abide by the established standards of [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/).
@@ -213,3 +227,10 @@ Throughout this process, active communication within the team is pivotal to main
## Docker Images Version Management
For more details on managing Docker image versions, visit [OpenIM Docker Images Administration](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/images.md).
+
+## More
+
+More on multi-branch version management design and version management design at helm charts:
+
++ https://github.com/openimsdk/open-im-server/issues/1695
++ https://github.com/openimsdk/open-im-server/issues/1662
\ No newline at end of file
diff --git a/pkg/common/config/version b/pkg/common/config/version
index e682ea429..4d0729e54 100644
--- a/pkg/common/config/version
+++ b/pkg/common/config/version
@@ -1 +1 @@
-v3.3.0
\ No newline at end of file
+v3.5.0
\ No newline at end of file
diff --git a/pkg/msgprocessor/conversation.go b/pkg/msgprocessor/conversation.go
index 56255f37c..7477bea7a 100644
--- a/pkg/msgprocessor/conversation.go
+++ b/pkg/msgprocessor/conversation.go
@@ -52,6 +52,7 @@ func GetChatConversationIDByMsg(msg *sdkws.MsgData) string {
case constant.NotificationChatType:
return "sn_" + msg.SendID + "_" + msg.RecvID
}
+
return ""
}
diff --git a/pkg/msgprocessor/options.go b/pkg/msgprocessor/options.go
index ea383a1af..c6e209b98 100644
--- a/pkg/msgprocessor/options.go
+++ b/pkg/msgprocessor/options.go
@@ -37,6 +37,7 @@ func NewOptions(opts ...OptionsOpt) Options {
for _, opt := range opts {
opt(options)
}
+
return options
}
diff --git a/scripts/genconfig.sh b/scripts/genconfig.sh
index 2371edc9d..8ded38b22 100755
--- a/scripts/genconfig.sh
+++ b/scripts/genconfig.sh
@@ -29,16 +29,8 @@ if [ $# -ne 2 ];then
exit 1
fi
-openim::util::require-dig
-result=$?
-if [ $result -ne 0 ]; then
- openim::log::info "Please install 'dig' to use this feature."
- openim::log::info "Installation instructions:"
- openim::log::info " For Ubuntu/Debian: sudo apt-get install dnsutils"
- openim::log::info " For CentOS/RedHat: sudo yum install bind-utils"
- openim::log::info " For macOS: 'dig' should be preinstalled. If missing, try: brew install bind"
- openim::log::info " For Windows: Install BIND9 tools from https://www.isc.org/download/"
- openim::log::error_exit "Error: 'dig' command is required but not installed."
+if [ -z "${OPENIM_IP}" ]; then
+ openim::util::require-dig
fi
source "${env_file}"
diff --git a/scripts/install-im-server.sh b/scripts/install-im-server.sh
index 16ac625ee..9afbb97c9 100755
--- a/scripts/install-im-server.sh
+++ b/scripts/install-im-server.sh
@@ -1,4 +1,18 @@
#!/usr/bin/env bash
+# Copyright © 2024 OpenIM. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
#
# OpenIM Docker Deployment Script
#
diff --git a/scripts/install/environment.sh b/scripts/install/environment.sh
index a95bf6a93..9d9fc4028 100755
--- a/scripts/install/environment.sh
+++ b/scripts/install/environment.sh
@@ -171,13 +171,13 @@ def "MONGO_URI" # MongoDB的URI
def "MONGO_PORT" "37017" # MongoDB的端口
def "MONGO_ADDRESS" "${DOCKER_BRIDGE_GATEWAY}" # MongoDB的地址
def "MONGO_DATABASE" "${DATABASE_NAME}" # MongoDB的数据库名
-def "MONGO_USERNAME" "root" # MongoDB的管理员身份用户名
+def "MONGO_USERNAME" "root" # MongoDB的管理员身份用户名
# MongoDB的管理员身份密码
readonly MONGO_PASSWORD=${MONGO_PASSWORD:-"${PASSWORD}"}
# Mongo OpenIM 身份用户名
def "MONGO_OPENIM_USERNAME" "openIM"
# Mongo OpenIM 身份密码
-readonly MONGO_OPENIM_PASSWORD=${MONGO_OPENIM_PASSWORD:-'openIM123456'}
+readonly MONGO_OPENIM_PASSWORD=${MONGO_OPENIM_PASSWORD:-"${PASSWORD}"}
def "MONGO_MAX_POOL_SIZE" "100" # 最大连接池大小
diff --git a/scripts/lib/util.sh b/scripts/lib/util.sh
index b8d76edeb..4de240972 100755
--- a/scripts/lib/util.sh
+++ b/scripts/lib/util.sh
@@ -1146,8 +1146,13 @@ function openim::util::require-jq {
# Checks whether dig is installed and provides installation instructions if it is not.
function openim::util::require-dig {
if ! command -v dig &>/dev/null; then
- openim::log::error "dig command not found."
- return 1
+ openim::log::error "Please install 'dig' to use this feature."
+ openim::log::error "Installation instructions:"
+ openim::log::error " For Ubuntu/Debian: sudo apt-get install dnsutils"
+ openim::log::error " For CentOS/RedHat: sudo yum install bind-utils"
+ openim::log::error " For macOS: 'dig' should be preinstalled. If missing, try: brew install bind"
+ openim::log::error " For Windows: Install BIND9 tools from https://www.isc.org/download/"
+ openim::log::error_exit "dig command not found."
fi
return 0
}
diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk
index 81b44826b..c56f9f071 100644
--- a/scripts/make-rules/common.mk
+++ b/scripts/make-rules/common.mk
@@ -129,7 +129,7 @@ FIND := find . ! -path './utils/*' ! -path './vendor/*' ! -path './third_party/*
XARGS := xargs -r --no-run-if-empty
# Linux command settings-CODE DIRS Copyright
-CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/config $(ROOT_DIR)/.docker-compose_cfg $(ROOT_DIR)/internal $(ROOT_DIR)/scripts $(ROOT_DIR)/test $(ROOT_DIR)/.github $(ROOT_DIR)/build $(ROOT_DIR)/tools $(ROOT_DIR)/deployments
+CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/config $(ROOT_DIR)/internal $(ROOT_DIR)/scripts $(ROOT_DIR)/test $(ROOT_DIR)/.github $(ROOT_DIR)/build $(ROOT_DIR)/tools $(ROOT_DIR)/deployments
FINDS := find $(CODE_DIRS)
# Makefile settings: Select different behaviors by determining whether V option is set
diff --git a/scripts/mongo-init.sh b/scripts/mongo-init.sh
index bb9519648..41d9ca0aa 100755
--- a/scripts/mongo-init.sh
+++ b/scripts/mongo-init.sh
@@ -18,7 +18,6 @@ mongosh <
Date: Mon, 8 Jan 2024 15:16:28 +0800
Subject: [PATCH 04/20] feat: send msg at text (#1705)
---
internal/api/msg.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/internal/api/msg.go b/internal/api/msg.go
index 548450534..9348596ac 100644
--- a/internal/api/msg.go
+++ b/internal/api/msg.go
@@ -164,6 +164,8 @@ func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendM
data = apistruct.VideoElem{}
case constant.File:
data = apistruct.FileElem{}
+ case constant.AtText:
+ data = apistruct.AtElem{}
case constant.Custom:
data = apistruct.CustomElem{}
case constant.OANotification:
@@ -172,7 +174,6 @@ func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendM
if err = m.userRpcClient.GetNotificationByID(c, req.SendID); err != nil {
return nil, err
}
-
default:
return nil, errs.ErrArgs.WithDetail("not support err contentType")
}
From d91a665891570c5be7b0b77e510a0178973b2140 Mon Sep 17 00:00:00 2001
From: Brabem <69128477+luhaoling@users.noreply.github.com>
Date: Mon, 8 Jan 2024 21:38:48 +0800
Subject: [PATCH 05/20] fix: fix some bug (#1710)
* fix: test the getUser api
* fix: fix the go.mod
* fix: fix the go.mod
* fix: fix the go.mod
* fix: fix the addNotificationAccount req
* fix: fix the addnotificationAccount resp
* fix: fix the searchNotificationResp
* fix: fix the go mod
* fix: fix the field of PageFindUser
* Update openimci.yml
* Update openimci.yml
---------
Co-authored-by: Xinwei Xiong <3293172751@qq.com>
---
.github/workflows/openimci.yml | 5 +-
go.mod | 4 +-
go.sum | 8 +--
internal/rpc/user/user.go | 83 +++++++++++++++-------------
pkg/common/db/controller/user.go | 6 ++
pkg/common/db/mgo/user.go | 4 ++
pkg/common/db/table/relation/user.go | 1 +
7 files changed, 65 insertions(+), 46 deletions(-)
diff --git a/.github/workflows/openimci.yml b/.github/workflows/openimci.yml
index 96e03f214..00339110c 100644
--- a/.github/workflows/openimci.yml
+++ b/.github/workflows/openimci.yml
@@ -161,7 +161,8 @@ jobs:
```
${{ env.containers }}
```
- GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ continue-on-error: true
execute-scripts:
name: Execute OpenIM Script On ${{ matrix.os }}
@@ -285,4 +286,4 @@ jobs:
id: docker_processes
run: |
sudo docker images
- sudo docker ps
\ No newline at end of file
+ sudo docker ps
diff --git a/go.mod b/go.mod
index f10e123a0..345cf044d 100644
--- a/go.mod
+++ b/go.mod
@@ -4,8 +4,8 @@ go 1.19
require (
firebase.google.com/go v3.13.0+incompatible
- github.com/OpenIMSDK/protocol v0.0.44
- github.com/OpenIMSDK/tools v0.0.21
+ github.com/OpenIMSDK/protocol v0.0.46
+ github.com/OpenIMSDK/tools v0.0.23
github.com/bwmarrin/snowflake v0.3.0 // indirect
github.com/dtm-labs/rockscache v0.1.1
github.com/gin-gonic/gin v1.9.1
diff --git a/go.sum b/go.sum
index 34f5d3ae9..8a102d347 100644
--- a/go.sum
+++ b/go.sum
@@ -18,10 +18,10 @@ firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIw
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c=
github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ=
-github.com/OpenIMSDK/protocol v0.0.44 h1:P+9gJ9EW3y+VmzrjPludzn/5r1fjubaC19mKYJ7Oiew=
-github.com/OpenIMSDK/protocol v0.0.44/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
-github.com/OpenIMSDK/tools v0.0.21 h1:iTapc2mIEVH/xl5Nd6jfwPub11Pgp44tVcE1rjB3a48=
-github.com/OpenIMSDK/tools v0.0.21/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
+github.com/OpenIMSDK/protocol v0.0.46 h1:LKfwcC3pUcJKSxiIyj82fc479BuDbDtsCrPxa7bHxmo=
+github.com/OpenIMSDK/protocol v0.0.46/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
+github.com/OpenIMSDK/tools v0.0.23 h1:xozfrGzhbpNPlDTap5DLVPk+JfgZ/ZyIj4Cuu3/bm9w=
+github.com/OpenIMSDK/tools v0.0.23/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go
index 51403d631..a1e2c75bc 100644
--- a/internal/rpc/user/user.go
+++ b/internal/rpc/user/user.go
@@ -17,6 +17,7 @@ package user
import (
"context"
"errors"
+ "github.com/OpenIMSDK/tools/pagination"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
"math/rand"
"strings"
@@ -58,6 +59,11 @@ type userServer struct {
RegisterCenter registry.SvcDiscoveryRegistry
}
+func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.ProcessUserCommandGetAllReq) (*pbuser.ProcessUserCommandGetAllResp, error) {
+ //TODO implement me
+ panic("implement me")
+}
+
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
rdb, err := cache.NewRedis()
if err != nil {
@@ -228,7 +234,7 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR
}
func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPaginationUsersReq) (resp *pbuser.GetPaginationUsersResp, err error) {
- total, users, err := s.Page(ctx, req.Pagination)
+ total, users, err := s.PageFindUser(ctx, constant.IMOrdinaryUser, req.Pagination)
if err != nil {
return nil, err
}
@@ -379,11 +385,6 @@ func (s *userServer) GetSubscribeUsersStatus(ctx context.Context,
// ProcessUserCommandAdd user general function add
func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) {
- // Assuming you have a method in s.UserDatabase to add a user command
- err := s.UserDatabase.AddUserCommand(ctx, req.UserID, req.Type, req.Uuid, req.Value)
- if err != nil {
- return nil, err
- }
return &pbuser.ProcessUserCommandAddResp{}, nil
}
@@ -401,11 +402,6 @@ func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.P
// ProcessUserCommandUpdate user general function update
func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) {
- // Assuming you have a method in s.UserDatabase to update a user command
- err := s.UserDatabase.UpdateUserCommand(ctx, req.UserID, req.Type, req.Uuid, req.Value)
- if err != nil {
- return nil, err
- }
return &pbuser.ProcessUserCommandUpdateResp{}, nil
}
@@ -430,7 +426,7 @@ func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.Proc
}
// Return the response with the slice
- return &pbuser.ProcessUserCommandGetResp{KVArray: commandInfoSlice}, nil
+ return &pbuser.ProcessUserCommandGetResp{}, nil
}
func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.AddNotificationAccountReq) (*pbuser.AddNotificationAccountResp, error) {
@@ -438,22 +434,23 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add
return nil, err
}
- var userID string
- for i := 0; i < 20; i++ {
- userId := s.genUserID()
- _, err := s.UserDatabase.FindWithError(ctx, []string{userId})
- if err == nil {
- continue
+ if req.UserID == "" {
+ for i := 0; i < 20; i++ {
+ userId := s.genUserID()
+ _, err := s.UserDatabase.FindWithError(ctx, []string{userId})
+ if err == nil {
+ continue
+ }
+ req.UserID = userId
+ break
+ }
+ if req.UserID == "" {
+ return nil, errs.ErrInternalServer.Wrap("gen user id failed")
}
- userID = userId
- break
- }
- if userID == "" {
- return nil, errs.ErrInternalServer.Wrap("gen user id failed")
}
user := &tablerelation.UserModel{
- UserID: userID,
+ UserID: req.UserID,
Nickname: req.NickName,
FaceURL: req.FaceURL,
CreateTime: time.Now(),
@@ -463,7 +460,11 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add
return nil, err
}
- return &pbuser.AddNotificationAccountResp{}, nil
+ return &pbuser.AddNotificationAccountResp{
+ UserID: req.UserID,
+ NickName: req.NickName,
+ FaceURL: req.FaceURL,
+ }, nil
}
func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context, req *pbuser.UpdateNotificationAccountInfoReq) (*pbuser.UpdateNotificationAccountInfoResp, error) {
@@ -497,30 +498,33 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.
return nil, err
}
- if req.NickName != "" {
- users, err := s.UserDatabase.FindByNickname(ctx, req.NickName)
+ var users []*relation.UserModel
+ var err error
+ if req.Keyword != "" {
+ users, err = s.UserDatabase.Find(ctx, []string{req.Keyword})
if err != nil {
return nil, err
}
- resp := s.userModelToResp(users)
- return resp, nil
- }
-
- if req.UserID != "" {
- users, err := s.UserDatabase.Find(ctx, []string{req.UserID})
+ resp := s.userModelToResp(users, req.Pagination)
+ if resp.Total != 0 {
+ return resp, nil
+ }
+ users, err = s.UserDatabase.FindByNickname(ctx, req.Keyword)
if err != nil {
return nil, err
}
- resp := s.userModelToResp(users)
+ resp = s.userModelToResp(users, req.Pagination)
+ return resp, nil
+
return resp, nil
}
- users, err := s.UserDatabase.FindNotification(ctx, constant.AppNotificationAdmin)
+ users, err = s.UserDatabase.FindNotification(ctx, constant.AppNotificationAdmin)
if err != nil {
return nil, err
}
- resp := s.userModelToResp(users)
+ resp := s.userModelToResp(users, req.Pagination)
return resp, nil
}
@@ -554,7 +558,7 @@ func (s *userServer) genUserID() string {
return string(data)
}
-func (s *userServer) userModelToResp(users []*relation.UserModel) *pbuser.SearchNotificationAccountResp {
+func (s *userServer) userModelToResp(users []*relation.UserModel, pagination pagination.Pagination) *pbuser.SearchNotificationAccountResp {
accounts := make([]*pbuser.NotificationAccountInfo, 0)
var total int64
for _, v := range users {
@@ -568,5 +572,8 @@ func (s *userServer) userModelToResp(users []*relation.UserModel) *pbuser.Search
total += 1
}
}
- return &pbuser.SearchNotificationAccountResp{Total: total, NotificationAccounts: accounts}
+
+ notificationAccounts := utils.Paginate(accounts, int(pagination.GetPageNumber()), int(pagination.GetShowNumber()))
+
+ return &pbuser.SearchNotificationAccountResp{Total: total, NotificationAccounts: notificationAccounts}
}
diff --git a/pkg/common/db/controller/user.go b/pkg/common/db/controller/user.go
index a109b81ef..445700e5e 100644
--- a/pkg/common/db/controller/user.go
+++ b/pkg/common/db/controller/user.go
@@ -50,6 +50,8 @@ type UserDatabase interface {
UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error)
// Page If not found, no error is returned
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
+ // FindUser
+ PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
// IsExist true as long as one exists
IsExist(ctx context.Context, userIDs []string) (exist bool, err error)
// GetAllUserID Get all user IDs
@@ -182,6 +184,10 @@ func (u *userDatabase) Page(ctx context.Context, pagination pagination.Paginatio
return u.userDB.Page(ctx, pagination)
}
+func (u *userDatabase) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
+ return u.userDB.PageFindUser(ctx, level, pagination)
+}
+
// IsExist Does userIDs exist? As long as there is one, it will be true.
func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist bool, err error) {
users, err := u.userDB.Find(ctx, userIDs)
diff --git a/pkg/common/db/mgo/user.go b/pkg/common/db/mgo/user.go
index 27ca264dd..892a42003 100644
--- a/pkg/common/db/mgo/user.go
+++ b/pkg/common/db/mgo/user.go
@@ -77,6 +77,10 @@ func (u *UserMgo) Page(ctx context.Context, pagination pagination.Pagination) (c
return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, pagination)
}
+func (u *UserMgo) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
+ return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{"app_manger_level": level}, pagination)
+}
+
func (u *UserMgo) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) {
return mgoutil.FindPage[string](ctx, u.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"user_id": 1}))
}
diff --git a/pkg/common/db/table/relation/user.go b/pkg/common/db/table/relation/user.go
index fc116adc2..9844bdcee 100644
--- a/pkg/common/db/table/relation/user.go
+++ b/pkg/common/db/table/relation/user.go
@@ -56,6 +56,7 @@ type UserModelInterface interface {
TakeNotification(ctx context.Context, level int64) (user []*UserModel, err error)
TakeByNickname(ctx context.Context, nickname string) (user []*UserModel, err error)
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*UserModel, err error)
+ PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*UserModel, err error)
Exist(ctx context.Context, userID string) (exist bool, err error)
GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, err error)
GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error)
From 3ff588896f53f6ed2465074cb8e8b9a219211800 Mon Sep 17 00:00:00 2001
From: skiffer-git <72860476+skiffer-git@users.noreply.github.com>
Date: Mon, 8 Jan 2024 21:40:04 +0800
Subject: [PATCH 06/20] update: update readme (#1714)
* update: update readme
* update: update readme
* update: update readme
* update: update readme
---
README-zh_CN.md | 56 +++++++++-------
README.md | 174 ++++++++----------------------------------------
2 files changed, 59 insertions(+), 171 deletions(-)
diff --git a/README-zh_CN.md b/README-zh_CN.md
index e2df68a56..12a56d4f6 100644
--- a/README-zh_CN.md
+++ b/README-zh_CN.md
@@ -35,52 +35,62 @@
## Ⓜ️ 关于 OpenIM
-OpenIM 不仅仅是一个开源的即时消息组件,它是你的应用程序生态系统的一个不可或缺的部分。查看下面的图表,了解 AppServer、AppClient、OpenIMServer 和 OpenIMSDK 是如何交互的。
+OpenIM 是一个专门设计用于在应用程序中集成聊天、音视频通话、通知以及AI聊天机器人等通信功能的服务平台。它通过提供一系列强大的API和Webhooks,使开发者可以轻松地在他们的应用中加入这些交互特性。OpenIM 本身并不是一个独立运行的聊天应用,而是作为一个平台,为其他应用提供支持,实现丰富的通信功能。下图展示 AppServer、AppClient、OpenIMServer 和 OpenIMSDK 之间的交互关系来具体说明。
+
+
+
+

## 🚀 关于 OpenIMSDK
-**OpenIMSDK** 无缝集成到您的应用中,提供丰富、实时的消息体验,无需复杂的 UI 集成。它提供:
+**OpenIMSDK** 是为 **OpenIMServer** 设计的IM SDK,专为嵌入客户端应用而生。其主要功能及模块如下:
-+ **本地存储**:用于快速数据检索和消息同步。
-+ **监听器回调**:确保实时消息交互性。
-+ **API 封装**:简化开发流程。
-+ **连接管理**:保证可靠的消息传递。
++ 🌟 主要功能:
-它使用 Golang 构建,并支持跨平台部署,确保在所有平台上提供一致的消息体验。
+ - 📦 本地存储
+ - 🔔 监听器回调
+ - 🛡️ API封装
+ - 🌐 连接管理
+
+ ## 📚 主要模块:
+
+ 1. 🚀 初始化及登录
+ 2. 👤 用户管理
+ 3. 👫 好友管理
+ 4. 🤖 群组功能
+ 5. 💬 会话处理
+
+它使用 Golang 构建,并支持跨平台部署,确保在所有平台上提供一致的接入体验。
👉 **[探索 GO SDK](https://github.com/openimsdk/openim-sdk-core)**
## 🌐 关于 OpenIMServer
-精心用 Golang 开发的 **OpenIMServer** 通过多重方式确保了卓越的即时消息服务器能力:
-
-+ **模块组成**:它由多个模块组成,例如网关和多个 RPC 服务,提供一个多功能的消息环境。
-+ **微服务架构**:支持集群模式,确保出色的性能和可伸缩性,以有效管理各个实例间的通信。
-+ **多样的部署选项**:适应你的操作偏好,通过源代码、Kubernetes 或 Docker 提供部署选项。
++ **OpenIMServer** 具有以下特点:
+ - 🌐 微服务架构:支持集群模式,包括网关(gateway)和多个rpc服务。
+ - 🚀 部署方式多样:支持源代码、kubernetes或docker部署。
+ - 海量用户支持:十万超级大群,千万用户,及百亿消息
### 增强的业务功能:
-+ **REST API**:OpenIMServer 为业务系统提供 REST API,旨在通过后端接口为您的操作提供附加功能,如群组创建和消息推送。
-+ **回调**:为了扩展其在各种业务形式中的实用性,OpenIMServer 提供了回调能力。即,在事件发生之前或之后,它向业务服务器发送请求,比如发送消息,丰富通信过程中的交互和数据交换流。
++ **REST API**:OpenIMServer 提供了REST API供业务系统使用,旨在赋予业务更多功能,例如通过后台接口建立群组、发送推送消息等。
++ **Webhooks**:OpenIMServer提供了回调能力以扩展更多的业务形态,所谓回调,即OpenIMServer会在某一事件发生之前或者之后,向业务服务器发送请求,如发送消息之前或之后的回调。
-👉 **[了解更多](https://doc.rentsoft.cn/guides/introduction/product)**
+👉 **[了解更多](https://docs.openim.io/guides/introduction/product)**
## :rocket: 快速开始
-你只需要一个简单的命令,就可以快速学习 OpenIM 的工程解决方案:
+在线体验iOS/Android/H5/PC/Web:
-```
-bashCopy code
-$ make demo
-```
+👉 **[OpenIM online demo](https://www.openim.io/zh/commercial)**
🤲 为了方便用户体验,我们提供了多种部署解决方案,您可以根据下面的列表选择自己的部署方法:
-+ **[源代码部署指南](https://doc.rentsoft.cn/guides/gettingStarted/imSourceCodeDeployment)**
-+ **[Docker 部署指南](https://doc.rentsoft.cn/guides/gettingStarted/dockerCompose)**
-+ **[Kubernetes 部署指南](https://github.com/openimsdk/open-im-server/tree/main/deployments)**
++ **[源代码部署指南](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
++ **[Docker 部署指南](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
++ **[Kubernetes 部署指南](https://docs.openim.io/guides/gettingStarted/k8s-deployment)**
## :hammer_and_wrench: 开始开发 OpenIM
diff --git a/README.md b/README.md
index 781db1217..025672a0b 100644
--- a/README.md
+++ b/README.md
@@ -25,178 +25,56 @@
-
## Ⓜ️ About OpenIM
-OpenIM isn't just an open-source instant messaging component, it's an integral part of your application ecosystem. Check out this diagram to understand how AppServer, AppClient, OpenIMServer, and OpenIMSDK interact.
+OpenIM is a service platform specifically designed for integrating chat, audio-video calls, notifications, and AI chatbots into applications. It provides a range of powerful APIs and Webhooks, enabling developers to easily incorporate these interactive features into their applications. OpenIM is not a standalone chat application, but rather serves as a platform to support other applications in achieving rich communication functionalities. The following diagram illustrates the interaction between AppServer, AppClient, OpenIMServer, and OpenIMSDK to explain in detail.

## 🚀 About OpenIMSDK
-**OpenIMSDK** seamlessly integrates into your application, delivering a rich, real-time messaging experience without requiring intricate UI integration. It provides:
-
-+ **Local Storage**: For quick data retrieval and message synchronization.
-+ **Listener Callbacks**: Ensuring real-time message interactivity.
-+ **API Encapsulation**: Streamlining development processes.
-+ **Connection Management**: Guaranteeing reliable message delivery.
-
-It's crafted in Golang and supports cross-platform deployment, ensuring a coherent messaging experience across all platforms.
-
-👉 **[Explore GO SDK](https://github.com/openimsdk/openim-sdk-core)**
-
-## 🌐 About OpenIMServer
-
-**OpenIMServer**, meticulously developed in Golang, ensures a stellar instant messaging server capability with a multifold approach:
-
-+ **Modular Composition**: It's comprised of several modules, such as the gateway and multiple RPC services, offering a versatile messaging environment.
-+ **Microservices Architecture**: Supporting cluster modes, it assures outstanding performance and scalability to manage communication effectively across various instances.
-+ **Diverse Deployment Options**: Adapts to your operational preferences, offering deployment via source code, Kubernetes, or Docker.
-
-### Enhanced Business Functionalities:
-
-+ **REST API**: OpenIMServer provides REST API for business systems, aiming to empower your operations with additional functionalities like group creation and message push via backend interfaces.
-+ **Callbacks**: To expand its utility across varied business forms, OpenIMServer offers callback capabilities. That is, it sends a request to the business server before or after an event occurs, such as sending a message, enriching the interaction and data exchange flow in the communication processes.
-
-👉 **[Learn More](https://docs.openim.io/guides/introduction/product)**
-
-
++ **REST API**: OpenIMServer offers REST APIs for business systems, aimed at empowering businesses with more functionalities, such as creating groups and sending push messages through backend interfaces.
++ **Webhooks**: OpenIMServer provides callback capabilities to extend more business forms. A callback means that OpenIMServer sends a request to the business server before or after a certain event, like callbacks before or after sending a message.
+👉 **[Learn more](https://docs.openim.io/guides/introduction/product)**
## :rocket: Quick Start
-We support many platforms. Here are the addresses for quick experience on the web side:
-
-👉 **[OpenIM online web demo](https://web-enterprise.rentsoft.cn/)**
-
-You can quickly learn OpenIM engineering solutions, all it takes is one simple command:
-
-```bash
-$ make demo
-```
-
-🤲 In order to facilitate the user experience, we have provided a variety of deployment solutions, you can choose your own deployment method according to the list below:
-
-
+🤲 To facilitate user experience, we offer various deployment solutions. You can choose your deployment method from the list below:
+ **[Source Code Deployment Guide](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
-+ **[Production deployment of Linux systems](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/install-openim-linux-system.md)**
+ **[Docker Deployment Guide](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
-+ **[Kubernetes Deployment Guide](https://github.com/openimsdk/open-im-server/tree/main/deployments)**
-
-
++ **[Kubernetes Deployment Guide](https://docs.openim.io/guides/gettingStarted/k8s-deployment)**
## :hammer_and_wrench: To start developing OpenIM
From 535ae19f7aea4ac06ca1959951396704f67e9674 Mon Sep 17 00:00:00 2001
From: Gordon <46924906+FGadvancer@users.noreply.github.com>
Date: Tue, 9 Jan 2024 14:49:31 +0800
Subject: [PATCH 07/20] fix: group messages sync failed. (#1720)
* fix: add notifications for some notifications.
* fix: modify dismissed group's status.
* fix: Adjust the logic in multiTerminalLoginChecker to prevent onlineUserNum from decreasing below zero, thereby avoiding negative values.
* fix: group messages sync failed.
---
pkg/common/db/controller/conversation.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pkg/common/db/controller/conversation.go b/pkg/common/db/controller/conversation.go
index 2a0cb63e4..c6629e9c8 100644
--- a/pkg/common/db/controller/conversation.go
+++ b/pkg/common/db/controller/conversation.go
@@ -279,7 +279,7 @@ func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context,
for _, v := range existConversationUserIDs {
cache = cache.DelConversations(v, conversationID)
}
- return c.cache.ExecDel(ctx)
+ return cache.ExecDel(ctx)
})
}
From a2a082f681a900c0c064b5aca5227b6e4c56b12d Mon Sep 17 00:00:00 2001
From: AndrewZuo01 <59896149+AndrewZuo01@users.noreply.github.com>
Date: Wed, 10 Jan 2024 10:27:03 +0800
Subject: [PATCH 08/20] update usercommand and fix callback (#1681)
* update set pin friends
* update set pin friends
* update set pin friends
* update set pin friends
* update set pin friends
* update set pin friends
* fix bugs
* fix bugs
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* Update go.mod
* Update friend.go
* debug
* debug
* debug
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* I cannot solve todo in test.sh
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* Update go.mod
* fix group notification
* fix group notification
* update openimsdk tools
* update openim server remove duplicate code
* update openim server remove duplicate code
* update user command get
* update user command get
* update response of callback response error
* update black ex
* update join group ex
* update user pb2map
* update go sum
* update go sum
* update updateUserInfoEx
* update updateUserInfoEx
* update updateUserInfoEx add callback functions
* fix dismiss group function
* fix dismiss group function
* fix dismiss group function
* fix dismiss group function
* update pin friend to update friend
* fix go mod
* fix err golangci-lint
* fix UserPb2DBMap
* update comments, update go.mod check for register username
* update comments, update go.mod check for register username
* update comments, update go.mod check for register username
* update comments, update go.mod check for register username
* fix callback
* fix go.mod
* fix debug
* fix bugs
* update notification
* update notification
* update notification
* update notification
* update notification
* update notification
* update notification
* update notification
* fix updateUserInfoEx
* fix updateUserInfoEx
* modify go.mod
* fix updateUserInfoEx
* fix updateUserInfoEx
* fix updateUserInfoEx
* update user command notification
* update user command get all notification
* update user command get all notification
* fix type = 0
* fix type = 0
* fix type = 0
* fix type = 0
* fix type = 0
* fix type = 0
* fix typing cause callback
* add ex to usercommand
* add ex to usercommand
* update updatefriends
* fix updatefriend map
* fix updatefriend FriendsInfoUpdateNotification
* fix push online and offline user, but why typing trigger callback push?
* fix push online and offline user, but why typing trigger callback push?
* update user command record not found and user access check
* update user command get all user access check
* update go.mod
* fix callback name and place
* upadtae callback test
* fix callback typing
* fix callback typing
* fix callback typing
* fix callback typing
* fix lint on processusercommand
---------
Co-authored-by: Xinwei Xiong <3293172751@qq.com>
---
deployments/templates/openim.yaml | 8 ++
internal/api/route.go | 1 +
internal/api/user.go | 5 ++
internal/push/callback.go | 6 +-
internal/push/push_to_client.go | 5 +-
internal/rpc/friend/friend.go | 29 +++----
internal/rpc/group/callback.go | 8 +-
internal/rpc/group/group.go | 2 +-
internal/rpc/msg/callback.go | 8 +-
internal/rpc/msg/send.go | 2 +
internal/rpc/user/user.go | 108 +++++++++++++++++++++++--
pkg/callbackstruct/constant.go | 2 +-
pkg/common/config/config.go | 2 +-
pkg/common/db/cache/friend.go | 14 ++++
pkg/common/db/controller/friend.go | 30 ++-----
pkg/common/db/controller/user.go | 17 ++--
pkg/common/db/mgo/friend.go | 54 +++----------
pkg/common/db/mgo/user.go | 80 ++++++++++++++++--
pkg/common/db/table/relation/friend.go | 8 +-
pkg/common/db/table/relation/user.go | 5 +-
pkg/rpcclient/notification/friend.go | 2 +-
pkg/rpcclient/notification/user.go | 18 +++++
22 files changed, 287 insertions(+), 127 deletions(-)
diff --git a/deployments/templates/openim.yaml b/deployments/templates/openim.yaml
index 6880e4c4e..4c84373a5 100644
--- a/deployments/templates/openim.yaml
+++ b/deployments/templates/openim.yaml
@@ -320,6 +320,14 @@ callback:
enable: ${CALLBACK_ENABLE}
timeout: ${CALLBACK_TIMEOUT}
failedContinue: ${CALLBACK_FAILED_CONTINUE}
+ beforeUpdateUserInfoEx:
+ enable: ${CALLBACK_ENABLE}
+ timeout: ${CALLBACK_TIMEOUT}
+ failedContinue: ${CALLBACK_FAILED_CONTINUE}
+ afterUpdateUserInfoEx:
+ enable: ${CALLBACK_ENABLE}
+ timeout: ${CALLBACK_TIMEOUT}
+ failedContinue: ${CALLBACK_FAILED_CONTINUE}
afterSendSingleMsg:
enable: ${CALLBACK_ENABLE}
timeout: ${CALLBACK_TIMEOUT}
diff --git a/internal/api/route.go b/internal/api/route.go
index 1c91f4dde..8729bc1b9 100644
--- a/internal/api/route.go
+++ b/internal/api/route.go
@@ -83,6 +83,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
userRouterGroup.POST("/process_user_command_delete", ParseToken, u.ProcessUserCommandDelete)
userRouterGroup.POST("/process_user_command_update", ParseToken, u.ProcessUserCommandUpdate)
userRouterGroup.POST("/process_user_command_get", ParseToken, u.ProcessUserCommandGet)
+ userRouterGroup.POST("/process_user_command_get_all", ParseToken, u.ProcessUserCommandGetAll)
userRouterGroup.POST("/add_notification_account", ParseToken, u.AddNotificationAccount)
userRouterGroup.POST("/update_notification_account", ParseToken, u.UpdateNotificationAccountInfo)
diff --git a/internal/api/user.go b/internal/api/user.go
index 5f0e23631..03d22c354 100644
--- a/internal/api/user.go
+++ b/internal/api/user.go
@@ -221,6 +221,11 @@ func (u *UserApi) ProcessUserCommandGet(c *gin.Context) {
a2r.Call(user.UserClient.ProcessUserCommandGet, u.Client, c)
}
+// ProcessUserCommandGet user general function get all
+func (u *UserApi) ProcessUserCommandGetAll(c *gin.Context) {
+ a2r.Call(user.UserClient.ProcessUserCommandGetAll, u.Client, c)
+}
+
func (u *UserApi) AddNotificationAccount(c *gin.Context) {
a2r.Call(user.UserClient.AddNotificationAccount, u.Client, c)
}
diff --git a/internal/push/callback.go b/internal/push/callback.go
index 2085493c5..99a58fb07 100644
--- a/internal/push/callback.go
+++ b/internal/push/callback.go
@@ -37,7 +37,7 @@ func callbackOfflinePush(
msg *sdkws.MsgData,
offlinePushUserIDs *[]string,
) error {
- if !config.Config.Callback.CallbackOfflinePush.Enable {
+ if !config.Config.Callback.CallbackOfflinePush.Enable || msg.ContentType == constant.Typing {
return nil
}
req := &callbackstruct.CallbackBeforePushReq{
@@ -73,7 +73,7 @@ func callbackOfflinePush(
}
func callbackOnlinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
- if !config.Config.Callback.CallbackOnlinePush.Enable || utils.Contain(msg.SendID, userIDs...) {
+ if !config.Config.Callback.CallbackOnlinePush.Enable || utils.Contain(msg.SendID, userIDs...) || msg.ContentType == constant.Typing {
return nil
}
req := callbackstruct.CallbackBeforePushReq{
@@ -107,7 +107,7 @@ func callbackBeforeSuperGroupOnlinePush(
msg *sdkws.MsgData,
pushToUserIDs *[]string,
) error {
- if !config.Config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable {
+ if !config.Config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable || msg.ContentType == constant.Typing {
return nil
}
req := callbackstruct.CallbackBeforeSuperGroupOnlinePushReq{
diff --git a/internal/push/push_to_client.go b/internal/push/push_to_client.go
index 12b78ea2d..7cee7b99d 100644
--- a/internal/push/push_to_client.go
+++ b/internal/push/push_to_client.go
@@ -101,11 +101,9 @@ func (p *Pusher) DeleteMemberAndSetConversationSeq(ctx context.Context, groupID
func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
log.ZDebug(ctx, "Get msg from msg_transfer And push msg", "userIDs", userIDs, "msg", msg.String())
- // callback
if err := callbackOnlinePush(ctx, userIDs, msg); err != nil {
return err
}
-
// push
wsResults, err := p.GetConnsAndOnlinePush(ctx, msg, userIDs)
if err != nil {
@@ -120,7 +118,7 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg
}
for _, v := range wsResults {
- if msg.SendID != v.UserID && (!v.OnlinePush) {
+ if !v.OnlinePush && msg.SendID == v.UserID {
if err = callbackOfflinePush(ctx, userIDs, msg, &[]string{}); err != nil {
return err
}
@@ -130,6 +128,7 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg
return err
}
}
+
}
return nil
}
diff --git a/internal/rpc/friend/friend.go b/internal/rpc/friend/friend.go
index c53cb88f5..84702f548 100644
--- a/internal/rpc/friend/friend.go
+++ b/internal/rpc/friend/friend.go
@@ -452,22 +452,19 @@ func (s *friendServer) UpdateFriends(
return nil, err
}
- for _, friendID := range req.FriendUserIDs {
- if req.IsPinned != nil {
- if err = s.friendDatabase.UpdateFriendPinStatus(ctx, req.OwnerUserID, friendID, req.IsPinned.Value); err != nil {
- return nil, err
- }
- }
- if req.Remark != nil {
- if err = s.friendDatabase.UpdateFriendRemark(ctx, req.OwnerUserID, friendID, req.Remark.Value); err != nil {
- return nil, err
- }
- }
- if req.Ex != nil {
- if err = s.friendDatabase.UpdateFriendEx(ctx, req.OwnerUserID, friendID, req.Ex.Value); err != nil {
- return nil, err
- }
- }
+ val := make(map[string]any)
+
+ if req.IsPinned != nil {
+ val["is_pinned"] = req.IsPinned.Value
+ }
+ if req.Remark != nil {
+ val["remark"] = req.Remark.Value
+ }
+ if req.Ex != nil {
+ val["ex"] = req.Ex.Value
+ }
+ if err = s.friendDatabase.UpdateFriends(ctx, req.OwnerUserID, req.FriendUserIDs, val); err != nil {
+ return nil, err
}
resp := &pbfriend.UpdateFriendsResp{}
diff --git a/internal/rpc/group/callback.go b/internal/rpc/group/callback.go
index 8779cb89b..d891f4d1e 100644
--- a/internal/rpc/group/callback.go
+++ b/internal/rpc/group/callback.go
@@ -279,20 +279,20 @@ func CallbackApplyJoinGroupBefore(ctx context.Context, req *callbackstruct.Callb
return nil
}
-func CallbackTransferGroupOwnerAfter(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) (err error) {
- if !config.Config.Callback.CallbackTransferGroupOwnerAfter.Enable {
+func CallbackAfterTransferGroupOwner(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) (err error) {
+ if !config.Config.Callback.CallbackAfterTransferGroupOwner.Enable {
return nil
}
cbReq := &callbackstruct.CallbackTransferGroupOwnerReq{
- CallbackCommand: callbackstruct.CallbackTransferGroupOwnerAfter,
+ CallbackCommand: callbackstruct.CallbackAfterTransferGroupOwner,
GroupID: req.GroupID,
OldOwnerUserID: req.OldOwnerUserID,
NewOwnerUserID: req.NewOwnerUserID,
}
resp := &callbackstruct.CallbackTransferGroupOwnerResp{}
- if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeJoinGroup); err != nil {
+ if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterTransferGroupOwner); err != nil {
return err
}
return nil
diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go
index b1ea0aa03..f9b73ad2b 100644
--- a/internal/rpc/group/group.go
+++ b/internal/rpc/group/group.go
@@ -1061,7 +1061,7 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans
return nil, err
}
- if err := CallbackTransferGroupOwnerAfter(ctx, req); err != nil {
+ if err := CallbackAfterTransferGroupOwner(ctx, req); err != nil {
return nil, err
}
s.Notification.GroupOwnerTransferredNotification(ctx, req)
diff --git a/internal/rpc/msg/callback.go b/internal/rpc/msg/callback.go
index 5d192fb87..f98318bba 100644
--- a/internal/rpc/msg/callback.go
+++ b/internal/rpc/msg/callback.go
@@ -70,7 +70,7 @@ func GetContent(msg *sdkws.MsgData) string {
}
func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
- if !config.Config.Callback.CallbackBeforeSendSingleMsg.Enable {
+ if !config.Config.Callback.CallbackBeforeSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
return nil
}
req := &cbapi.CallbackBeforeSendSingleMsgReq{
@@ -85,7 +85,7 @@ func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) er
}
func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
- if !config.Config.Callback.CallbackAfterSendSingleMsg.Enable {
+ if !config.Config.Callback.CallbackAfterSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
return nil
}
req := &cbapi.CallbackAfterSendSingleMsgReq{
@@ -100,7 +100,7 @@ func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) err
}
func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
- if !config.Config.Callback.CallbackBeforeSendGroupMsg.Enable {
+ if !config.Config.Callback.CallbackBeforeSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
return nil
}
req := &cbapi.CallbackBeforeSendGroupMsgReq{
@@ -115,7 +115,7 @@ func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) err
}
func callbackAfterSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
- if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable {
+ if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
return nil
}
req := &cbapi.CallbackAfterSendGroupMsgReq{
diff --git a/internal/rpc/msg/send.go b/internal/rpc/msg/send.go
index dd08292bd..630b74a4a 100644
--- a/internal/rpc/msg/send.go
+++ b/internal/rpc/msg/send.go
@@ -65,6 +65,7 @@ func (m *msgServer) sendMsgSuperGroupChat(
if err = callbackBeforeSendGroupMsg(ctx, req); err != nil {
return nil, err
}
+
if err := callbackMsgModify(ctx, req); err != nil {
return nil, err
}
@@ -167,6 +168,7 @@ func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbmsg.SendMsgReq
if err = callbackBeforeSendSingleMsg(ctx, req); err != nil {
return nil, err
}
+
if err := callbackMsgModify(ctx, req); err != nil {
return nil, err
}
diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go
index a1e2c75bc..21b419fa3 100644
--- a/internal/rpc/user/user.go
+++ b/internal/rpc/user/user.go
@@ -59,11 +59,6 @@ type userServer struct {
RegisterCenter registry.SvcDiscoveryRegistry
}
-func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.ProcessUserCommandGetAllReq) (*pbuser.ProcessUserCommandGetAllResp, error) {
- //TODO implement me
- panic("implement me")
-}
-
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
rdb, err := cache.NewRedis()
if err != nil {
@@ -385,28 +380,94 @@ func (s *userServer) GetSubscribeUsersStatus(ctx context.Context,
// ProcessUserCommandAdd user general function add
func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) {
+ err := authverify.CheckAccessV3(ctx, req.UserID)
+ if err != nil {
+ return nil, err
+ }
+ var value string
+ if req.Value != nil {
+ value = req.Value.Value
+ }
+ var ex string
+ if req.Ex != nil {
+ value = req.Ex.Value
+ }
+ // Assuming you have a method in s.UserDatabase to add a user command
+ err = s.UserDatabase.AddUserCommand(ctx, req.UserID, req.Type, req.Uuid, value, ex)
+ if err != nil {
+ return nil, err
+ }
+ tips := &sdkws.UserCommandAddTips{
+ FromUserID: req.UserID,
+ ToUserID: req.UserID,
+ }
+ err = s.userNotificationSender.UserCommandAddNotification(ctx, tips)
+ if err != nil {
+ return nil, err
+ }
return &pbuser.ProcessUserCommandAddResp{}, nil
}
// ProcessUserCommandDelete user general function delete
func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) {
- // Assuming you have a method in s.UserDatabase to delete a user command
- err := s.UserDatabase.DeleteUserCommand(ctx, req.UserID, req.Type, req.Uuid)
+ err := authverify.CheckAccessV3(ctx, req.UserID)
if err != nil {
return nil, err
}
+ err = s.UserDatabase.DeleteUserCommand(ctx, req.UserID, req.Type, req.Uuid)
+ if err != nil {
+ return nil, err
+ }
+ tips := &sdkws.UserCommandDeleteTips{
+ FromUserID: req.UserID,
+ ToUserID: req.UserID,
+ }
+ err = s.userNotificationSender.UserCommandDeleteNotification(ctx, tips)
+ if err != nil {
+ return nil, err
+ }
return &pbuser.ProcessUserCommandDeleteResp{}, nil
}
// ProcessUserCommandUpdate user general function update
func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) {
+ err := authverify.CheckAccessV3(ctx, req.UserID)
+ if err != nil {
+ return nil, err
+ }
+ val := make(map[string]any)
+ // Map fields from eax to val
+ if req.Value != nil {
+ val["value"] = req.Value.Value
+ }
+ if req.Ex != nil {
+ val["ex"] = req.Ex.Value
+ }
+
+ // Assuming you have a method in s.UserDatabase to update a user command
+ err = s.UserDatabase.UpdateUserCommand(ctx, req.UserID, req.Type, req.Uuid, val)
+ if err != nil {
+ return nil, err
+ }
+ tips := &sdkws.UserCommandUpdateTips{
+ FromUserID: req.UserID,
+ ToUserID: req.UserID,
+ }
+ err = s.userNotificationSender.UserCommandUpdateNotification(ctx, tips)
+ if err != nil {
+ return nil, err
+ }
return &pbuser.ProcessUserCommandUpdateResp{}, nil
}
func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.ProcessUserCommandGetReq) (*pbuser.ProcessUserCommandGetResp, error) {
+ err := authverify.CheckAccessV3(ctx, req.UserID)
+ if err != nil {
+ return nil, err
+ }
// Fetch user commands from the database
commands, err := s.UserDatabase.GetUserCommands(ctx, req.UserID, req.Type)
if err != nil {
@@ -419,14 +480,45 @@ func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.Proc
for _, command := range commands {
// No need to use index since command is already a pointer
commandInfoSlice = append(commandInfoSlice, &pbuser.CommandInfoResp{
+ Type: command.Type,
+ Uuid: command.Uuid,
+ Value: command.Value,
+ CreateTime: command.CreateTime,
+ Ex: command.Ex,
+ })
+ }
+
+ // Return the response with the slice
+ return &pbuser.ProcessUserCommandGetResp{CommandResp: commandInfoSlice}, nil
+}
+
+func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.ProcessUserCommandGetAllReq) (*pbuser.ProcessUserCommandGetAllResp, error) {
+ err := authverify.CheckAccessV3(ctx, req.UserID)
+ if err != nil {
+ return nil, err
+ }
+ // Fetch user commands from the database
+ commands, err := s.UserDatabase.GetAllUserCommands(ctx, req.UserID)
+ if err != nil {
+ return nil, err
+ }
+
+ // Initialize commandInfoSlice as an empty slice
+ commandInfoSlice := make([]*pbuser.AllCommandInfoResp, 0, len(commands))
+
+ for _, command := range commands {
+ // No need to use index since command is already a pointer
+ commandInfoSlice = append(commandInfoSlice, &pbuser.AllCommandInfoResp{
+ Type: command.Type,
Uuid: command.Uuid,
Value: command.Value,
CreateTime: command.CreateTime,
+ Ex: command.Ex,
})
}
// Return the response with the slice
- return &pbuser.ProcessUserCommandGetResp{}, nil
+ return &pbuser.ProcessUserCommandGetAllResp{CommandResp: commandInfoSlice}, nil
}
func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.AddNotificationAccountReq) (*pbuser.AddNotificationAccountResp, error) {
diff --git a/pkg/callbackstruct/constant.go b/pkg/callbackstruct/constant.go
index cda98af16..f3bcf1383 100644
--- a/pkg/callbackstruct/constant.go
+++ b/pkg/callbackstruct/constant.go
@@ -41,7 +41,7 @@ const (
CallbackBeforeUpdateUserInfoExCommand = "callbackBeforeUpdateUserInfoExCommand"
CallbackBeforeUserRegisterCommand = "callbackBeforeUserRegisterCommand"
CallbackAfterUserRegisterCommand = "callbackAfterUserRegisterCommand"
- CallbackTransferGroupOwnerAfter = "callbackTransferGroupOwnerAfter"
+ CallbackAfterTransferGroupOwner = "callbackAfterTransferGroupOwner"
CallbackBeforeSetFriendRemark = "callbackBeforeSetFriendRemark"
CallbackAfterSetFriendRemark = "callbackAfterSetFriendRemark"
CallbackSingleMsgRead = "callbackSingleMsgRead"
diff --git a/pkg/common/config/config.go b/pkg/common/config/config.go
index 88e87e709..9696e9367 100644
--- a/pkg/common/config/config.go
+++ b/pkg/common/config/config.go
@@ -296,7 +296,7 @@ type configStruct struct {
CallbackKillGroupMember CallBackConfig `yaml:"killGroupMember"`
CallbackDismissGroup CallBackConfig `yaml:"dismissGroup"`
CallbackBeforeJoinGroup CallBackConfig `yaml:"joinGroup"`
- CallbackTransferGroupOwnerAfter CallBackConfig `yaml:"transferGroupOwner"`
+ CallbackAfterTransferGroupOwner CallBackConfig `yaml:"transferGroupOwner"`
CallbackBeforeInviteUserToGroup CallBackConfig `yaml:"beforeInviteUserToGroup"`
CallbackAfterJoinGroup CallBackConfig `yaml:"joinGroupAfter"`
CallbackAfterSetGroupInfo CallBackConfig `yaml:"setGroupInfoAfter"`
diff --git a/pkg/common/db/cache/friend.go b/pkg/common/db/cache/friend.go
index 1708f7664..a2b60d48f 100644
--- a/pkg/common/db/cache/friend.go
+++ b/pkg/common/db/cache/friend.go
@@ -44,6 +44,8 @@ type FriendCache interface {
GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error)
// Delete friend when friend info changed
DelFriend(ownerUserID, friendUserID string) FriendCache
+ // Delete friends when friends' info changed
+ DelFriends(ownerUserID string, friendUserIDs []string) FriendCache
}
// FriendCacheRedis is an implementation of the FriendCache interface using Redis.
@@ -152,3 +154,15 @@ func (f *FriendCacheRedis) DelFriend(ownerUserID, friendUserID string) FriendCac
return newFriendCache
}
+
+// DelFriends deletes multiple friend infos from the cache.
+func (f *FriendCacheRedis) DelFriends(ownerUserID string, friendUserIDs []string) FriendCache {
+ newFriendCache := f.NewCache()
+
+ for _, friendUserID := range friendUserIDs {
+ key := f.getFriendKey(ownerUserID, friendUserID)
+ newFriendCache.AddKeys(key) // Assuming AddKeys marks the keys for deletion
+ }
+
+ return newFriendCache
+}
diff --git a/pkg/common/db/controller/friend.go b/pkg/common/db/controller/friend.go
index 924a179ba..3b98f5d7b 100644
--- a/pkg/common/db/controller/friend.go
+++ b/pkg/common/db/controller/friend.go
@@ -74,15 +74,8 @@ type FriendDatabase interface {
// FindBothFriendRequests finds friend requests sent and received
FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error)
- // UpdateFriendPinStatus updates the pinned status of a friend
- UpdateFriendPinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (err error)
-
- // UpdateFriendRemark updates the remark for a friend
- UpdateFriendRemark(ctx context.Context, ownerUserID string, friendUserID string, remark string) (err error)
-
- // UpdateFriendEx updates the 'ex' field for a friend
- UpdateFriendEx(ctx context.Context, ownerUserID string, friendUserID string, ex string) (err error)
-
+ // UpdateFriends updates fields for friends
+ UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) (err error)
}
type friendDatabase struct {
@@ -323,21 +316,12 @@ func (f *friendDatabase) FindFriendUserIDs(ctx context.Context, ownerUserID stri
func (f *friendDatabase) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error) {
return f.friendRequest.FindBothFriendRequests(ctx, fromUserID, toUserID)
}
-func (f *friendDatabase) UpdateFriendPinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (err error) {
- if err := f.friend.UpdatePinStatus(ctx, ownerUserID, friendUserID, isPinned); err != nil {
- return err
+func (f *friendDatabase) UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) (err error) {
+ if len(val) == 0 {
+ return nil
}
- return f.cache.DelFriend(ownerUserID, friendUserID).ExecDel(ctx)
-}
-func (f *friendDatabase) UpdateFriendRemark(ctx context.Context, ownerUserID string, friendUserID string, remark string) (err error) {
- if err := f.friend.UpdateFriendRemark(ctx, ownerUserID, friendUserID, remark); err != nil {
+ if err := f.friend.UpdateFriends(ctx, ownerUserID, friendUserIDs, val); err != nil {
return err
}
- return f.cache.DelFriend(ownerUserID, friendUserID).ExecDel(ctx)
-}
-func (f *friendDatabase) UpdateFriendEx(ctx context.Context, ownerUserID string, friendUserID string, ex string) (err error) {
- if err := f.friend.UpdateFriendEx(ctx, ownerUserID, friendUserID, ex); err != nil {
- return err
- }
- return f.cache.DelFriend(ownerUserID, friendUserID).ExecDel(ctx)
+ return f.cache.DelFriends(ownerUserID, friendUserIDs).ExecDel(ctx)
}
diff --git a/pkg/common/db/controller/user.go b/pkg/common/db/controller/user.go
index 445700e5e..cedae5c97 100644
--- a/pkg/common/db/controller/user.go
+++ b/pkg/common/db/controller/user.go
@@ -78,10 +78,11 @@ type UserDatabase interface {
SetUserStatus(ctx context.Context, userID string, status, platformID int32) error
//CRUD user command
- AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error
+ AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string, ex string) error
DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error
- UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error
+ UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, val map[string]any) error
GetUserCommands(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error)
+ GetAllUserCommands(ctx context.Context, userID string) ([]*user.AllCommandInfoResp, error)
}
type userDatabase struct {
@@ -259,16 +260,20 @@ func (u *userDatabase) GetUserStatus(ctx context.Context, userIDs []string) ([]*
func (u *userDatabase) SetUserStatus(ctx context.Context, userID string, status, platformID int32) error {
return u.cache.SetUserStatus(ctx, userID, status, platformID)
}
-func (u *userDatabase) AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error {
- return u.userDB.AddUserCommand(ctx, userID, Type, UUID, value)
+func (u *userDatabase) AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string, ex string) error {
+ return u.userDB.AddUserCommand(ctx, userID, Type, UUID, value, ex)
}
func (u *userDatabase) DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error {
return u.userDB.DeleteUserCommand(ctx, userID, Type, UUID)
}
-func (u *userDatabase) UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error {
- return u.userDB.UpdateUserCommand(ctx, userID, Type, UUID, value)
+func (u *userDatabase) UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, val map[string]any) error {
+ return u.userDB.UpdateUserCommand(ctx, userID, Type, UUID, val)
}
func (u *userDatabase) GetUserCommands(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error) {
commands, err := u.userDB.GetUserCommand(ctx, userID, Type)
return commands, err
}
+func (u *userDatabase) GetAllUserCommands(ctx context.Context, userID string) ([]*user.AllCommandInfoResp, error) {
+ commands, err := u.userDB.GetAllUserCommand(ctx, userID)
+ return commands, err
+}
diff --git a/pkg/common/db/mgo/friend.go b/pkg/common/db/mgo/friend.go
index 72289181b..b4172d0fb 100644
--- a/pkg/common/db/mgo/friend.go
+++ b/pkg/common/db/mgo/friend.go
@@ -16,7 +16,6 @@ package mgo
import (
"context"
- "github.com/OpenIMSDK/tools/errs"
"github.com/OpenIMSDK/tools/mgoutil"
"github.com/OpenIMSDK/tools/pagination"
"go.mongodb.org/mongo-driver/mongo/options"
@@ -144,49 +143,22 @@ func (f *FriendMgo) FindFriendUserIDs(ctx context.Context, ownerUserID string) (
return mgoutil.Find[string](ctx, f.coll, filter, options.Find().SetProjection(bson.M{"_id": 0, "friend_user_id": 1}))
}
-// UpdatePinStatus update friend's pin status
-func (f *FriendMgo) UpdatePinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (err error) {
-
- filter := bson.M{"owner_user_id": ownerUserID, "friend_user_id": friendUserID}
- // Create an update operation to set the "is_pinned" field to isPinned for all documents.
- update := bson.M{"$set": bson.M{"is_pinned": isPinned}}
-
- // Perform the update operation for all documents in the collection.
- _, err = f.coll.UpdateMany(ctx, filter, update)
-
- if err != nil {
- return errs.Wrap(err, "update pin error")
+func (f *FriendMgo) UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) error {
+ // Ensure there are IDs to update
+ if len(friendUserIDs) == 0 {
+ return nil // Or return an error if you expect there to always be IDs
}
- return nil
-}
-func (f *FriendMgo) UpdateFriendRemark(ctx context.Context, ownerUserID string, friendUserID string, remark string) (err error) {
-
- filter := bson.M{"owner_user_id": ownerUserID, "friend_user_id": friendUserID}
- // Create an update operation to set the "is_pinned" field to isPinned for all documents.
- update := bson.M{"$set": bson.M{"remark": remark}}
-
- // Perform the update operation for all documents in the collection.
- _, err = f.coll.UpdateMany(ctx, filter, update)
-
- if err != nil {
- return errs.Wrap(err, "update remark error")
+ // Create a filter to match documents with the specified ownerUserID and any of the friendUserIDs
+ filter := bson.M{
+ "owner_user_id": ownerUserID,
+ "friend_user_id": bson.M{"$in": friendUserIDs},
}
- return nil
-}
-func (f *FriendMgo) UpdateFriendEx(ctx context.Context, ownerUserID string, friendUserID string, ex string) (err error) {
-
- filter := bson.M{"owner_user_id": ownerUserID, "friend_user_id": friendUserID}
- // Create an update operation to set the "is_pinned" field to isPinned for all documents.
- update := bson.M{"$set": bson.M{"ex": ex}}
-
- // Perform the update operation for all documents in the collection.
- _, err = f.coll.UpdateMany(ctx, filter, update)
-
- if err != nil {
- return errs.Wrap(err, "update ex error")
- }
+ // Create an update document
+ update := bson.M{"$set": val}
- return nil
+ // Perform the update operation for all matching documents
+ _, err := mgoutil.UpdateMany(ctx, f.coll, filter, update)
+ return err
}
diff --git a/pkg/common/db/mgo/user.go b/pkg/common/db/mgo/user.go
index 892a42003..b82966371 100644
--- a/pkg/common/db/mgo/user.go
+++ b/pkg/common/db/mgo/user.go
@@ -17,6 +17,7 @@ package mgo
import (
"context"
"github.com/OpenIMSDK/protocol/user"
+ "github.com/OpenIMSDK/tools/errs"
"time"
"github.com/OpenIMSDK/tools/mgoutil"
@@ -100,7 +101,7 @@ func (u *UserMgo) CountTotal(ctx context.Context, before *time.Time) (count int6
return mgoutil.Count(ctx, u.coll, bson.M{"create_time": bson.M{"$lt": before}})
}
-func (u *UserMgo) AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error {
+func (u *UserMgo) AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string, ex string) error {
collection := u.coll.Database().Collection("userCommands")
// Create a new document instead of updating an existing one
@@ -110,28 +111,48 @@ func (u *UserMgo) AddUserCommand(ctx context.Context, userID string, Type int32,
"uuid": UUID,
"createTime": time.Now().Unix(), // assuming you want the creation time in Unix timestamp
"value": value,
+ "ex": ex,
}
_, err := collection.InsertOne(ctx, doc)
return err
}
+
func (u *UserMgo) DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error {
collection := u.coll.Database().Collection("userCommands")
filter := bson.M{"userID": userID, "type": Type, "uuid": UUID}
- _, err := collection.DeleteOne(ctx, filter)
+ result, err := collection.DeleteOne(ctx, filter)
+ if result.DeletedCount == 0 {
+ // No records found to update
+ return errs.Wrap(errs.ErrRecordNotFound)
+ }
return err
}
-func (u *UserMgo) UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error {
+func (u *UserMgo) UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, val map[string]any) error {
+ if len(val) == 0 {
+ return nil
+ }
+
collection := u.coll.Database().Collection("userCommands")
filter := bson.M{"userID": userID, "type": Type, "uuid": UUID}
- update := bson.M{"$set": bson.M{"value": value}}
+ update := bson.M{"$set": val}
- _, err := collection.UpdateOne(ctx, filter, update)
- return err
+ result, err := collection.UpdateOne(ctx, filter, update)
+ if err != nil {
+ return err
+ }
+
+ if result.MatchedCount == 0 {
+ // No records found to update
+ return errs.Wrap(errs.ErrRecordNotFound)
+ }
+
+ return nil
}
+
func (u *UserMgo) GetUserCommand(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error) {
collection := u.coll.Database().Collection("userCommands")
filter := bson.M{"userID": userID, "type": Type}
@@ -147,19 +168,23 @@ func (u *UserMgo) GetUserCommand(ctx context.Context, userID string, Type int32)
for cursor.Next(ctx) {
var document struct {
+ Type int32 `bson:"type"`
UUID string `bson:"uuid"`
Value string `bson:"value"`
CreateTime int64 `bson:"createTime"`
+ Ex string `bson:"ex"`
}
if err := cursor.Decode(&document); err != nil {
return nil, err
}
- commandInfo := &user.CommandInfoResp{ // Change here: use a pointer to the struct
+ commandInfo := &user.CommandInfoResp{
+ Type: document.Type,
Uuid: document.UUID,
Value: document.Value,
CreateTime: document.CreateTime,
+ Ex: document.Ex,
}
commands = append(commands, commandInfo)
@@ -171,7 +196,48 @@ func (u *UserMgo) GetUserCommand(ctx context.Context, userID string, Type int32)
return commands, nil
}
+func (u *UserMgo) GetAllUserCommand(ctx context.Context, userID string) ([]*user.AllCommandInfoResp, error) {
+ collection := u.coll.Database().Collection("userCommands")
+ filter := bson.M{"userID": userID}
+ cursor, err := collection.Find(ctx, filter)
+ if err != nil {
+ return nil, err
+ }
+ defer cursor.Close(ctx)
+
+ // Initialize commands as a slice of pointers
+ commands := []*user.AllCommandInfoResp{}
+
+ for cursor.Next(ctx) {
+ var document struct {
+ Type int32 `bson:"type"`
+ UUID string `bson:"uuid"`
+ Value string `bson:"value"`
+ CreateTime int64 `bson:"createTime"`
+ Ex string `bson:"ex"`
+ }
+
+ if err := cursor.Decode(&document); err != nil {
+ return nil, err
+ }
+
+ commandInfo := &user.AllCommandInfoResp{
+ Type: document.Type,
+ Uuid: document.UUID,
+ Value: document.Value,
+ CreateTime: document.CreateTime,
+ Ex: document.Ex,
+ }
+
+ commands = append(commands, commandInfo)
+ }
+
+ if err := cursor.Err(); err != nil {
+ return nil, err
+ }
+ return commands, nil
+}
func (u *UserMgo) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) {
pipeline := bson.A{
bson.M{
diff --git a/pkg/common/db/table/relation/friend.go b/pkg/common/db/table/relation/friend.go
index cc337701d..73f7454df 100644
--- a/pkg/common/db/table/relation/friend.go
+++ b/pkg/common/db/table/relation/friend.go
@@ -57,10 +57,6 @@ type FriendModelInterface interface {
FindInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*FriendModel, err error)
// FindFriendUserIDs retrieves a list of friend user IDs for a given owner.
FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error)
- // UpdatePinStatus update friend's pin status
- UpdatePinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (err error)
- // UpdateFriendRemark update friend's remark
- UpdateFriendRemark(ctx context.Context, ownerUserID string, friendUserID string, remark string) (err error)
- // UpdateFriendEx update friend's ex
- UpdateFriendEx(ctx context.Context, ownerUserID string, friendUserID string, ex string) (err error)
+ // UpdateFriends update friends' fields
+ UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) (err error)
}
diff --git a/pkg/common/db/table/relation/user.go b/pkg/common/db/table/relation/user.go
index 9844bdcee..a1b4269d1 100644
--- a/pkg/common/db/table/relation/user.go
+++ b/pkg/common/db/table/relation/user.go
@@ -65,8 +65,9 @@ type UserModelInterface interface {
// 获取范围内用户增量
CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error)
//CRUD user command
- AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error
+ AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string, ex string) error
DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error
- UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error
+ UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, val map[string]any) error
GetUserCommand(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error)
+ GetAllUserCommand(ctx context.Context, userID string) ([]*user.AllCommandInfoResp, error)
}
diff --git a/pkg/rpcclient/notification/friend.go b/pkg/rpcclient/notification/friend.go
index 00759b1b2..b98a1d38e 100644
--- a/pkg/rpcclient/notification/friend.go
+++ b/pkg/rpcclient/notification/friend.go
@@ -197,7 +197,7 @@ func (f *FriendNotificationSender) FriendRemarkSetNotification(ctx context.Conte
return f.Notification(ctx, fromUserID, toUserID, constant.FriendRemarkSetNotification, &tips)
}
func (f *FriendNotificationSender) FriendsInfoUpdateNotification(ctx context.Context, toUserID string, friendIDs []string) error {
- tips := sdkws.FriendsInfoUpdateTips{}
+ tips := sdkws.FriendsInfoUpdateTips{FromToUserID: &sdkws.FromToUserID{}}
tips.FromToUserID.ToUserID = toUserID
tips.FriendIDs = friendIDs
return f.Notification(ctx, toUserID, toUserID, constant.FriendsInfoUpdateNotification, &tips)
diff --git a/pkg/rpcclient/notification/user.go b/pkg/rpcclient/notification/user.go
index 4feebf7b9..4347faece 100644
--- a/pkg/rpcclient/notification/user.go
+++ b/pkg/rpcclient/notification/user.go
@@ -103,3 +103,21 @@ func (u *UserNotificationSender) UserStatusChangeNotification(
) error {
return u.Notification(ctx, tips.FromUserID, tips.ToUserID, constant.UserStatusChangeNotification, tips)
}
+func (u *UserNotificationSender) UserCommandUpdateNotification(
+ ctx context.Context,
+ tips *sdkws.UserCommandUpdateTips,
+) error {
+ return u.Notification(ctx, tips.FromUserID, tips.ToUserID, constant.UserCommandUpdateNotification, tips)
+}
+func (u *UserNotificationSender) UserCommandAddNotification(
+ ctx context.Context,
+ tips *sdkws.UserCommandAddTips,
+) error {
+ return u.Notification(ctx, tips.FromUserID, tips.ToUserID, constant.UserCommandAddNotification, tips)
+}
+func (u *UserNotificationSender) UserCommandDeleteNotification(
+ ctx context.Context,
+ tips *sdkws.UserCommandDeleteTips,
+) error {
+ return u.Notification(ctx, tips.FromUserID, tips.ToUserID, constant.UserCommandDeleteNotification, tips)
+}
From 1c72e46cc97732c5e67e4547c2782d243ae7c789 Mon Sep 17 00:00:00 2001
From: Brabem <69128477+luhaoling@users.noreply.github.com>
Date: Wed, 10 Jan 2024 10:55:55 +0800
Subject: [PATCH 09/20] fix: fix the GetSortedConversationList (#1725)
* fix: improve the GetSortedConversation api
* fix: fix the go.mod
* fix: fix the valiable name
---
go.mod | 2 +-
go.sum | 4 ++--
internal/api/conversation.go | 4 ++--
internal/api/route.go | 2 +-
internal/rpc/conversation/conversaion.go | 29 +++++++++++++++---------
internal/rpc/user/user.go | 5 ++++
6 files changed, 29 insertions(+), 17 deletions(-)
diff --git a/go.mod b/go.mod
index 345cf044d..5e8e7275b 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.19
require (
firebase.google.com/go v3.13.0+incompatible
- github.com/OpenIMSDK/protocol v0.0.46
+ github.com/OpenIMSDK/protocol v0.0.47
github.com/OpenIMSDK/tools v0.0.23
github.com/bwmarrin/snowflake v0.3.0 // indirect
github.com/dtm-labs/rockscache v0.1.1
diff --git a/go.sum b/go.sum
index 8a102d347..80a02d20a 100644
--- a/go.sum
+++ b/go.sum
@@ -18,8 +18,8 @@ firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIw
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c=
github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ=
-github.com/OpenIMSDK/protocol v0.0.46 h1:LKfwcC3pUcJKSxiIyj82fc479BuDbDtsCrPxa7bHxmo=
-github.com/OpenIMSDK/protocol v0.0.46/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
+github.com/OpenIMSDK/protocol v0.0.47 h1:DTJMFSONzqT0i/wa4Q1CtDT/jVATVudIRHcpY1zSWYE=
+github.com/OpenIMSDK/protocol v0.0.47/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
github.com/OpenIMSDK/tools v0.0.23 h1:xozfrGzhbpNPlDTap5DLVPk+JfgZ/ZyIj4Cuu3/bm9w=
github.com/OpenIMSDK/tools v0.0.23/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
diff --git a/internal/api/conversation.go b/internal/api/conversation.go
index 6463cbde6..eb735e550 100644
--- a/internal/api/conversation.go
+++ b/internal/api/conversation.go
@@ -33,8 +33,8 @@ func (o *ConversationApi) GetAllConversations(c *gin.Context) {
a2r.Call(conversation.ConversationClient.GetAllConversations, o.Client, c)
}
-func (o *ConversationApi) GetConversationsList(c *gin.Context) {
- a2r.Call(conversation.ConversationClient.GetConversationList, o.Client, c)
+func (o *ConversationApi) GetSortedConversationList(c *gin.Context) {
+ a2r.Call(conversation.ConversationClient.GetSortedConversationList, o.Client, c)
}
func (o *ConversationApi) GetConversation(c *gin.Context) {
diff --git a/internal/api/route.go b/internal/api/route.go
index 8729bc1b9..3f16d3e50 100644
--- a/internal/api/route.go
+++ b/internal/api/route.go
@@ -205,7 +205,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
conversationGroup := r.Group("/conversation", ParseToken)
{
c := NewConversationApi(*conversationRpc)
- conversationGroup.POST("/get_conversations_list", c.GetConversationsList)
+ conversationGroup.POST("/get_sorted_conversation_list", c.GetSortedConversationList)
conversationGroup.POST("/get_all_conversations", c.GetAllConversations)
conversationGroup.POST("/get_conversation", c.GetConversation)
conversationGroup.POST("/get_conversations", c.GetConversations)
diff --git a/internal/rpc/conversation/conversaion.go b/internal/rpc/conversation/conversaion.go
index b80e32953..d0d59547c 100644
--- a/internal/rpc/conversation/conversaion.go
+++ b/internal/rpc/conversation/conversaion.go
@@ -89,8 +89,8 @@ func (c *conversationServer) GetConversation(ctx context.Context, req *pbconvers
return resp, nil
}
-func (m *conversationServer) GetConversationList(ctx context.Context, req *pbconversation.GetConversationListReq) (resp *pbconversation.GetConversationListResp, err error) {
- log.ZDebug(ctx, "GetConversationList", "seqs", req, "userID", req.UserID)
+func (m *conversationServer) GetSortedConversationList(ctx context.Context, req *pbconversation.GetSortedConversationListReq) (resp *pbconversation.GetSortedConversationListResp, err error) {
+ log.ZDebug(ctx, "GetSortedConversationList", "seqs", req, "userID", req.UserID)
var conversationIDs []string
if len(req.ConversationIDs) == 0 {
conversationIDs, err = m.conversationDatabase.GetConversationIDs(ctx, req.UserID)
@@ -129,30 +129,37 @@ func (m *conversationServer) GetConversationList(ctx context.Context, req *pbcon
return nil, err
}
+ var unreadTotal int64
conversation_unreadCount := make(map[string]int64)
for conversationID, maxSeq := range maxSeqs {
- conversation_unreadCount[conversationID] = maxSeq - hasReadSeqs[conversationID]
+ unreadCount := maxSeq - hasReadSeqs[conversationID]
+ conversation_unreadCount[conversationID] = unreadCount
+ unreadTotal += unreadCount
}
- conversation_isPinkTime := make(map[int64]string)
- conversation_notPinkTime := make(map[int64]string)
+ conversation_isPinTime := make(map[int64]string)
+ conversation_notPinTime := make(map[int64]string)
for _, v := range conversations {
conversationID := v.ConversationID
time := conversationMsg[conversationID].MsgInfo.LatestMsgRecvTime
conversationMsg[conversationID].RecvMsgOpt = v.RecvMsgOpt
if v.IsPinned {
conversationMsg[conversationID].IsPinned = v.IsPinned
- conversation_isPinkTime[time] = conversationID
+ conversation_isPinTime[time] = conversationID
continue
}
- conversation_notPinkTime[time] = conversationID
+ conversation_notPinTime[time] = conversationID
}
- resp = &pbconversation.GetConversationListResp{
+ resp = &pbconversation.GetSortedConversationListResp{
+ ConversationTotal: int64(len(chatLogs)),
ConversationElems: []*pbconversation.ConversationElem{},
+ UnreadTotal: unreadTotal,
}
- m.conversationSort(conversation_isPinkTime, resp, conversation_unreadCount, conversationMsg)
- m.conversationSort(conversation_notPinkTime, resp, conversation_unreadCount, conversationMsg)
+ m.conversationSort(conversation_isPinTime, resp, conversation_unreadCount, conversationMsg)
+ m.conversationSort(conversation_notPinTime, resp, conversation_unreadCount, conversationMsg)
+
+ resp.ConversationElems = utils.Paginate(resp.ConversationElems, int(req.Pagination.GetPageNumber()), int(req.Pagination.GetShowNumber()))
return resp, nil
}
@@ -425,7 +432,7 @@ func (c *conversationServer) GetConversationOfflinePushUserIDs(
func (c *conversationServer) conversationSort(
conversations map[int64]string,
- resp *pbconversation.GetConversationListResp,
+ resp *pbconversation.GetSortedConversationListResp,
conversation_unreadCount map[string]int64,
conversationMsg map[string]*pbconversation.ConversationElem,
) {
diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go
index 21b419fa3..158e37d70 100644
--- a/internal/rpc/user/user.go
+++ b/internal/rpc/user/user.go
@@ -539,6 +539,11 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add
if req.UserID == "" {
return nil, errs.ErrInternalServer.Wrap("gen user id failed")
}
+ } else {
+ _, err := s.UserDatabase.FindWithError(ctx, []string{req.UserID})
+ if err == nil {
+ return nil, errs.ErrArgs.Wrap("userID is used")
+ }
}
user := &tablerelation.UserModel{
From 04c77bff7e3093b4839484a9404a2c3a1dd60489 Mon Sep 17 00:00:00 2001
From: Brabem <69128477+luhaoling@users.noreply.github.com>
Date: Wed, 10 Jan 2024 18:59:12 +0800
Subject: [PATCH 10/20] fix: fix the mongo search error (#1736)
* fix: improve the GetSortedConversation api
* fix: fix the go.mod
* fix: fix the valiable name
* fix: the FindUser error
* fix: fix the mongo search
---
pkg/common/db/mgo/user.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pkg/common/db/mgo/user.go b/pkg/common/db/mgo/user.go
index b82966371..b07f82928 100644
--- a/pkg/common/db/mgo/user.go
+++ b/pkg/common/db/mgo/user.go
@@ -83,7 +83,7 @@ func (u *UserMgo) PageFindUser(ctx context.Context, level int64, pagination pagi
}
func (u *UserMgo) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) {
- return mgoutil.FindPage[string](ctx, u.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"user_id": 1}))
+ return mgoutil.FindPage[string](ctx, u.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"_id": 0, "user_id": 1}))
}
func (u *UserMgo) Exist(ctx context.Context, userID string) (exist bool, err error) {
@@ -91,7 +91,7 @@ func (u *UserMgo) Exist(ctx context.Context, userID string) (exist bool, err err
}
func (u *UserMgo) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) {
- return mgoutil.FindOne[int](ctx, u.coll, bson.M{"user_id": userID}, options.FindOne().SetProjection(bson.M{"global_recv_msg_opt": 1}))
+ return mgoutil.FindOne[int](ctx, u.coll, bson.M{"user_id": userID}, options.FindOne().SetProjection(bson.M{"_id": 0, "global_recv_msg_opt": 1}))
}
func (u *UserMgo) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) {
From bf46412c5a9d6e68eca1e87f69c6db3aa1d31d13 Mon Sep 17 00:00:00 2001
From: chao <48119764+withchao@users.noreply.github.com>
Date: Fri, 12 Jan 2024 11:49:16 +0800
Subject: [PATCH 11/20] fix: GroupApplicationRejectedNotification not
notification apply for userID (#1740)
* fix: GroupApplicationAcceptedNotification
* fix: GroupApplicationAcceptedNotification
* fix: NotificationUserInfoUpdate
---
internal/rpc/group/group.go | 5 +----
pkg/rpcclient/notification/group.go | 16 +++++++++++++---
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go
index f9b73ad2b..abc271651 100644
--- a/internal/rpc/group/group.go
+++ b/internal/rpc/group/group.go
@@ -109,14 +109,11 @@ type groupServer struct {
}
func (s *groupServer) NotificationUserInfoUpdate(ctx context.Context, req *pbgroup.NotificationUserInfoUpdateReq) (*pbgroup.NotificationUserInfoUpdateResp, error) {
- defer log.ZDebug(ctx, "return")
+ defer log.ZDebug(ctx, "NotificationUserInfoUpdate return")
members, err := s.db.FindGroupMemberUser(ctx, nil, req.UserID)
if err != nil {
return nil, err
}
- if err := s.PopulateGroupMember(ctx, members...); err != nil {
- return nil, err
- }
groupIDs := make([]string, 0, len(members))
for _, member := range members {
if member.Nickname != "" && member.FaceURL != "" {
diff --git a/pkg/rpcclient/notification/group.go b/pkg/rpcclient/notification/group.go
index cbae7c49b..8c3719b2c 100755
--- a/pkg/rpcclient/notification/group.go
+++ b/pkg/rpcclient/notification/group.go
@@ -409,11 +409,16 @@ func (g *GroupNotificationSender) GroupApplicationAcceptedNotification(ctx conte
if err != nil {
return err
}
- tips := &sdkws.GroupApplicationAcceptedTips{Group: group, HandleMsg: req.HandledMsg, ReceiverAs: 1}
+ tips := &sdkws.GroupApplicationAcceptedTips{Group: group, HandleMsg: req.HandledMsg}
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
return err
}
- for _, userID := range append(userIDs, mcontext.GetOpUserID(ctx)) {
+ for _, userID := range append(userIDs, req.FromUserID) {
+ if userID == req.FromUserID {
+ tips.ReceiverAs = 0
+ } else {
+ tips.ReceiverAs = 1
+ }
err = g.Notification(ctx, mcontext.GetOpUserID(ctx), userID, constant.GroupApplicationAcceptedNotification, tips)
if err != nil {
log.ZError(ctx, "failed", err)
@@ -441,7 +446,12 @@ func (g *GroupNotificationSender) GroupApplicationRejectedNotification(ctx conte
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
return err
}
- for _, userID := range append(userIDs, mcontext.GetOpUserID(ctx)) {
+ for _, userID := range append(userIDs, req.FromUserID) {
+ if userID == req.FromUserID {
+ tips.ReceiverAs = 0
+ } else {
+ tips.ReceiverAs = 1
+ }
err = g.Notification(ctx, mcontext.GetOpUserID(ctx), userID, constant.GroupApplicationRejectedNotification, tips)
if err != nil {
log.ZError(ctx, "failed", err)
From c795304df108f4f868b12c72d9889f95f7b73af7 Mon Sep 17 00:00:00 2001
From: Xinwei Xiong <3293172751@qq.com>
Date: Fri, 12 Jan 2024 18:04:06 +0800
Subject: [PATCH 12/20] =?UTF-8?q?=F0=9F=9A=80=20Enhancements=20in=20Offlin?=
=?UTF-8?q?e=20Deployment=20Documentation,=20CICD=20Process=20Upgrades,=20?=
=?UTF-8?q?Deployment=20Optimization,=20and=20Additional=20Fixes=20(#1721)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: support openim prom enbels
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: support openim prom enbels
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: support openim prom enbels
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: support openim prom enbels
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: support openim prom enbels
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: support openim prom enbels
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: support openim prom enbels
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: support openim prom enbels
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add go formity checker
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim offline deployment docs
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim offline deployment docs
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim offline deployment docs
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim support arm arch
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* fix: fox openim support arm arch
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* fix: fox openim support arm arch
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim v3.4 and v3.5 changelog
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add devcontainer.json file
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim v3.4 and v3.5 changelog
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim v3.4 and v3.5 changelog
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* Update util.sh
amend shell get pid command fd on mac.
* feat: Add To start developing OpenIM Docs
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* docs: update openim readme and dov container
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: set openim lint
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
* feat: fix go release scripts
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: fix go release scripts
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* docs(changelog): add CHANGELOG-3.5.0+6.a09200e.md
* docs(changelog): add CHANGELOG-3.5.0+2.e0bd54f.md
* docs(changelog): add CHANGELOG-3.5.0+2.e0bd54f-1-g4ce6a0fa6.md
* feat: set openim lint
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
* docs(changelog): add CHANGELOG-3.5.0+2.e0bd54f-3-g52f9fc209.md
* docs(changelog): add CHANGELOG-3.5.0+2.e0bd54f-4-g87f685b17.md
* docs(changelog): add CHANGELOG-3.5.0.md
* feat: set openim lint
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
* fix: fix scripts functions upload
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* fix: fix scripts functions upload
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* docs(changelog): add CHANGELOG-3.5.0.md
* fix: fix scripts functions upload
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* fix: fix scripts functions upload
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: set openim lint
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
---------
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
Co-authored-by: mrwenhui
---
.devcontainer /README.md | 140 ++
.devcontainer /devcontainer.json | 83 +
.github/workflows/e2e-test.yml | 33 +-
.github/workflows/openimci.yml | 36 +-
CHANGELOG/CHANGELOG-3.4.md | 32 +
CHANGELOG/CHANGELOG-3.5.0.md | 15 +
CHANGELOG/CHANGELOG-3.5.md | 76 +
README.md | 6 +-
assets/README.md | 2 +-
cmd/openim-api/main.go | 4 +-
docker-compose.yml | 56 +-
docs/contrib/environment.md | 4 +-
docs/contrib/gitcherry-pick.md | 2 +-
docs/contrib/github-workflow.md | 5 +-
docs/contrib/init-config.md | 4 +-
.../contrib/mac-developer-deployment-guide.md | 149 ++
docs/contrib/offline-deployment.md | 118 +-
docs/contrib/prometheus-grafana.md | 55 +-
docs/contrib/release.md | 251 +++
go.work | 11 +-
pkg/common/prommetrics/gin_api.go | 4 +-
pkg/common/prommetrics/prommetrics.go | 6 +-
scripts/.spelling_failures | 4 +-
scripts/build-all-service.sh | 2 +-
scripts/check-all.sh | 3 +-
scripts/common.sh | 17 +-
scripts/ensure-tag.sh | 4 +-
scripts/genconfig.sh | 2 +-
scripts/install/environment.sh | 34 +-
scripts/install/openim-man.sh | 6 +-
scripts/install/openim-tools.sh | 9 +-
scripts/lib/chat.sh | 6 +-
scripts/lib/golang.sh | 15 +-
scripts/lib/init.sh | 9 +-
scripts/lib/release.sh | 156 +-
scripts/lib/util.sh | 1490 ++++++++++++++++-
scripts/make-rules/common.mk | 5 +-
scripts/make-rules/tools.mk | 2 +-
scripts/release.sh | 135 +-
scripts/stop-all.sh | 11 +-
scripts/update-generated-docs.sh | 2 +-
scripts/update-yamlfmt.sh | 6 +-
scripts/verify-shellcheck.sh | 2 +-
scripts/verify-spelling.sh | 4 +-
scripts/verify-yamlfmt.sh | 4 +-
test/typecheck/typecheck.go | 8 +-
test/wrktest.sh | 2 +-
tools/changelog/changelog.go | 2 +-
tools/component/component.go | 34 +-
tools/formitychecker/README.md | 102 ++
tools/formitychecker/checker/checker.go | 97 ++
tools/formitychecker/config/config.go | 27 +
tools/formitychecker/formitychecker.go | 27 +
tools/formitychecker/go.mod | 3 +
tools/imctl/imctl.go | 8 +
tools/up35/pkg/convert.go | 70 +-
tools/up35/pkg/pkg.go | 16 +-
tools/yamlfmt/OWNERS | 10 -
58 files changed, 3090 insertions(+), 336 deletions(-)
create mode 100644 .devcontainer /README.md
create mode 100644 .devcontainer /devcontainer.json
create mode 100644 CHANGELOG/CHANGELOG-3.4.md
create mode 100644 CHANGELOG/CHANGELOG-3.5.0.md
create mode 100644 CHANGELOG/CHANGELOG-3.5.md
create mode 100644 docs/contrib/mac-developer-deployment-guide.md
create mode 100644 docs/contrib/release.md
create mode 100644 tools/formitychecker/README.md
create mode 100644 tools/formitychecker/checker/checker.go
create mode 100644 tools/formitychecker/config/config.go
create mode 100644 tools/formitychecker/formitychecker.go
create mode 100644 tools/formitychecker/go.mod
create mode 100644 tools/imctl/imctl.go
delete mode 100644 tools/yamlfmt/OWNERS
diff --git a/.devcontainer /README.md b/.devcontainer /README.md
new file mode 100644
index 000000000..7abba5ac1
--- /dev/null
+++ b/.devcontainer /README.md
@@ -0,0 +1,140 @@
+# OpenIM - OSS Development Container
+
+[](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/openimsdk/open-im-server)
+
+This repository includes configuration for a development container for working with OpenIM - OSS in a local container or using [GitHub Codespaces](https://github.com/features/codespaces).
+
+> **Tip:** The default VNC password is `openIM123`. The VNC server runs on port `5901` and a web client is available on port `11001`, openim-admin on port `11002`.
+
+## Quick start - local
+
+If you already have VS Code and Docker installed, you can click the badge above or [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/openimsdk/open-im-server) to get started. Clicking these links will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.
+
+1. Install Docker Desktop or Docker for Linux on your local machine. (See [docs](https://aka.ms/vscode-remote/containers/getting-started) for additional details.)
+
+2. **Important**: Docker needs at least **4 Cores and 8 GB of RAM** to run a full build with **9 GB of RAM** being recommended. If you are on macOS, or are using the old Hyper-V engine for Windows, update these values for Docker Desktop by right-clicking on the Docker status bar item and going to **Preferences/Settings > Resources > Advanced**.
+
+ > **Note:** The [Resource Monitor](https://marketplace.visualstudio.com/items?itemName=mutantdino.resourcemonitor) extension is included in the container so you can keep an eye on CPU/Memory in the status bar.
+
+3. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Dev Containers](https://aka.ms/vscode-remote/download/containers) extension.
+
+ 
+
+ > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of OpenIM - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details.
+
+4. Press Ctrl/Cmd + Shift + P or F1 and select **Dev Containers: Clone Repository in Container Volume...**.
+
+ > **Tip:** While you can use your local source tree instead, operations like `yarn install` can be slow on macOS or when using the Hyper-V engine on Windows. We recommend using the WSL filesystem on Windows or the "clone repository in container" approach on Windows and macOS instead since it uses "named volume" rather than the local filesystem.
+
+5. Type `https://github.com/openimsdk/open-im-server` (or a branch or PR URL) in the input box and press Enter.
+
+6. After the container is running:
+ 1. If you have the `DISPLAY` or `WAYLAND_DISPLAY` environment variables set locally (or in WSL on Windows), desktop apps in the container will be shown in local windows.
+ 2. If these are not set, open a web browser and go to [http://localhost:11001](http://localhost:11001), or use a [VNC Viewer][def] to connect to `localhost:11001` and enter `vscode` as the password. Anything you start in VS Code, or the integrated terminal, will appear here.
+
+Next: **[Try it out!](#try-it)**
+
+## Quick start - GitHub Codespaces
+
+1. From the [openimsdk/open-im-server GitHub repository](https://github.com/openimsdk/open-im-server), click on the **Code** dropdown, select **Open with Codespaces**, and then click on **New codespace**. If prompted, select the **Standard** machine size (which is also the default).
+
+ > **Note:** You will not see these options within GitHub if you are not in the Codespaces beta.
+
+2. After the codespace is up and running in your browser, press Ctrl/Cmd + Shift + P or F1 and select **Ports: Focus on Ports View**.
+
+3. You should see **VNC web client (11001)** under in the list of ports. Select the line and click on the globe icon to open it in a browser tab.
+
+ > **Tip:** If you do not see the port, Ctrl/Cmd + Shift + P or F1, select **Forward a Port** and enter port `11001`.
+
+4. In the new tab, you should see noVNC. Click **Connect** and enter `vscode` as the password.
+
+Anything you start in VS Code, or the integrated terminal, will appear here.
+
+Next: **[Try it out!](#try-it)**
+
+### Using VS Code with GitHub Codespaces
+
+You may see improved VNC responsiveness when accessing a codespace from VS Code client since you can use a [VNC Viewer][def]. Here's how to do it.
+
+1. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the the [GitHub Codespaces extension](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces).
+
+ > **Note:** The GitHub Codespaces extension requires the Visual Studio Code distribution of OpenIM - OSS.
+
+2. After the VS Code is up and running, press Ctrl/Cmd + Shift + P or F1, choose **Codespaces: Create New Codespace**, and use the following settings:
+
+- `openimsdk/open-im-server` for the repository.
+- Select any branch (e.g. **main**) - you can select a different one later.
+- Choose **Standard** (4-core, 8GB) as the size.
+
+3. After you have connected to the codespace, you can use a [VNC Viewer][def] to connect to `localhost:5901` and enter `vscode` as the password.
+
+ > **Tip:** You may also need change your VNC client's **Picture Quality** setting to **High** to get a full color desktop.
+
+4. Anything you start in VS Code, or the integrated terminal, will appear here.
+
+Next: **[Try it out!](#try-it)**
+
+## Try it
+
+This container uses the [Fluxbox](http://fluxbox.org/) window manager to keep things lean. **Right-click on the desktop** to see menu options. It works with GNOME and GTK applications, so other tools can be installed if needed.
+
+ > **Note:** You can also set the resolution from the command line by typing `set-resolution`.
+
+To start working with OpenIM - OSS, follow these steps:
+
+1. In your local VS Code client, open a terminal (Ctrl/Cmd + Shift + \`) and type the following commands:
+
+ ```bash
+ yarn install
+ bash scripts/code.sh
+ ```
+
+2. After the build is complete, open a web browser or a [VNC Viewer][def] to connect to the desktop environment as described in the quick start and enter `vscode` as the password.
+
+3. You should now see OpenIM - OSS!
+
+Next, let's try debugging.
+
+1. Shut down OpenIM - OSS by clicking the box in the upper right corner of the OpenIM - OSS window through your browser or VNC viewer.
+
+2. Go to your local VS Code client, and use the **Run / Debug** view to launch the **VS Code** configuration. (Typically the default, so you can likely just press F5).
+
+ > **Note:** If launching times out, you can increase the value of `timeout` in the "VS Code", "Attach Main Process", "Attach Extension Host", and "Attach to Shared Process" configurations in [launch.json](../../.vscode/launch.json). However, running `./scripts/code.sh` first will set up Electron which will usually solve timeout issues.
+
+3. After a bit, OpenIM - OSS will appear with the debugger attached!
+
+Enjoy!
+
+
+### Dotfiles
+
+Dotfiles are files and folders on Unix-like systems starting with `.` that control the configuration of applications and shells on your system. You can store and manage your dotfiles in a repository on GitHub. For advice and tutorials about what to include in your dotfiles repository, see [GitHub does dotfiles](https://dotfiles.github.io/).
+
+Your dotfiles repository might include your shell aliases and preferences, any tools you want to install, or any other codespace personalization you want to make.
+
+You can configure GitHub Codespaces to use dotfiles from any repository you own by selecting that repository in your [personal GitHub Codespaces settings](https://github.com/settings/codespaces).
+
+When you create a new codespace, GitHub clones your selected dotfiles repository to the codespace environment, and looks for one of the following files to set up the environment.
+
+- *install.sh*
+- *install*
+- *bootstrap.sh*
+- *bootstrap*
+- *script/bootstrap*
+- *setup.sh*
+- *setup*
+- *script/setup*
+
+If none of these files are found, then any files or folders in your selected dotfiles repository starting with `.` are symlinked to the codespace's `~` or `$HOME` directory.
+
+Any changes to your selected dotfiles repository will apply only to each new codespace, and do not affect any existing codespace.
+
+**Note:** Currently, Codespaces does not support personalizing the User-scoped settings for VS Code with your `dotfiles` repository. You can set default Workspace and Remote [Codespaces] settings for a specific project in the project's repository. For more information, see "[Introduction to dev containers](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers#creating-a-custom-dev-container-configuration)."
+
+In addition, you can also configure Codespaces secrets on your personal profile page at [github.com/settings/codespaces](https://github.com/settings/codespaces). Development environment secrets are environment variables that are encrypted, and they are accessible to any codespace you create using repositories that have access to these secrets.
+
+### Notes
+
+The container comes with VS Code Insiders installed. To run it from an Integrated Terminal use `VSCODE_IPC_HOOK_CLI= /usr/bin/code-insiders .`.
+
+[def]: https://www.realvnc.com/en/connect/download/viewer/
\ No newline at end of file
diff --git a/.devcontainer /devcontainer.json b/.devcontainer /devcontainer.json
new file mode 100644
index 000000000..d8b13d3a4
--- /dev/null
+++ b/.devcontainer /devcontainer.json
@@ -0,0 +1,83 @@
+{
+ // Reference Doc: https://code.visualstudio.com/remote/advancedcontainers/overview
+ "name": "OpenIM Dev Environment",
+ // Update the container version when you publish dev-container
+ "dockerComposeFile": "docker-compose.yml",
+ "build": { "dockerfile": "Dockerfile" },
+ // Replace with uncommented line below to build your own local copy of the image
+ // "dockerFile": "../docker/Dockerfile-dev",
+ "containerEnv": {
+ // Uncomment to overwrite devcontainer .kube/config and .minikube certs with the localhost versions
+ // each time the devcontainer starts, if the respective .kube-localhost/config and .minikube-localhost
+ // folders respectively are bind mounted to the devcontainer.
+ // "SYNC_LOCALHOST_KUBECONFIG": "true"
+
+ // Uncomment to disable docker-in-docker and automatically proxy default /var/run/docker.sock to
+ // the localhost bind-mount /var/run/docker-host.sock.
+ // "BIND_LOCALHOST_DOCKER": "true"
+ },
+ "remoteEnv": {
+ "GO111MODULE": "on",
+ "GOPROXY": "https://goproxy.cn",
+ "GOSUMDB": "sum.golang.org",
+ "GONOPROXY": "github.com/openimsdk",
+ "GONOSUMDB": "github.com/openimsdk",
+ "GOPRIVATE": "github.com/openimsdk"
+ },
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ "davidanson.vscode-markdownlint",
+ "golang.go",
+ "ms-azuretools.vscode-dapr",
+ "ms-azuretools.vscode-docker",
+ "ms-kubernetes-tools.vscode-kubernetes-tools"
+ ],
+ "settings": {
+ "go.toolsManagement.checkForUpdates": "local",
+ "go.useLanguageServer": true,
+ "go.gopath": "/go"
+ }
+ }
+ },
+ "mounts": [
+ // Mount docker-in-docker library volume
+ "type=volume,source=dind-var-lib-docker,target=/var/lib/docker",
+
+ // Bind mount docker socket under an alias to support docker-from-docker
+ "type=bind,source=/var/run/docker.sock,target=/var/run/docker-host.sock",
+
+ // Bind mount docker socket under an alias to support docker-from-docker
+ // "type=bind,source=${env:HOME}${env:USERPROFILE}/.minikube/cache,target=/home/openim/.minikube/cache",
+
+ // Uncomment to clone local .kube/config into devcontainer
+ "type=bind,source=${env:HOME}${env:USERPROFILE}/.kube,target=/home/openim/.kube-localhost"
+
+ // Uncomment to additionally clone minikube certs into devcontainer for use with .kube/config
+ // "type=bind,source=${env:HOME}${env:USERPROFILE}/.minikube,target=/home/openim/.minikube-localhost"
+ ],
+ // Always run image-defined default command
+ "overrideCommand": false,
+ // On Linux, this will prevent new files getting created as root, but you
+ // may need to update the USER_UID and USER_GID in docker/Dockerfile-dev
+ // to match your user if not 1000.
+ // "remoteUser": "openimsdk",
+ "runArgs": [
+ // Enable ptrace-based debugging for go
+ "--cap-add=SYS_PTRACE",
+ "--security-opt",
+ "seccomp=unconfined",
+
+ // Uncomment to bind to host network for local devcontainer; this is necessary if using the
+ // bind-mounted /var/run/docker-host.sock directly.
+ "--net=host",
+
+ // Enable docker-in-docker configuration. Comment out if not using for better security.
+ "--privileged",
+
+ // Run the entrypoint defined in container image.
+ "--init"
+ ],
+ "workspaceFolder": "/workspaces/openim",
+ "workspaceMount": "type=bind,source=${localWorkspaceFolder},target=/workspaces/openim"
+}
diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml
index 6d8112eb4..21bb4986e 100644
--- a/.github/workflows/e2e-test.yml
+++ b/.github/workflows/e2e-test.yml
@@ -92,29 +92,30 @@ jobs:
- name: Exec OpenIM API test
run: |
- touch /tmp/test.md
- echo "# OpenIM Test" >> /tmp/test.md
- echo "## OpenIM API Test" >> /tmp/test.md
- echo "Command Output for OpenIM API Test
" >> /tmp/test.md
- echo "" >> /tmp/test.md
- sudo make test-api | tee -a /tmp/test.md
- echo "
" >> /tmp/test.md
- echo " " >> /tmp/test.md
+ mkdir -p ./tmp
+ touch ./tmp/test.md
+ echo "# OpenIM Test" >> ./tmp/test.md
+ echo "## OpenIM API Test" >> ./tmp/test.md
+ echo "Command Output for OpenIM API Test
" >> ./tmp/test.md
+ echo "" >> ./tmp/test.md
+ sudo make test-api | tee -a ./tmp/test.md
+ echo "
" >> ./tmp/test.md
+ echo " " >> ./tmp/test.md
- name: Exec OpenIM E2E Test
run: |
- echo "" >> /tmp/test.md
- echo "## OpenIM E2E Test" >> /tmp/test.md
- echo "Command Output for OpenIM E2E Test
" >> /tmp/test.md
- echo "" >> /tmp/test.md
- sudo make test-e2e | tee -a /tmp/test.md
- echo "
" >> /tmp/test.md
- echo " " >> /tmp/test.md
+ echo "" >> ./tmp/test.md
+ echo "## OpenIM E2E Test" >> ./tmp/test.md
+ echo "Command Output for OpenIM E2E Test
" >> ./tmp/test.md
+ echo "" >> ./tmp/test.md
+ sudo make test-e2e | tee -a ./tmp/test.md
+ echo "
" >> ./tmp/test.md
+ echo " " >> ./tmp/test.md
- name: Comment PR with file
uses: thollander/actions-comment-pull-request@v2
with:
- filePath: /tmp/test.md
+ filePath: ./tmp/test.md
comment_tag: nrt_file
reactions: eyes, rocket
mode: recreate
diff --git a/.github/workflows/openimci.yml b/.github/workflows/openimci.yml
index 00339110c..dce5649df 100644
--- a/.github/workflows/openimci.yml
+++ b/.github/workflows/openimci.yml
@@ -18,6 +18,7 @@ on:
push:
branches:
- main
+ - release-*
paths-ignore:
- "docs/**"
- "README.md"
@@ -26,6 +27,7 @@ on:
pull_request:
branches:
- main
+ - release-*
paths-ignore:
- "README.md"
- "README_zh-CN.md"
@@ -81,6 +83,11 @@ jobs:
- name: Build Source
run: sudo make build
+ - name: Build multiarch PLATFORMS
+ if: startsWith(github.ref, 'refs/heads/release-')
+ run: |
+ sudo make multiarch
+
- name: Cleanup Build
run: sudo make clean
@@ -107,7 +114,7 @@ jobs:
continue-on-error: true
openim-start:
- name: Test OpenIM install/start on ${{ matrix.os }}
+ name: Test OpenIM install/start on ${{ matrix.os }}-${{ matrix.arch }}
runs-on: ${{ matrix.os }}
permissions:
contents: write
@@ -136,6 +143,7 @@ jobs:
# sudo docker ps
- name: Check the OpenIM environment and status
+ if: runner.os == 'Linux' && matrix.arch == 'amd64'
id: docker_info
run: |
sleep 30
@@ -148,24 +156,29 @@ jobs:
- name: Comment PR
uses: thollander/actions-comment-pull-request@v2
+ if: runner.os == 'Linux' && matrix.arch == 'amd64'
with:
message: |
> [!TIP]
> Run make install to check the status
### Docker Images:
- ```
+ Click to expand docker images
+ ```bash
${{ env.images }}
```
+
+
### Docker Processes:
- ```
+ Click to expand docker ps
+ ```bash
${{ env.containers }}
```
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- continue-on-error: true
+
+ GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
execute-scripts:
- name: Execute OpenIM Script On ${{ matrix.os }}
+ name: Execute OpenIM Script On ${{ matrix.os }}-${{ matrix.arch }}
runs-on: ${{ matrix.os }}
permissions:
contents: write
@@ -174,8 +187,9 @@ jobs:
name: openim
strategy:
matrix:
- go_version: ["1.20"]
+ go_version: ["1.21"]
os: ["ubuntu-latest", "macos-latest"]
+ arch: [arm64, armv7, amd64]
steps:
- name: Checkout code
uses: actions/checkout@v4
@@ -193,7 +207,7 @@ jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }}
# - name: Install latest Bash (macOS only)
- # if: runner.os == 'macOS'
+ # if: runner.os == 'macOS' && matrix.arch == 'arm64'
# run: |
# /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# brew update
@@ -213,7 +227,7 @@ jobs:
sudo sleep 20
# - name: Set up Docker for macOS
- # if: runner.os == 'macOS'
+ # if: runner.os == 'macOS' && matrix.arch == 'arm64'
# run: |
# brew install --cask docker
# open /Applications/Docker.app
@@ -244,13 +258,13 @@ jobs:
sudo make check
- name: Restart Services and Print Logs for Ubuntu
- if: runner.os == 'Linux'
+ if: runner.os == 'Linux' && matrix.arch == 'amd64'
run: |
sudo make restart
sudo make check
- name: Build, Start, Check Services and Print Logs for macOS
- if: runner.os == 'macOS'
+ if: runner.os == 'macOS' && matrix.arch == 'arm64'
run: |
make build
diff --git a/CHANGELOG/CHANGELOG-3.4.md b/CHANGELOG/CHANGELOG-3.4.md
new file mode 100644
index 000000000..db4dd59c5
--- /dev/null
+++ b/CHANGELOG/CHANGELOG-3.4.md
@@ -0,0 +1,32 @@
+# Version logging for OpenIM
+
+
+
+
+
+
+## [Unreleased]
+
+
+
+## [v3.4.2] - 2023-12-14
+
+
+## [v3.4.0] - 2023-11-10
+
+
+## [v3.4.0-rc.1] - 2023-11-09
+
+
+## v3.4.0-rc.0 - 2023-11-09
+### Reverts
+- update etcd to v3.5.2 ([#206](https://github.com/openimsdk/open-im-server/issues/206))
+
+### Pull Requests
+- Merge branch 'tuoyun'
+
+
+[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v3.4.2...HEAD
+[v3.4.2]: https://github.com/openimsdk/open-im-server/compare/v3.4.0...v3.4.2
+[v3.4.0]: https://github.com/openimsdk/open-im-server/compare/v3.4.0-rc.1...v3.4.0
+[v3.4.0-rc.1]: https://github.com/openimsdk/open-im-server/compare/v3.4.0-rc.0...v3.4.0-rc.1
diff --git a/CHANGELOG/CHANGELOG-3.5.0.md b/CHANGELOG/CHANGELOG-3.5.0.md
new file mode 100644
index 000000000..02c28308d
--- /dev/null
+++ b/CHANGELOG/CHANGELOG-3.5.0.md
@@ -0,0 +1,15 @@
+# Version logging for OpenIM
+
+
+
+
+
+
+## [Unreleased]
+
+
+
+## [v3.5.0+3.97baaac] - 2024-01-12
+
+[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v3.5.0+3.97baaac...HEAD
+[v3.5.0+3.97baaac]: https://github.com/openimsdk/open-im-server/compare/v3.5.0+5.950e970...v3.5.0+3.97baaac
diff --git a/CHANGELOG/CHANGELOG-3.5.md b/CHANGELOG/CHANGELOG-3.5.md
new file mode 100644
index 000000000..ed9ba77c6
--- /dev/null
+++ b/CHANGELOG/CHANGELOG-3.5.md
@@ -0,0 +1,76 @@
+# Version logging for OpenIM
+
+
+
+
+
+
+## [Unreleased]
+
+
+
+## [v3.5.1-alpha.1] - 2024-01-09
+
+
+## [v3.5.0] - 2024-01-02
+
+
+## [v3.5.1] - 2024-01-02
+
+
+## [v3.5.1-bate.1] - 2024-01-02
+
+
+## [v3.5.1-rc.0] - 2023-12-30
+
+
+## [v3.5.0-rc.8] - 2023-12-28
+
+
+## [v3.5.0-rc.7] - 2023-12-18
+
+
+## [v3.5.0-rc.6] - 2023-12-15
+
+
+## [v3.5.0-rc.5] - 2023-12-15
+
+
+## [v3.5.0-rc.4] - 2023-12-14
+
+
+## [v3.5.0-rc.3] - 2023-12-14
+
+
+## [v3.5.0-rc.2] - 2023-12-14
+
+
+## [v3.5.0-rc.1] - 2023-12-14
+
+
+## [v3.5.0-rc.0] - 2023-12-14
+
+
+## v3.5.0-beta.1 - 2023-11-29
+### Reverts
+- update etcd to v3.5.2 ([#206](https://github.com/openimsdk/open-im-server/issues/206))
+
+### Pull Requests
+- Merge branch 'tuoyun'
+
+
+[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-alpha.1...HEAD
+[v3.5.1-alpha.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.0...v3.5.1-alpha.1
+[v3.5.0]: https://github.com/openimsdk/open-im-server/compare/v3.5.1...v3.5.0
+[v3.5.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-bate.1...v3.5.1
+[v3.5.1-bate.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-rc.0...v3.5.1-bate.1
+[v3.5.1-rc.0]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.8...v3.5.1-rc.0
+[v3.5.0-rc.8]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.7...v3.5.0-rc.8
+[v3.5.0-rc.7]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.6...v3.5.0-rc.7
+[v3.5.0-rc.6]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.5...v3.5.0-rc.6
+[v3.5.0-rc.5]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.4...v3.5.0-rc.5
+[v3.5.0-rc.4]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.3...v3.5.0-rc.4
+[v3.5.0-rc.3]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.2...v3.5.0-rc.3
+[v3.5.0-rc.2]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.1...v3.5.0-rc.2
+[v3.5.0-rc.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.0...v3.5.0-rc.1
+[v3.5.0-rc.0]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-beta.1...v3.5.0-rc.0
diff --git a/README.md b/README.md
index 025672a0b..551ff27f8 100644
--- a/README.md
+++ b/README.md
@@ -76,7 +76,7 @@ It is built using Golang and supports cross-platform deployment, ensuring a cons
+ **[Docker Deployment Guide](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
+ **[Kubernetes Deployment Guide](https://docs.openim.io/guides/gettingStarted/k8s-deployment)**
-## :hammer_and_wrench: To start developing OpenIM
+## :hammer_and_wrench: To Start Developing OpenIM
[](https://vscode.dev/github/openimsdk/open-im-server)
@@ -114,6 +114,8 @@ Before you start, please make sure your changes are in demand. The best for that
- [OpenIM Script Utilities](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/util-scripts.md)
- [OpenIM Versioning](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/version.md)
- [Manage backend and monitor deployment](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/prometheus-grafana.md)
+- [Mac Developer Deployment Guide for OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/mac-developer-deployment-guide.md)
+
## :busts_in_silhouette: Community
@@ -130,7 +132,7 @@ Our conference is in the [OpenIM Slack](https://join.slack.com/t/openimsdk/share
We take notes of each [biweekly meeting](https://github.com/orgs/OpenIMSDK/discussions/categories/meeting) in [GitHub discussions](https://github.com/openimsdk/open-im-server/discussions/categories/meeting), Our historical meeting notes, as well as replays of the meetings are available at [Google Docs :bookmark_tabs:](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing).
-## :eyes: Who are using OpenIM
+## :eyes: Who Are Using OpenIM
Check out our [user case studies](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) page for a list of the project users. Don't hesitate to leave a [📝comment](https://github.com/openimsdk/open-im-server/issues/379) and share your use case.
diff --git a/assets/README.md b/assets/README.md
index d3e735dc0..152e5850c 100644
--- a/assets/README.md
+++ b/assets/README.md
@@ -25,7 +25,7 @@ assets/
## Copyright Notice:
-The OpenIM logo, including its variations and animated versions, displayed in this repository [OpenIM](https://github.com/OpenIMSDK/openim) under the `/assets/logo` and `/assets/logo-gif` directories, are protected by copyright laws.
+The OpenIM logo, including its variations and animated versions, displayed in this repository [OpenIM](https://github.com/openimsdk/open-im-server) under the `/assets/logo` and `/assets/logo-gif` directories, are protected by copyright laws.
The logo design is credited to @Xx(席欣).
diff --git a/cmd/openim-api/main.go b/cmd/openim-api/main.go
index cb9b09802..f0b62e31f 100644
--- a/cmd/openim-api/main.go
+++ b/cmd/openim-api/main.go
@@ -35,7 +35,7 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
- ginProm "github.com/openimsdk/open-im-server/v3/pkg/common/ginprometheus"
+ ginprom "github.com/openimsdk/open-im-server/v3/pkg/common/ginprometheus"
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
)
@@ -88,7 +88,7 @@ func run(port int, proPort int) error {
log.ZInfo(context.Background(), "api register public config to discov success")
router := api.NewGinRouter(client, rdb)
if config.Config.Prometheus.Enable {
- p := ginProm.NewPrometheus("app", prommetrics.GetGinCusMetrics("Api"))
+ p := ginprom.NewPrometheus("app", prommetrics.GetGinCusMetrics("Api"))
p.SetListenAddress(fmt.Sprintf(":%d", proPort))
p.Use(router)
}
diff --git a/docker-compose.yml b/docker-compose.yml
index defc910c4..de4b30d48 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -124,10 +124,52 @@ services:
server:
ipv4_address: ${OPENIM_WEB_NETWORK_ADDRESS:-172.28.0.7}
+### TODO: Uncomment, or deploy using openim docker: https://github.com/openimsdk/openim-docker
# Uncomment and configure the following services as needed
+
+ # openim-chat:
+ # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-chat:${CHAT_IMAGE_VERSION:-latest}
+ # container_name: openim-chat
+ # healthcheck:
+ # test: ["CMD", "/openim/openim-chat/scripts/check_all.sh"]
+ # interval: 60s
+ # timeout: 30s
+ # retries: 5
+ # env_file:
+ # - .env
+ # environment:
+ # - ZOOKEEPER_ADDRESS=${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}
+ # - ZOOKEEPER_PORT=${ZOOKEEPER_PORT:-12181}
+ # - OPENIM_SERVER_ADDRESS=http://${OPENIM_SERVER_ADDRESS:-172.28.0.1}
+ # - API_OPENIM_PORT=${API_OPENIM_PORT:-10002}
+ # - MYSQL_ADDRESS=${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}
+ # - MYSQL_PORT=${MYSQL_PORT:-13306}
+ # - REDIS_ADDRESS=${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}
+ # - REDIS_PORT=${REDIS_PORT:-16379}
+ # ports:
+ # - "${OPENIM_CHAT_API_PORT:-10008}:10008"
+ # - "${OPENIM_ADMIN_API_PORT:-10009}:10009"
+ # volumes:
+ # - "${DATA_DIR:-./}/components/openim-chat/logs:/openim/openim-chat/logs"
+ # - "${DATA_DIR:-./}/components/openim-chat/config:/openim/openim-chat/config"
+ # restart: always
+ # # user: root:root
+ # depends_on:
+ # openim-server:
+ # condition: service_healthy
+ # logging:
+ # driver: json-file
+ # options:
+ # max-size: "1g"
+ # max-file: "2"
+ # networks:
+ # server:
+ # ipv4_address: ${OPENIM_CHAT_NETWORK_ADDRESS:-172.28.0.9}
+
# openim-admin:
- # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-admin-front:v3.4.0
- # container_name: openim-admin
+ # # https://github.com/openimsdk/open-im-server/issues/1662
+ # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-admin:${ADMIN_FRONT_VERSION:-toc-base-open-docker.35}
+ # container_name: openim-admin
# restart: always
# ports:
# - "${OPENIM_ADMIN_FRONT_PORT:-11002}:80"
@@ -141,8 +183,8 @@ services:
# hostname: prometheus
# restart: always
# volumes:
- # - ./config/prometheus.yml:/etc/prometheus/prometheus.yml
- # - ./config/instance-down-rules.yml:/etc/prometheus/instance-down-rules.yml
+ # - "${DATA_DIR:-./}/config/instance-down-rules.yml:/etc/prometheus/instance-down-rules.yml"
+ # - "${DATA_DIR:-./}/config/prometheus.yml:/etc/prometheus/prometheus.yml"
# ports:
# - "${PROMETHEUS_PORT:-19090}:9090"
# networks:
@@ -155,8 +197,8 @@ services:
# hostname: alertmanager
# restart: always
# volumes:
- # - ./config/alertmanager.yml:/etc/alertmanager/alertmanager.yml
- # - ./config/email.tmpl:/etc/alertmanager/email.tmpl
+ # - ${DATA_DIR:-./}/config/alertmanager.yml:/etc/alertmanager/alertmanager.yml
+ # - ${DATA_DIR:-./}/config/email.tmpl:/etc/alertmanager/email.tmpl
# ports:
# - "${ALERT_MANAGER_PORT:-19093}:9093"
# networks:
@@ -172,7 +214,7 @@ services:
# ports:
# - "${GRAFANA_PORT:-13000}:3000"
# volumes:
- # - ${DATA_DIR:-./}/components/grafana:/var/lib/grafana
+ # - "${DATA_DIR:-./}/components/grafana:/var/lib/grafana"
# networks:
# server:
# ipv4_address: ${GRAFANA_NETWORK_ADDRESS:-172.28.0.11}
diff --git a/docs/contrib/environment.md b/docs/contrib/environment.md
index 7425c8022..7d672eda5 100644
--- a/docs/contrib/environment.md
+++ b/docs/contrib/environment.md
@@ -108,7 +108,7 @@ export CHAT_IMAGE_VERSION="main"
export SERVER_IMAGE_VERSION="main"
```
-These variables are stored within the [`environment.sh`](https://github.com/OpenIMSDK/openim-docker/blob/main/scripts/install/environment.sh) configuration:
+These variables are stored within the [`environment.sh`](https://github.com/OpenIMSDK/open-im-server/blob/main/scripts/install/environment.sh) configuration:
```bash
readonly CHAT_IMAGE_VERSION=${CHAT_IMAGE_VERSION:-'main'}
@@ -448,7 +448,7 @@ This section involves configuring the log settings, including storage location,
| Parameter | Example Value | Description |
| ------------------------- | ------------------------ | --------------------------------- |
-| LOG_STORAGE_LOCATION | ""${OPENIM_ROOT}"/logs/" | Location for storing logs |
+| LOG_STORAGE_LOCATION | "${OPENIM_ROOT}/logs/" | Location for storing logs |
| LOG_ROTATION_TIME | "24" | Log rotation time (in hours) |
| LOG_REMAIN_ROTATION_COUNT | "2" | Number of log rotations to retain |
| LOG_REMAIN_LOG_LEVEL | "6" | Log level to retain |
diff --git a/docs/contrib/gitcherry-pick.md b/docs/contrib/gitcherry-pick.md
index 010685d65..2e901385f 100644
--- a/docs/contrib/gitcherry-pick.md
+++ b/docs/contrib/gitcherry-pick.md
@@ -75,7 +75,7 @@ It is critical that our full community is actively engaged on enhancements in th
- Be aware the cherry pick script assumes you have a git remote called `upstream` that points at the openim-server github org.
- Please see our [recommended Git workflow](https://github.com/openimsdk/open-im-server/blob/main/docs/contributors/github-workflow.md#workflow).
+ Please see our [recommended Git workflow](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/github-workflow.md#workflow).
- You will need to run the cherry pick script separately for each patch release you want to cherry pick to. Cherry picks should be applied to all [active](https://github.com/openimsdk/open-im-server/releases) release branches where the fix is applicable.
diff --git a/docs/contrib/github-workflow.md b/docs/contrib/github-workflow.md
index 0afbae144..50f2e0bb2 100644
--- a/docs/contrib/github-workflow.md
+++ b/docs/contrib/github-workflow.md
@@ -8,7 +8,6 @@ description: |
commit hygiene.
---
-
## 1. Fork in the cloud
@@ -28,10 +27,10 @@ neither `$GOPATH/src/github.com/${your github profile name}/`
nor any other pattern will work.
```sh
-export working_dir="$(go env GOPATH)/src/k8s.io"
+export working_dir="$(go env GOPATH)/src/github.com/openimsdk"
```
-If you already do Go development on github, the `k8s.io` directory
+If you already do Go development on github, the `github.com/openimsdk` directory
will be a sibling to your existing `github.com` directory.
Set `user` to match your github profile name:
diff --git a/docs/contrib/init-config.md b/docs/contrib/init-config.md
index 9ef4759a4..5e3139dea 100644
--- a/docs/contrib/init-config.md
+++ b/docs/contrib/init-config.md
@@ -23,8 +23,8 @@ In the `scripts/init_config.sh` file, we defined some template files. These temp
```
# Defines an associative array where the keys are the template files and the values are the corresponding output files.
declare -A TEMPLATES=(
- [""${OPENIM_ROOT}"/scripts/template/config-tmpl/env.template"]="${OPENIM_OUTPUT_SUBPATH}/bin/.env"
- [""${OPENIM_ROOT}"/scripts/template/config-tmpl/config.yaml"]="${OPENIM_OUTPUT_SUBPATH}/bin/config.yaml"
+ ["${OPENIM_ROOT}/scripts/template/config-tmpl/env.template"]="${OPENIM_OUTPUT_SUBPATH}/bin/.env"
+ ["${OPENIM_ROOT}/scripts/template/config-tmpl/config.yaml"]="${OPENIM_OUTPUT_SUBPATH}/bin/config.yaml"
)
```
diff --git a/docs/contrib/mac-developer-deployment-guide.md b/docs/contrib/mac-developer-deployment-guide.md
new file mode 100644
index 000000000..40ef4b8be
--- /dev/null
+++ b/docs/contrib/mac-developer-deployment-guide.md
@@ -0,0 +1,149 @@
+# Mac Developer Deployment Guide for OpenIM
+
+## Introduction
+
+This guide aims to assist Mac-based developers in contributing effectively to OpenIM. It covers the setup of a development environment tailored for Mac, including the use of GitHub for development workflow and `devcontainer` for a consistent development experience.
+
+Before contributing to OpenIM through issues and pull requests, make sure you are familiar with GitHub and the [pull request workflow](https://docs.github.com/en/get-started/quickstart/github-flow).
+
+## Prerequisites
+
+### System Requirements
+
+- macOS (latest stable version recommended)
+- Internet connection
+- Administrator access
+
+### Knowledge Requirements
+
+- Basic understanding of Git and GitHub
+- Familiarity with Docker and containerization
+- Experience with Go programming language
+
+## Setting up the Development Environment
+
+### Installing Homebrew
+
+Homebrew is an essential package manager for macOS. Install it using:
+
+```sh
+/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+```
+
+### Installing and Configuring Git
+
+1. Install Git:
+
+ ```sh
+ brew install git
+ ```
+
+2. Configure Git with your user details:
+
+ ```sh
+ git config --global user.name "Your Name"
+ git config --global user.email "your.email@example.com"
+ ```
+
+### Forking and Cloning the Repository
+
+1. Fork the OpenIM repository on GitHub to your account.
+2. Clone your fork to your local machine:
+
+ ```sh
+ git clone https://github.com//open-im-server.git
+ # The Docker bridging network mode for Mac is slightly different and needs to be set:
+ export DOCKER_BRIDGE_SUBNET=127.0.0.0/16
+ # Set OpenIM IP
+ export OPENIM_IP=
+ # Init Config
+ make init
+
+ # Start Components
+ docker compose up -d
+
+ # Start OpenIM Server
+ make start
+ ```
+
+### Setting Up the Devcontainer
+
+`Devcontainers` provide a Docker-based isolated development environment.
+
+Read [README.md](https://github.com/openimsdk/open-im-server/tree/main/.devcontainer) in the `.devcontainer` directory of the project to learn more about the devcontainer.
+
+To set it up:
+
+1. Install Docker Desktop for Mac from [Docker Hub](https://docs.docker.com/desktop/install/mac-install/).
+2. Install Visual Studio Code and the Remote - Containers extension.
+3. Open the cloned OpenIM repository in VS Code.
+4. VS Code will prompt to reopen the project in a container. Accept this to set up the environment automatically.
+
+### Installing Go and Dependencies
+
+Use Homebrew to install Go:
+
+```sh
+brew install go
+```
+
+Ensure the version of Go is compatible with the version required by OpenIM (refer to the main documentation for version requirements).
+
+### Additional Tools
+
+Install other required tools like Docker, Vagrant, and necessary GNU utils as described in the main documentation.
+
+## GitHub Development Workflow
+
+### Creating a New Branch
+
+For new features or fixes, create a new branch:
+
+```sh
+git checkout -b feat/your-feature-name
+```
+
+### Making Changes and Committing
+
+1. Make your changes in the code.
+2. Stage your changes:
+
+ ```sh
+ git add .
+ ```
+
+3. Commit with a meaningful message:
+
+ ```sh
+ git commit -m "Add a brief description of your changes"
+ ```
+
+### Pushing Changes and Creating Pull Requests
+
+1. Push your branch to GitHub:
+
+ ```sh
+ git push origin feat/your-feature-name
+ ```
+
+2. Go to your fork on GitHub and create a pull request to the main OpenIM repository.
+
+### Keeping Your Fork Updated
+
+Regularly sync your fork with the main repository:
+
+```sh
+git fetch upstream
+git checkout main
+git rebase upstream/main
+```
+
+More read: [https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md](https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md)
+
+## Testing and Quality Assurance
+
+Run tests as described in the OpenIM documentation to ensure your changes do not break existing functionality.
+
+## Conclusion
+
+This guide provides a comprehensive overview for Mac developers to set up and contribute to OpenIM. By following these steps, you can ensure a smooth and efficient development experience. Happy coding!
\ No newline at end of file
diff --git a/docs/contrib/offline-deployment.md b/docs/contrib/offline-deployment.md
index 39fc3598e..a96f82d4a 100644
--- a/docs/contrib/offline-deployment.md
+++ b/docs/contrib/offline-deployment.md
@@ -6,25 +6,57 @@
Below are the base images and their versions you'll need:
-- wurstmeister/kafka
-- redis:7.0.0
-- mongo:6.0.2
-- mysql:5.7
-- wurstmeister/zookeeper
-- minio/minio
+- [ ] bitnami/kafka:3.5.1
+- [ ] redis:7.0.0
+- [ ] mongo:6.0.2
+- [ ] bitnami/zookeeper:3.8
+- [ ] minio/minio:latest
+
+> [!IMPORTANT]
+> It is important to note that OpenIM removed mysql components from versions v3.5.0 (release-v3.5) and above, so mysql can be deployed without this requirement or above
+
+**If you need to install more IM components or monitoring products:**
+
+OpenIM:
+
+> [!TIP]
+> If you need to install more IM components or monitoring products [images.md](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/images.md)
+
+- [ ] ghcr.io/openimsdk/openim-web:latest
+- [ ] ghcr.io/openimsdk/openim-admin:latest
+- [ ] ghcr.io/openimsdk/openim-chat:latest
+- [ ] ghcr.io/openimsdk/openim-server:latest
+
+
+Monitoring:
+
+- [ ] prom/prometheus:v2.48.1
+- [ ] prom/alertmanager:v0.23.0
+- [ ] grafana/grafana:10.2.2
+- [ ] bitnami/node-exporter:1.7.0
+
Use the following commands to pull these base images:
-```
-docker pull wurstmeister/kafka
+```bash
+docker pull bitnami/kafka:3.5.1
docker pull redis:7.0.0
docker pull mongo:6.0.2
docker pull mysql:5.7
-docker pull wurstmeister/zookeeper
-docker pull minio/minio
+docker pull bitnami/zookeeper:3.8
+docker pull minio/minio:latest
```
-## 2. OpenIM & Chat Images
+If you need to install more IM components or monitoring products:
+
+```bash
+docker pull prom/prometheus:v2.48.1
+docker pull prom/alertmanager:v0.23.0
+docker pull grafana/grafana:10.2.2
+docker pull bitnami/node-exporter:1.7.0
+```
+
+## 2. OpenIM Images
**For detailed understanding of version management and storage of OpenIM and Chat**: [version.md](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/version.md)
@@ -42,9 +74,26 @@ docker pull ghcr.io/openimsdk/openim-server:
- Execute the following command to pull the image:
```bash
-docker pull ghcr.io/openimsdk/openim-server:
+docker pull ghcr.io/openimsdk/openim-chat:
+```
+
+### Web Image
+
+- Execute the following command to pull the image:
+
+```bash
+docker pull ghcr.io/openimsdk/openim-web:
```
+### Admin Image
+
+- Execute the following command to pull the image:
+
+```bash
+docker pull ghcr.io/openimsdk/openim-admin:
+```
+
+
## 3. Image Storage Selection
**Repositories**:
@@ -71,46 +120,61 @@ You can select from the following versions:
1. **Pull images**: Execute the above `docker pull` commands to pull all required images locally.
2. **Save images**:
-```
+```bash
docker save -o .tar
```
-1. **Fetch code**: Clone the repository:
+If you want to save all the images, use the following command:
+```bash
+docker save -o .tar $(docker images -q)
```
-git clone https://github.com/OpenIMSDK/openim-docker.git
+
+3. **Fetch code**: Clone the repository:
+
+```bash
+git clone https://github.com/openimsdk/openim-docker.git
```
-Or download the code from [Releases](https://github.com/OpenIMSDK/openim-docker/releases/).
+Or download the code from [Releases](https://github.com/openimsdk/openim-docker/releases/).
-1. **Transfer files**: Use `scp` to transfer all images and code to the intranet server.
+> Because of the difference between win and linux newlines, please do not clone the repository with win and then synchronize scp to linux.
-```
+4. **Transfer files**: Use `scp` to transfer all images and code to the intranet server.
+
+```bash
scp .tar user@remote-ip:/path/on/remote/server
```
Or choose other transfer methods such as a hard drive.
-1. **Import images**: On the intranet server:
+5. **Import images**: On the intranet server:
-```
+```bash
docker load -i .tar
```
-1. **Deploy**: Navigate to the `openim-docker` repository directory and follow the README guide for deployment.
-2. **Deploy using Docker-compose**:
+Import directly with shortcut commands:
+```bash
+for i in `ls ./`;do docker load -i $i;done
```
-docker-compose up -d
-# Verify
-docker-compose ps
+6. **Deploy**: Navigate to the `openim-docker` repository directory and follow the [README guide](https://github.com/openimsdk/openim-docker) for deployment.
+
+7. **Deploy using docker compose**:
+
+```bash
+export OPENIM_IP="your ip" # Set Ip
+make init # Init config
+docker compose up -d # Deployment
+docker compose ps # Verify
```
> **Note**: If you're using a version of Docker prior to 20, make sure you've installed `docker-compose`.
## 6. Reference Links
-- [OpenIMSDK Issue #432](https://github.com/openimsdk/open-im-server/issues/432)
+- [openimsdk Issue #432](https://github.com/openimsdk/open-im-server/issues/432)
- [Notion Link](https://nsddd.notion.site/435ee747c0bc44048da9300a2d745ad3?pvs=25)
-- [OpenIMSDK Issue #474](https://github.com/openimsdk/open-im-server/issues/474)
\ No newline at end of file
+- [openimsdk Issue #474](https://github.com/openimsdk/open-im-server/issues/474)
\ No newline at end of file
diff --git a/docs/contrib/prometheus-grafana.md b/docs/contrib/prometheus-grafana.md
index a59847f71..5b57c5942 100644
--- a/docs/contrib/prometheus-grafana.md
+++ b/docs/contrib/prometheus-grafana.md
@@ -111,32 +111,35 @@ Importing Grafana Dashboards is a straightforward process and is applicable to O
To monitor OpenIM in Grafana, you need to focus on three categories of key metrics, each with its specific deployment and configuration steps:
-1. **OpenIM Metrics (`prometheus-dashboard.yaml`)**:
- + **Configuration File Path**: Located at `config/prometheus-dashboard.yaml`.
- + **Enabling Monitoring**: Set the environment variable `export PROMETHEUS_ENABLE=true` to enable Prometheus monitoring.
- + **More Information**: Refer to the [OpenIM Configuration Guide](https://docs.openim.io/configurations/prometheus-integration).
-2. **Node Exporter**:
- + **Container Deployment**: Deploy the `quay.io/prometheus/node-exporter` container for node monitoring.
- + **Get Dashboard**: Access the [Node Exporter Full Feature Dashboard](https://grafana.com/grafana/dashboards/1860-node-exporter-full/) and import it using YAML file download or ID import.
- + **Deployment Guide**: Refer to the [Node Exporter Deployment Documentation](https://prometheus.io/docs/guides/node-exporter/).
-3. **Middleware Metrics**: Each middleware requires specific steps and configurations to enable monitoring. Here is a list of common middleware and links to their respective setup guides:
- + MySQL:
- + **Configuration**: Ensure MySQL has performance monitoring enabled.
- + **Link**: Refer to the [MySQL Monitoring Configuration Guide](https://grafana.com/docs/grafana/latest/datasources/mysql/).
- + Redis:
- + **Configuration**: Configure Redis to allow monitoring data export.
- + **Link**: Refer to the [Redis Monitoring Guide](https://grafana.com/docs/grafana/latest/datasources/redis/).
- + MongoDB:
- + **Configuration**: Set up monitoring metrics for MongoDB.
- + **Link**: Refer to the [MongoDB Monitoring Guide](https://grafana.com/grafana/plugins/grafana-mongodb-datasource/).
- + Kafka:
- + **Configuration**: Integrate Kafka with Prometheus monitoring.
- + **Link**: Refer to the [Kafka Monitoring Guide](https://grafana.com/grafana/plugins/grafana-kafka-datasource/).
- + Zookeeper:
- + **Configuration**: Ensure Zookeeper can be monitored by Prometheus.
- + **Link**: Refer to the [Zookeeper Monitoring Configuration](https://grafana.com/docs/grafana/latest/datasources/zookeeper/).
-
-
+**OpenIM Metrics (`prometheus-dashboard.yaml`)**:
+
+- **Configuration File Path**: Find this at `config/prometheus-dashboard.yaml`.
+- **Enabling Monitoring**: Activate Prometheus monitoring by setting the environment variable: `export PROMETHEUS_ENABLE=true`.
+- **More Information**: For detailed instructions, see the [OpenIM Configuration Guide](https://docs.openim.io/configurations/prometheus-integration).
+
+**Node Exporter**:
+
+- **Container Deployment**: Use the container `quay.io/prometheus/node-exporter` for effective node monitoring.
+- **Access Dashboard**: Visit the [Node Exporter Full Feature Dashboard](https://grafana.com/grafana/dashboards/1860-node-exporter-full/) for dashboard integration either through YAML file download or ID.
+- **Deployment Guide**: For deployment steps, consult the [Node Exporter Deployment Documentation](https://prometheus.io/docs/guides/node-exporter/).
+
+**Middleware Metrics**: Different middlewares require unique steps and configurations for monitoring:
+
+- MySQL:
+ - **Configuration**: Make sure MySQL is set up for performance monitoring.
+ - **Guide**: See the [MySQL Monitoring Configuration Guide](https://grafana.com/docs/grafana/latest/datasources/mysql/).
+- Redis:
+ - **Configuration**: Adjust Redis settings to enable monitoring data export.
+ - **Guide**: Consult the [Redis Monitoring Guide](https://grafana.com/docs/grafana/latest/datasources/redis/).
+- MongoDB:
+ - **Configuration**: Configure MongoDB for monitoring metrics.
+ - **Guide**: Visit the [MongoDB Monitoring Guide](https://grafana.com/grafana/plugins/grafana-mongodb-datasource/).
+- Kafka:
+ - **Configuration**: Set up Kafka for Prometheus monitoring integration.
+ - **Guide**: Refer to the [Kafka Monitoring Guide](https://grafana.com/grafana/plugins/grafana-kafka-datasource/).
+- Zookeeper:
+ - **Configuration**: Ensure Prometheus can monitor Zookeeper.
+ - **Guide**: Check out the [Zookeeper Monitoring Configuration](https://grafana.com/docs/grafana/latest/datasources/zookeeper/).
**Importing Steps**:
diff --git a/docs/contrib/release.md b/docs/contrib/release.md
new file mode 100644
index 000000000..65756fe9a
--- /dev/null
+++ b/docs/contrib/release.md
@@ -0,0 +1,251 @@
+# OpenIM Release Automation Design Document
+
+This document outlines the automation process for releasing OpenIM. You can use the `make release` command for automated publishing. We will discuss how to use the `make release` command and Github Actions CICD separately, while also providing insight into the design principles involved.
+
+## Github Actions Automation
+
+In our CICD pipeline, we have implemented logic for automating the release process using the goreleaser tool. To achieve this, follow these steps on your local machine or server:
+
+```bash
+git clone https://github.com/openimsdk/open-im-server
+cd open-im-server
+git tag -a v3.6.0 -s -m "release: xxx"
+# For pre-release versions: git tag -a v3.6.0-rc.0 -s -m "pre-release: xxx"
+git push origin v3.6.0
+```
+
+The remaining tasks are handled by automated processes:
+
++ Automatically complete the release publication on Github
++ Automatically build the `v3.6.0` version image and push it to aliyun, dockerhub, and github
+
+Through these automated steps, we achieve rapid and efficient OpenIM version releases, simplifying the release process and enhancing productivity.
+
+
+Certainly, here is the continuation of the document in English:
+
+## Local Make Release Design
+
+There are two primary scenarios for local usage:
+
++ Advanced compilation and release, manually executed locally
++ Quick compilation verification and version release, manually executed locally
+
+**These two scenarios can also be combined, for example, by tagging locally and then releasing:**
+
+```bash
+git add .
+git commit -a -s -m "release(v3.6.0): ......"
+git tag v3.6.0
+git release
+git push origin main
+```
+
+In a local environment, you can use the `make release` command to complete the release process. The main implementation logic can be found in the `/data/workspaces/open-im-server/scripts/lib/release.sh` file. First, let's explore its usage through the help information.
+
+### Help Information
+
+To view the help information, execute the following command:
+
+```bash
+$ ./scripts/release.sh --help
+Usage: release.sh [options]
+Options:
+ -h, --help Display this help message
+ -se, --setup-env Execute environment setup
+ -vp, --verify-prereqs Execute prerequisite verification
+ -bc, --build-command Execute build command
+ -bi, --build-image Execute build image (default is not executed)
+ -pt, --package-tarballs Execute tarball packaging
+ -ut, --upload-tarballs Execute tarball upload
+ -gr, --github-release Execute GitHub release
+ -gc, --generate-changelog Execute changelog generation
+```
+
+### Default Behavior
+
+If no options are provided, all operations are executed by default:
+
+```bash
+# If no options are provided, enable all operations by default
+if [ "$#" -eq 0 ]; then
+ perform_setup_env=true
+ perform_verify_prereqs=true
+ perform_build_command=true
+ perform_package_tarballs=true
+ perform_upload_tarballs=true
+ perform_github_release=true
+ perform_generate_changelog=true
+ # TODO: Defaultly not enable build_image
+ # perform_build_image=true
+fi
+```
+
+### Environment Variable Setup
+
+Before starting, you need to set environment variables:
+
+```bash
+export TENCENT_SECRET_KEY=OZZ****************************
+export TENCENT_SECRET_ID=AKI****************************
+```
+
+### Modifying COS Account and Password
+
+If you need to change the COS account, password, and bucket information, please modify the following section in the `/data/workspaces/open-im-server/scripts/lib/release.sh` file:
+
+```bash
+readonly BUCKET="openim-1306374445"
+readonly REGION="ap-guangzhou"
+readonly COS_RELEASE_DIR="openim-release"
+```
+
+### GitHub Release Configuration
+
+If you intend to use the GitHub Release feature, you also need to set the environment variable:
+
+```bash
+export GITHUB_TOKEN="your_github_token"
+```
+
+### Modifying GitHub Release Basic Information
+
+If you need to modify the basic information of GitHub Release, please edit the following section in the `/data/workspaces/open-im-server/scripts/lib/release.sh` file:
+
+```bash
+# OpenIM GitHub account information
+readonly OPENIM_GITHUB_ORG=openimsdk
+readonly OPENIM_GITHUB_REPO=open-im-server
+```
+
+This setup allows you to configure and execute the local release process according to your specific needs.
+
+
+### GitHub Release Versioning Rules
+
+Firstly, it's important to note that GitHub Releases should primarily be for pre-release versions. However, goreleaser might provide a `prerelease: auto` option, which automatically marks versions with pre-release indicators like `-rc1`, `-beta`, etc., as pre-releases.
+
+So, if your most recent tag does not have pre-release indicators such as `-rc1` or `-beta`, even if you use `make release` for pre-release versions, goreleaser might still consider them as formal releases.
+
+To avoid this issue, I have added the `--draft` flag to github-release. This way, all releases are created as drafts.
+
+## CICD Release Documentation Design
+
+The release records still require manual composition for GitHub Release. This is different from github-release.
+
+This approach ensures that all releases are initially created as drafts, allowing you to manually review and edit the release documentation on GitHub. This manual step provides more control and allows you to curate release notes and other information before making them public.
+
+
+## Makefile Section
+
+This document aims to elaborate and explain key sections of the OpenIM Release automation design, including the Makefile section and functions within the code. Below, we will provide a detailed explanation of the logic and functions of each section.
+
+In the project's root directory, the Makefile imports a subdirectory:
+
+```makefile
+include scripts/make-rules/release.mk
+```
+
+And defines the `release` target as follows:
+
+```makefile
+## release: release the project ✨
+.PHONY: release release: release.verify release.ensure-tag
+ @scripts/release.sh
+```
+
+### Importing Subdirectory
+
+At the beginning of the Makefile, the `include scripts/make-rules/release.mk` statement imports the `release.mk` file from the subdirectory. This file contains rules and configurations related to releases to be used in subsequent operations.
+
+### The `release` Target
+
+The Makefile defines a target named `release`, which is used to execute the project's release operation. This target is marked as a phony target (`.PHONY`), meaning it doesn't represent an actual file or directory but serves as an identifier for executing a series of actions.
+
+In the `release` target, two dependency targets are executed first: `release.verify` and `release.ensure-tag`. Afterward, the `scripts/release.sh` script is called to perform the actual release operation.
+
+## Logic of `release.verify` and `release.ensure-tag`
+
+```makefile
+## release.verify: Check if a tool is installed and install it
+.PHONY: release.verify
+release.verify: tools.verify.git-chglog tools.verify.github-release tools.verify.coscmd tools.verify.coscli
+
+## release.ensure-tag: ensure tag
+.PHONY: release.ensure-tag
+release.ensure-tag: tools.verify.gsemver
+ @scripts/ensure-tag.sh
+```
+
+### `release.verify` Target
+
+The `release.verify` target is used to check and install tools. It depends on four sub-targets: `tools.verify.git-chglog`, `tools.verify.github-release`, `tools.verify.coscmd`, and `tools.verify.coscli`. These sub-targets aim to check if specific tools are installed and attempt to install them if they are not.
+
+The purpose of this target is to ensure that the necessary tools required for the release process are available so that subsequent operations can be executed smoothly.
+
+### `release.ensure-tag` Target
+
+The `release.ensure-tag` target is used to ensure that the project has a version tag. It depends on the sub-target `tools.verify.gsemver`, indicating that it should check if the `gsemver` tool is installed before executing.
+
+When the `release.ensure-tag` target is executed, it calls the `scripts/ensure-tag.sh` script to ensure that the project has a version tag. Version tags are typically used to identify specific versions of the project for management and release in version control systems.
+
+## Logic of `release.sh` Script
+
+```bash
+openim::golang::setup_env
+openim::build::verify_prereqs
+openim::release::verify_prereqs
+#openim::build::build_image
+openim::build::build_command
+openim::release::package_tarballs
+openim::release::upload_tarballs
+git push origin ${VERSION}
+#openim::release::github_release
+#openim::release::generate_changelog
+```
+
+The `release.sh` script is responsible for executing the actual release operations. Below is the logic of this script:
+
+1. `openim::golang::setup_env`: This function sets up some configurations for the Golang development environment.
+
+2. `openim::build::verify_prereqs`: This function is used to verify whether the prerequisites for building are met. This includes checking dependencies, environment variables, and more.
+
+3. `openim::release::verify_prereqs`: Similar to the previous function, this one is used to verify whether the prerequisites for the release are met. It focuses on conditions relevant to the release.
+
+4. `openim::build::build_command`: This function is responsible for building the project's command, which typically involves compiling the project or performing other build operations.
+
+5. `openim::release::package_tarballs`: This function is used to package tarball files required for the release. These tarballs are usually used for distribution packages during the release.
+
+6. `openim::release::upload_tarballs`: This function is used to upload the packaged tarball files, typically to a distribution platform or repository.
+
+7. `git push origin ${VERSION}`: This line of command pushes the version tag to the remote Git repository's `origin` branch, marking this release in the version control system.
+
+In the comments, you can see that there are some operations that are commented out, such as `openim::build::build_image`, `openim::release::github_release`, and `openim::release::generate_changelog`. These operations are related to building images, releasing to GitHub, and generating changelogs, and they can be enabled in the release process as needed.
+
+Let's take a closer look at the function responsible for packaging the tarball files:
+
+```bash
+function openim::release::package_tarballs() {
+ # Clean out any old releases
+ rm -rf "${RELEASE_STAGE}" "${RELEASE_TARS}" "${RELEASE_IMAGES}"
+ mkdir -p "${RELEASE_TARS}"
+ openim::release::package_src_tarball &
+ openim::release::package_client_tarballs &
+ openim::release::package_openim_manifests_tarball &
+ openim::release::package_server_tarballs &
+ openim::util::wait-for-jobs || { openim::log::error "previous tarball phase failed"; return 1; }
+
+ openim::release::package_final_tarball & # _final depends on some of the previous phases
+ openim::util::wait-for-jobs || { openim::log::error "previous tarball phase failed"; return 1; }
+}
+```
+
+The `openim::release::package_tarballs()` function is responsible for packaging the tarball files required for the release. Here is the specific logic of this function:
+
+1. `rm -rf "${RELEASE_STAGE}" "${RELEASE_TARS}" "${RELEASE_IMAGES}"`: First, the function removes any old release directories and files to ensure a clean starting state.
+
+2. `mkdir -p "${RELEASE_TARS}"`: Next, it creates a directory `${RELEASE_TARS}` to store the packaged tarball files. If the directory doesn't exist, it will be created.
+
+3. `openim::release::package_final_tarball &`: This is an asynchronous operation that depends on some of the previous phases. It is likely used to package the final tarball file, which includes the contents of all previous asynchronous operations.
+
+4. `openim::util::wait-for-jobs`: It waits for all asynchronous operations to complete. If any of the previous asynchronous operations fail, an error will be returned.
diff --git a/go.work b/go.work
index 63100b9f6..97d2816d6 100644
--- a/go.work
+++ b/go.work
@@ -4,14 +4,15 @@ use (
.
./test/typecheck
./tools/changelog
- //./tools/imctl
+ ./tools/component
+ ./tools/data-conversion
+ ./tools/formitychecker
+ ./tools/imctl
./tools/infra
./tools/ncpu
./tools/openim-web
+ ./tools/up35
+ ./tools/url2im
./tools/versionchecker
./tools/yamlfmt
- ./tools/component
- ./tools/url2im
- ./tools/data-conversion
- ./tools/up35
)
diff --git a/pkg/common/prommetrics/gin_api.go b/pkg/common/prommetrics/gin_api.go
index c5ef612a2..9f2e4c99d 100644
--- a/pkg/common/prommetrics/gin_api.go
+++ b/pkg/common/prommetrics/gin_api.go
@@ -14,14 +14,14 @@
package prommetrics
-import ginProm "github.com/openimsdk/open-im-server/v3/pkg/common/ginprometheus"
+import ginprom "github.com/openimsdk/open-im-server/v3/pkg/common/ginprometheus"
/*
labels := prometheus.Labels{"label_one": "any", "label_two": "value"}
ApiCustomCnt.MetricCollector.(*prometheus.CounterVec).With(labels).Inc().
*/
var (
- ApiCustomCnt = &ginProm.Metric{
+ ApiCustomCnt = &ginprom.Metric{
Name: "custom_total",
Description: "Custom counter events.",
Type: "counter_vec",
diff --git a/pkg/common/prommetrics/prommetrics.go b/pkg/common/prommetrics/prommetrics.go
index 41719dd2d..b7c5e07f4 100644
--- a/pkg/common/prommetrics/prommetrics.go
+++ b/pkg/common/prommetrics/prommetrics.go
@@ -15,7 +15,7 @@
package prommetrics
import (
- grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
+ gp "github.com/grpc-ecosystem/go-grpc-prometheus"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
@@ -23,10 +23,10 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/common/ginprometheus"
)
-func NewGrpcPromObj(cusMetrics []prometheus.Collector) (*prometheus.Registry, *grpc_prometheus.ServerMetrics, error) {
+func NewGrpcPromObj(cusMetrics []prometheus.Collector) (*prometheus.Registry, *gp.ServerMetrics, error) {
////////////////////////////////////////////////////////
reg := prometheus.NewRegistry()
- grpcMetrics := grpc_prometheus.NewServerMetrics()
+ grpcMetrics := gp.NewServerMetrics()
grpcMetrics.EnableHandlingTimeHistogram()
cusMetrics = append(cusMetrics, grpcMetrics, collectors.NewGoCollector())
reg.MustRegister(cusMetrics...)
diff --git a/scripts/.spelling_failures b/scripts/.spelling_failures
index 5c29b5992..149d314ba 100644
--- a/scripts/.spelling_failures
+++ b/scripts/.spelling_failures
@@ -3,4 +3,6 @@ go.mod
go.sum
third_party/
translations/
-log
\ No newline at end of file
+logs
+.git
+.golangci.yml
\ No newline at end of file
diff --git a/scripts/build-all-service.sh b/scripts/build-all-service.sh
index c79018a87..4b5c0613a 100755
--- a/scripts/build-all-service.sh
+++ b/scripts/build-all-service.sh
@@ -30,7 +30,7 @@ OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
source "${OPENIM_ROOT}/scripts/lib/init.sh"
# CPU core number
-pushd ""${OPENIM_ROOT}"/tools/ncpu" >/dev/null
+pushd "${OPENIM_ROOT}/tools/ncpu" >/dev/null
cpu_count=$(go run .)
popd >/dev/null
diff --git a/scripts/check-all.sh b/scripts/check-all.sh
index 7b53e4a89..72a34a5e5 100755
--- a/scripts/check-all.sh
+++ b/scripts/check-all.sh
@@ -30,6 +30,7 @@ OPENIM_VERBOSE=4
openim::log::info "\n# Begin to check all openim service"
+openim::log::status "Check all dependent service ports"
# Elegant printing function
# Elegant printing function
print_services_and_ports() {
@@ -60,7 +61,7 @@ print_services_and_ports "${OPENIM_DEPENDENCY_TARGETS[@]}" "${OPENIM_DEPENDENCY_
# OpenIM check
echo "++ The port being checked: ${OPENIM_SERVER_PORT_LISTARIES[@]}"
openim::log::info "\n## Check all dependent service ports"
-echo "+++ The port being checked: ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]}"
+echo "++ The port being checked: ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]}"
set +e
diff --git a/scripts/common.sh b/scripts/common.sh
index da0d36118..882641ae9 100755
--- a/scripts/common.sh
+++ b/scripts/common.sh
@@ -42,7 +42,7 @@ OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd -P)
# Constants
readonly OPENIM_BUILD_IMAGE_REPO=openim-build
-#readonly OPENIM_BUILD_IMAGE_CROSS_TAG="$(cat ""${OPENIM_ROOT}"/build/build-image/cross/VERSION")"
+#readonly OPENIM_BUILD_IMAGE_CROSS_TAG="$(cat "${OPENIM_ROOT}/build/build-image/cross/VERSION")"
readonly OPENIM_DOCKER_REGISTRY="${OPENIM_DOCKER_REGISTRY:-k8s.gcr.io}"
readonly OPENIM_BASE_IMAGE_REGISTRY="${OPENIM_BASE_IMAGE_REGISTRY:-us.gcr.io/k8s-artifacts-prod/build-image}"
@@ -53,7 +53,7 @@ readonly OPENIM_BASE_IMAGE_REGISTRY="${OPENIM_BASE_IMAGE_REGISTRY:-us.gcr.io/k8s
#
# Increment/change this number if you change the build image (anything under
# build/build-image) or change the set of volumes in the data container.
-#readonly OPENIM_BUILD_IMAGE_VERSION_BASE="$(cat ""${OPENIM_ROOT}"/build/build-image/VERSION")"
+#readonly OPENIM_BUILD_IMAGE_VERSION_BASE="$(cat "${OPENIM_ROOT}/build/build-image/VERSION")"
#readonly OPENIM_BUILD_IMAGE_VERSION="${OPENIM_BUILD_IMAGE_VERSION_BASE}-${OPENIM_BUILD_IMAGE_CROSS_TAG}"
# Here we map the output directories across both the local and remote _output
@@ -66,9 +66,10 @@ readonly OPENIM_BASE_IMAGE_REGISTRY="${OPENIM_BASE_IMAGE_REGISTRY:-us.gcr.io/k8s
# is really remote, this is the stuff that has to be copied
# back.
# OUT_DIR can come in from the Makefile, so honor it.
-readonly LOCAL_OUTPUT_ROOT=""${OPENIM_ROOT}"/${OUT_DIR:-_output}"
-readonly LOCAL_OUTPUT_SUBPATH="${LOCAL_OUTPUT_ROOT}/platforms"
-readonly LOCAL_OUTPUT_BINPATH="${LOCAL_OUTPUT_SUBPATH}"
+readonly LOCAL_OUTPUT_ROOT="${OPENIM_ROOT}/${OUT_DIR:-_output}"
+readonly LOCAL_OUTPUT_SUBPATH="${LOCAL_OUTPUT_ROOT}/bin"
+readonly LOCAL_OUTPUT_BINPATH="${LOCAL_OUTPUT_SUBPATH}/platforms"
+readonly LOCAL_OUTPUT_BINTOOLSPATH="${LOCAL_OUTPUT_SUBPATH}/tools"
readonly LOCAL_OUTPUT_GOPATH="${LOCAL_OUTPUT_SUBPATH}/go"
readonly LOCAL_OUTPUT_IMAGE_STAGING="${LOCAL_OUTPUT_ROOT}/images"
@@ -161,7 +162,7 @@ function openim::build::verify_prereqs() {
#LOCAL_OUTPUT_BUILD_CONTEXT="${LOCAL_OUTPUT_IMAGE_STAGING}/${OPENIM_BUILD_IMAGE}"
openim::version::get_version_vars
- #openim::version::save_version_vars ""${OPENIM_ROOT}"/.dockerized-openim-version-defs"
+ #openim::version::save_version_vars "${OPENIM_ROOT}/.dockerized-openim-version-defs"
}
# ---------------------------------------------------------------------------
@@ -416,8 +417,8 @@ function openim::build::build_image() {
cp /etc/localtime "${LOCAL_OUTPUT_BUILD_CONTEXT}/"
- cp ""${OPENIM_ROOT}"/build/build-image/Dockerfile" "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
- cp ""${OPENIM_ROOT}"/build/build-image/rsyncd.sh" "${LOCAL_OUTPUT_BUILD_CONTEXT}/"
+ cp "${OPENIM_ROOT}/build/build-image/Dockerfile" "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
+ cp "${OPENIM_ROOT}/build/build-image/rsyncd.sh" "${LOCAL_OUTPUT_BUILD_CONTEXT}/"
dd if=/dev/urandom bs=512 count=1 2>/dev/null | LC_ALL=C tr -dc 'A-Za-z0-9' | dd bs=32 count=1 2>/dev/null > "${LOCAL_OUTPUT_BUILD_CONTEXT}/rsyncd.password"
chmod go= "${LOCAL_OUTPUT_BUILD_CONTEXT}/rsyncd.password"
diff --git a/scripts/ensure-tag.sh b/scripts/ensure-tag.sh
index c6fea7ca0..2847342f4 100755
--- a/scripts/ensure-tag.sh
+++ b/scripts/ensure-tag.sh
@@ -14,9 +14,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
+
version="${VERSION}"
if [ "${version}" == "" ];then
- version=v`gsemver bump`
+ version=v`${OPENIM_ROOT}/_output/tools/gsemver bump`
fi
if [ -z "`git tag -l ${version}`" ];then
diff --git a/scripts/genconfig.sh b/scripts/genconfig.sh
index 8ded38b22..659e8f4be 100755
--- a/scripts/genconfig.sh
+++ b/scripts/genconfig.sh
@@ -53,4 +53,4 @@ fi
eval "cat << EOF
$(cat ${template_file})
-EOF"
+EOF"
\ No newline at end of file
diff --git a/scripts/install/environment.sh b/scripts/install/environment.sh
index 9d9fc4028..f84cb924a 100755
--- a/scripts/install/environment.sh
+++ b/scripts/install/environment.sh
@@ -22,7 +22,7 @@
OPENIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"
# 生成文件存放目录
-LOCAL_OUTPUT_ROOT=""${OPENIM_ROOT}"/${OUT_DIR:-_output}"
+LOCAL_OUTPUT_ROOT="${OPENIM_ROOT}/${OUT_DIR:-_output}"
source "${OPENIM_ROOT}/scripts/lib/init.sh"
#TODO: Access to the OPENIM_IP networks outside, or you want to use the OPENIM_IP network
@@ -62,7 +62,7 @@ readonly LINUX_PASSWORD=${LINUX_PASSWORD:-"${PASSWORD}"}
def "INSTALL_DIR" "${LOCAL_OUTPUT_ROOT}/installs"
mkdir -p ${INSTALL_DIR}
-def "ENV_FILE" ""${OPENIM_ROOT}"/scripts/install/environment.sh"
+def "ENV_FILE" "${OPENIM_ROOT}/scripts/install/environment.sh"
###################### Docker compose ###################
# OPENIM AND CHAT
@@ -128,7 +128,7 @@ def "OPENIM_CONFIG_DIR" "/etc/openim/config"
def "OPENIM_LOG_DIR" "/var/log/openim"
def "CA_FILE" "${OPENIM_CONFIG_DIR}/cert/ca.pem"
-def "OPNEIM_CONFIG" ""${OPENIM_ROOT}"/config"
+def "OPNEIM_CONFIG" "${OPENIM_ROOT}/config"
def "OPENIM_SERVER_ADDRESS" "${DOCKER_BRIDGE_GATEWAY}" # OpenIM服务地址
# OpenIM Websocket端口
@@ -326,7 +326,7 @@ def "OPENIM_CONVERSATION_NAME" "Conversation" # OpenIM对话服务名称
def "OPENIM_THIRD_NAME" "Third" # OpenIM第三方服务名称
###################### Log Configuration Variables ######################
-def "LOG_STORAGE_LOCATION" ""${OPENIM_ROOT}"/logs/" # 日志存储位置
+def "LOG_STORAGE_LOCATION" "${OPENIM_ROOT}/logs/" # 日志存储位置
def "LOG_ROTATION_TIME" "24" # 日志轮替时间
def "LOG_REMAIN_ROTATION_COUNT" "2" # 保留的日志轮替数量
def "LOG_REMAIN_LOG_LEVEL" "6" # 保留的日志级别
@@ -414,7 +414,7 @@ readonly MSG_TRANSFER_PROM_ADDRESS_PORT=${MSG_TRANSFER_PROM_ADDRESS_PORT:-"${DOC
###################### OpenIM openim-api ######################
def "OPENIM_API_HOST" "127.0.0.1"
def "OPENIM_API_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-api" # OpenIM openim-api 二进制文件路径
-def "OPENIM_API_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-api 配置文件路径
+def "OPENIM_API_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-api 配置文件路径
def "OPENIM_API_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-api" # OpenIM openim-api 日志存储路径
def "OPENIM_API_LOG_LEVEL" "info" # OpenIM openim-api 日志级别
def "OPENIM_API_LOG_MAX_SIZE" "100" # OpenIM openim-api 日志最大大小(MB)
@@ -426,7 +426,7 @@ def "OPENIM_API_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-ap
###################### OpenIM openim-cmdutils ######################
def "OPENIM_CMDUTILS_HOST" "127.0.0.1"
def "OPENIM_CMDUTILS_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-cmdutils" # OpenIM openim-cmdutils 二进制文件路径
-def "OPENIM_CMDUTILS_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-cmdutils 配置文件路径
+def "OPENIM_CMDUTILS_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-cmdutils 配置文件路径
def "OPENIM_CMDUTILS_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-cmdutils" # OpenIM openim-cmdutils 日志存储路径
def "OPENIM_CMDUTILS_LOG_LEVEL" "info" # OpenIM openim-cmdutils 日志级别
def "OPENIM_CMDUTILS_LOG_MAX_SIZE" "100" # OpenIM openim-cmdutils 日志最大大小(MB)
@@ -438,7 +438,7 @@ def "OPENIM_CMDUTILS_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM
###################### OpenIM openim-crontask ######################
def "OPENIM_CRONTASK_HOST" "127.0.0.1"
def "OPENIM_CRONTASK_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-crontask" # OpenIM openim-crontask 二进制文件路径
-def "OPENIM_CRONTASK_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-crontask 配置文件路径
+def "OPENIM_CRONTASK_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-crontask 配置文件路径
def "OPENIM_CRONTASK_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-crontask" # OpenIM openim-crontask 日志存储路径
def "OPENIM_CRONTASK_LOG_LEVEL" "info" # OpenIM openim-crontask 日志级别
def "OPENIM_CRONTASK_LOG_MAX_SIZE" "100" # OpenIM openim-crontask 日志最大大小(MB)
@@ -450,7 +450,7 @@ def "OPENIM_CRONTASK_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM
###################### OpenIM openim-msggateway ######################
def "OPENIM_MSGGATEWAY_HOST" "127.0.0.1"
def "OPENIM_MSGGATEWAY_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-msggateway"
-def "OPENIM_MSGGATEWAY_CONFIG" ""${OPENIM_ROOT}"/config/"
+def "OPENIM_MSGGATEWAY_CONFIG" "${OPENIM_ROOT}/config/"
def "OPENIM_MSGGATEWAY_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-msggateway"
def "OPENIM_MSGGATEWAY_LOG_LEVEL" "info"
def "OPENIM_MSGGATEWAY_LOG_MAX_SIZE" "100"
@@ -465,7 +465,7 @@ readonly OPENIM_MSGGATEWAY_NUM=${OPENIM_MSGGATEWAY_NUM:-'4'}
###################### OpenIM openim-msgtransfer ######################
def "OPENIM_MSGTRANSFER_HOST" "127.0.0.1"
def "OPENIM_MSGTRANSFER_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-msgtransfer" # OpenIM openim-msgtransfer 二进制文件路径
-def "OPENIM_MSGTRANSFER_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-msgtransfer 配置文件路径
+def "OPENIM_MSGTRANSFER_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-msgtransfer 配置文件路径
def "OPENIM_MSGTRANSFER_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-msgtransfer" # OpenIM openim-msgtransfer 日志存储路径
def "OPENIM_MSGTRANSFER_LOG_LEVEL" "info" # OpenIM openim-msgtransfer 日志级别
def "OPENIM_MSGTRANSFER_LOG_MAX_SIZE" "100" # OpenIM openim-msgtransfer 日志最大大小(MB)
@@ -477,7 +477,7 @@ def "OPENIM_MSGTRANSFER_LOG_WITH_STACK" "${LOG_WITH_STACK}" #
###################### OpenIM openim-push ######################
def "OPENIM_PUSH_HOST" "127.0.0.1"
def "OPENIM_PUSH_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-push" # OpenIM openim-push 二进制文件路径
-def "OPENIM_PUSH_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-push 配置文件路径
+def "OPENIM_PUSH_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-push 配置文件路径
def "OPENIM_PUSH_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-push" # OpenIM openim-push 日志存储路径
def "OPENIM_PUSH_LOG_LEVEL" "info" # OpenIM openim-push 日志级别
def "OPENIM_PUSH_LOG_MAX_SIZE" "100" # OpenIM openim-push 日志最大大小(MB)
@@ -489,7 +489,7 @@ def "OPENIM_PUSH_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-
###################### OpenIM openim-rpc-auth ######################
def "OPENIM_RPC_AUTH_HOST" "127.0.0.1"
def "OPENIM_RPC_AUTH_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-auth" # OpenIM openim-rpc-auth 二进制文件路径
-def "OPENIM_RPC_AUTH_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-rpc-auth 配置文件路径
+def "OPENIM_RPC_AUTH_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-auth 配置文件路径
def "OPENIM_RPC_AUTH_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-auth" # OpenIM openim-rpc-auth 日志存储路径
def "OPENIM_RPC_AUTH_LOG_LEVEL" "info" # OpenIM openim-rpc-auth 日志级别
def "OPENIM_RPC_AUTH_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-auth 日志最大大小(MB)
@@ -501,7 +501,7 @@ def "OPENIM_RPC_AUTH_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM
###################### OpenIM openim-rpc-conversation ######################
def "OPENIM_RPC_CONVERSATION_HOST" "127.0.0.1"
def "OPENIM_RPC_CONVERSATION_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-conversation" # OpenIM openim-rpc-conversation 二进制文件路径
-def "OPENIM_RPC_CONVERSATION_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-rpc-conversation 配置文件路径
+def "OPENIM_RPC_CONVERSATION_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-conversation 配置文件路径
def "OPENIM_RPC_CONVERSATION_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-conversation" # OpenIM openim-rpc-conversation 日志存储路径
def "OPENIM_RPC_CONVERSATION_LOG_LEVEL" "info" # OpenIM openim-rpc-conversation 日志级别
def "OPENIM_RPC_CONVERSATION_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-conversation 日志最大大小(MB)
@@ -513,7 +513,7 @@ def "OPENIM_RPC_CONVERSATION_LOG_WITH_STACK" "${LOG_WITH_STACK}"
###################### OpenIM openim-rpc-friend ######################
def "OPENIM_RPC_FRIEND_HOST" "127.0.0.1"
def "OPENIM_RPC_FRIEND_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-friend" # OpenIM openim-rpc-friend 二进制文件路径
-def "OPENIM_RPC_FRIEND_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-rpc-friend 配置文件路径
+def "OPENIM_RPC_FRIEND_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-friend 配置文件路径
def "OPENIM_RPC_FRIEND_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-friend" # OpenIM openim-rpc-friend 日志存储路径
def "OPENIM_RPC_FRIEND_LOG_LEVEL" "info" # OpenIM openim-rpc-friend 日志级别
def "OPENIM_RPC_FRIEND_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-friend 日志最大大小(MB)
@@ -525,7 +525,7 @@ def "OPENIM_RPC_FRIEND_LOG_WITH_STACK" "${LOG_WITH_STACK}" # Op
###################### OpenIM openim-rpc-group ######################
def "OPENIM_RPC_GROUP_HOST" "127.0.0.1"
def "OPENIM_RPC_GROUP_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-group" # OpenIM openim-rpc-group 二进制文件路径
-def "OPENIM_RPC_GROUP_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-rpc-group 配置文件路径
+def "OPENIM_RPC_GROUP_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-group 配置文件路径
def "OPENIM_RPC_GROUP_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-group" # OpenIM openim-rpc-group 日志存储路径
def "OPENIM_RPC_GROUP_LOG_LEVEL" "info" # OpenIM openim-rpc-group 日志级别
def "OPENIM_RPC_GROUP_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-group 日志最大大小(MB)
@@ -537,7 +537,7 @@ def "OPENIM_RPC_GROUP_LOG_WITH_STACK" "${LOG_WITH_STACK}" # Open
###################### OpenIM openim-rpc-msg ######################
def "OPENIM_RPC_MSG_HOST" "127.0.0.1"
def "OPENIM_RPC_MSG_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-msg" # OpenIM openim-rpc-msg 二进制文件路径
-def "OPENIM_RPC_MSG_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-rpc-msg 配置文件路径
+def "OPENIM_RPC_MSG_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-msg 配置文件路径
def "OPENIM_RPC_MSG_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-msg" # OpenIM openim-rpc-msg 日志存储路径
def "OPENIM_RPC_MSG_LOG_LEVEL" "info" # OpenIM openim-rpc-msg 日志级别
def "OPENIM_RPC_MSG_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-msg 日志最大大小(MB)
@@ -549,7 +549,7 @@ def "OPENIM_RPC_MSG_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM o
###################### OpenIM openim-rpc-third ######################
def "OPENIM_RPC_THIRD_HOST" "127.0.0.1"
def "OPENIM_RPC_THIRD_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-third" # OpenIM openim-rpc-third 二进制文件路径
-def "OPENIM_RPC_THIRD_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-rpc-third 配置文件路径
+def "OPENIM_RPC_THIRD_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-third 配置文件路径
def "OPENIM_RPC_THIRD_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-third" # OpenIM openim-rpc-third 日志存储路径
def "OPENIM_RPC_THIRD_LOG_LEVEL" "info" # OpenIM openim-rpc-third 日志级别
def "OPENIM_RPC_THIRD_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-third 日志最大大小(MB)
@@ -561,7 +561,7 @@ def "OPENIM_RPC_THIRD_LOG_WITH_STACK" "${LOG_WITH_STACK}" # Open
###################### OpenIM openim-rpc-user ######################
def "OPENIM_RPC_USER_HOST" "127.0.0.1"
def "OPENIM_RPC_USER_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-user" # OpenIM openim-rpc-user 二进制文件路径
-def "OPENIM_RPC_USER_CONFIG" ""${OPENIM_ROOT}"/config/" # OpenIM openim-rpc-user 配置文件路径
+def "OPENIM_RPC_USER_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-user 配置文件路径
def "OPENIM_RPC_USER_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-user" # OpenIM openim-rpc-user 日志存储路径
def "OPENIM_RPC_USER_LOG_LEVEL" "info" # OpenIM openim-rpc-user 日志级别
def "OPENIM_RPC_USER_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-user 日志最大大小(MB)
diff --git a/scripts/install/openim-man.sh b/scripts/install/openim-man.sh
index 6dda4bfe1..f23c54a20 100755
--- a/scripts/install/openim-man.sh
+++ b/scripts/install/openim-man.sh
@@ -26,9 +26,9 @@
# ./openim-man.sh openim::man::status - Check installation status
#
# Dependencies:
-# - Assumes there's a common.sh in ""${OPENIM_ROOT}"/scripts/install/"
+# - Assumes there's a common.sh in "${OPENIM_ROOT}/scripts/install/"
# containing shared functions and variables.
-# - Relies on the script ""${OPENIM_ROOT}"/scripts/update-generated-docs.sh"
+# - Relies on the script "${OPENIM_ROOT}/scripts/update-generated-docs.sh"
# to generate the man pages.
#
# Notes:
@@ -58,7 +58,7 @@ function openim::man::install() {
pushd "${OPENIM_ROOT}" > /dev/null
# Generate man pages for each component
- ""${OPENIM_ROOT}"/scripts/update-generated-docs.sh"
+ "${OPENIM_ROOT}/scripts/update-generated-docs.sh"
openim::common::sudo "cp docs/man/man1/* /usr/share/man/man1/"
# Verify installation status
diff --git a/scripts/install/openim-tools.sh b/scripts/install/openim-tools.sh
index f97b9d836..385df64f5 100755
--- a/scripts/install/openim-tools.sh
+++ b/scripts/install/openim-tools.sh
@@ -103,8 +103,13 @@ function openim::tools::start_service() {
printf "Specifying prometheus port: %s\n" "${prometheus_port}"
cmd="${cmd} --prometheus_port ${prometheus_port}"
fi
- openim::log::info "Starting ${binary_name}..."
- ${cmd}
+ openim::log::status "Starting ${binary_name}..."
+ # Later, after discarding Docker, the Docker keyword is unreliable, and Kubepods is used
+ if grep -qE 'docker|kubepods' /proc/1/cgroup || [ -f /.dockerenv ]; then
+ ${cmd} >> "${LOG_FILE}" 2>&1
+ else
+ ${cmd} | tee -a "${LOG_FILE}"
+ fi
}
function openim::tools::start() {
diff --git a/scripts/lib/chat.sh b/scripts/lib/chat.sh
index eef94edbd..549422b11 100755
--- a/scripts/lib/chat.sh
+++ b/scripts/lib/chat.sh
@@ -27,7 +27,7 @@ openim::chat::validate() {
# validate if in path
command -v chat >/dev/null || {
openim::log::usage "chat must be in your PATH"
- openim::log::info "You can use 'hack/install-chat.sh' to install a copy in third_party/."
+ openim::log::info "You can use 'scripts/install-chat.sh' to install a copy in third_party/."
exit 1
}
@@ -61,7 +61,7 @@ openim::chat::validate() {
version=$(chat --version | grep Version | head -n 1 | cut -d " " -f 3)
if [[ $(openim::chat::version "${CHAT_VERSION}") -gt $(openim::chat::version "${version}") ]]; then
openim::log::usage "chat version ${CHAT_VERSION} or greater required."
- openim::log::info "You can use 'hack/install-chat.sh' to install a copy in third_party/."
+ openim::log::info "You can use 'scripts/install-chat.sh' to install a copy in third_party/."
exit 1
fi
fi
@@ -148,7 +148,7 @@ openim::chat::install() {
os=$(openim::util::host_os)
arch=$(openim::util::host_arch)
- cd ""${OPENIM_ROOT}"/third_party" || return 1
+ cd "${OPENIM_ROOT}/third_party" || return 1
if [[ $(readlink chat) == chat-v${CHAT_VERSION}-${os}-* ]]; then
openim::log::info "chat v${CHAT_VERSION} already installed. To use:"
openim::log::info "export PATH=\"$(pwd)/chat:\${PATH}\""
diff --git a/scripts/lib/golang.sh b/scripts/lib/golang.sh
index a65d2c9f5..af04771d5 100755
--- a/scripts/lib/golang.sh
+++ b/scripts/lib/golang.sh
@@ -89,7 +89,7 @@ readonly OPENIM_SERVER_TARGETS
readonly OPENIM_SERVER_BINARIES=("${OPENIM_SERVER_TARGETS[@]##*/}")
# TODO: Label
-START_SCRIPTS_PATH=""${OPENIM_ROOT}"/scripts/install/"
+START_SCRIPTS_PATH="${OPENIM_ROOT}/scripts/install/"
openim::golang::start_script_list() {
local targets=(
openim-api.sh
@@ -261,7 +261,18 @@ openim::golang::setup_platforms
# The set of client targets that we are building for all platforms
# If you update this list, please also update build/BUILD.
readonly OPENIM_CLIENT_TARGETS=(
- imctl
+ changelog
+ component
+ conversion-msg
+ conversion-mysql
+ formitychecker
+ imctl
+ infra
+ ncpu
+ openim-web
+ up35
+ versionchecker
+ yamlfmt
)
readonly OPENIM_CLIENT_BINARIES=("${OPENIM_CLIENT_TARGETS[@]##*/}")
diff --git a/scripts/lib/init.sh b/scripts/lib/init.sh
index 631e751ba..be8e9f8aa 100755
--- a/scripts/lib/init.sh
+++ b/scripts/lib/init.sh
@@ -25,7 +25,7 @@ unset CDPATH
# Until all GOPATH references are removed from all build scripts as well,
# explicitly disable module mode to avoid picking up user-set GO111MODULE preferences.
-# As individual scripts (like hack/update-vendor.sh) make use of go modules,
+# As individual scripts (like scripts/update-vendor.sh) make use of go modules,
# they can explicitly set GO111MODULE=on
export GO111MODULE=on
@@ -33,7 +33,7 @@ export GO111MODULE=on
OPENIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"
OPENIM_OUTPUT_SUBPATH="${OPENIM_OUTPUT_SUBPATH:-_output}"
-OPENIM_OUTPUT=""${OPENIM_ROOT}"/${OPENIM_OUTPUT_SUBPATH}"
+OPENIM_OUTPUT="${OPENIM_ROOT}/${OPENIM_OUTPUT_SUBPATH}"
OPENIM_OUTPUT_BINPATH="${OPENIM_OUTPUT}/bin/platforms"
OPENIM_OUTPUT_BINTOOLPATH="${OPENIM_OUTPUT}/bin/tools"
@@ -50,8 +50,8 @@ OPENIM_RSYNC_COMPRESS="${KUBE_RSYNC_COMPRESS:-0}"
export no_proxy="127.0.0.1,localhost${no_proxy:+,${no_proxy}}"
# This is a symlink to binaries for "this platform", e.g. build tools.
-export THIS_PLATFORM_BIN=""${OPENIM_ROOT}"/_output/bin/platforms"
-export THIS_PLATFORM_BIN_TOOLS=""${OPENIM_ROOT}"/_output/bin/tools"
+export THIS_PLATFORM_BIN="${OPENIM_ROOT}/_output/bin/platforms"
+export THIS_PLATFORM_BIN_TOOLS="${OPENIM_ROOT}/_output/bin/tools"
. $(dirname ${BASH_SOURCE})/color.sh
. $(dirname ${BASH_SOURCE})/util.sh
@@ -62,7 +62,6 @@ openim::util::ensure-bash-version
. $(dirname ${BASH_SOURCE})/version.sh
. $(dirname ${BASH_SOURCE})/golang.sh
-. $(dirname ${BASH_SOURCE})/release.sh
. $(dirname ${BASH_SOURCE})/chat.sh
OPENIM_OUTPUT_HOSTBIN="${OPENIM_OUTPUT_BINPATH}/$(openim::util::host_platform)"
diff --git a/scripts/lib/release.sh b/scripts/lib/release.sh
index dba74c768..16f2cd97a 100755
--- a/scripts/lib/release.sh
+++ b/scripts/lib/release.sh
@@ -22,7 +22,6 @@
# example: ./coscli cp/sync -r /home/off-line/docker-off-line/ cos://openim-1306374445/openim/image/amd/off-line/off-line/ -e cos.ap-guangzhou.myqcloud.com
# https://cloud.tencent.com/document/product/436/71763
-# Tencent cos configuration
readonly BUCKET="openim-1306374445"
readonly REGION="ap-guangzhou"
readonly COS_RELEASE_DIR="openim-release"
@@ -36,8 +35,8 @@ readonly RELEASE_TARS="${LOCAL_OUTPUT_ROOT}/release-tars"
readonly RELEASE_IMAGES="${LOCAL_OUTPUT_ROOT}/release-images"
# OpenIM github account info
-readonly OPENIM_GITHUB_ORG=OpenIMSDK
-readonly OPENIM_GITHUB_REPO=Open-IM-Server
+readonly OPENIM_GITHUB_ORG=openimsdk
+readonly OPENIM_GITHUB_REPO=open-im-server
readonly CHAT_GITHUB_REPO=chat
readonly ARTIFACT=openim.tar.gz
@@ -46,6 +45,14 @@ readonly CHECKSUM=${ARTIFACT}.sha1sum
OPENIM_BUILD_CONFORMANCE=${OPENIM_BUILD_CONFORMANCE:-y}
OPENIM_BUILD_PULL_LATEST_IMAGES=${OPENIM_BUILD_PULL_LATEST_IMAGES:-y}
+if [ -z "${OPENIM_ROOT}" ]; then
+ OPENIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"
+fi
+
+if [ -z "${TOOLS_DIR}" ]; then
+ TOOLS_DIR="${OPENIM_ROOT}/_output/tools"
+fi
+
# Validate a ci version
#
# Globals:
@@ -113,13 +120,14 @@ function openim::release::package_tarballs() {
openim::util::wait-for-jobs || { openim::log::error "previous tarball phase failed"; return 1; }
}
-function openim::release::updload_tarballs() {
+function openim::release::upload_tarballs() {
openim::log::info "upload ${RELEASE_TARS}/* to cos bucket ${BUCKET}."
for file in $(ls ${RELEASE_TARS}/*)
do
if [ "${COSTOOL}" == "coscli" ];then
- coscli cp "${file}" "cos://${BUCKET}/${COS_RELEASE_DIR}/${OPENIM_GIT_VERSION}/${file##*/}"
- coscli cp "${file}" "cos://${BUCKET}/${COS_RELEASE_DIR}/latest/${file##*/}"
+ echo "++++ ${TOOLS_DIR}/coscli cp ${file} cos://${BUCKET}/${COS_RELEASE_DIR}/${OPENIM_GIT_VERSION}/${file##*/}"
+ ${TOOLS_DIR}/coscli cp "${file}" "cos://${BUCKET}/${COS_RELEASE_DIR}/${OPENIM_GIT_VERSION}/${file##*/}"
+ ${TOOLS_DIR}/coscli cp "${file}" "cos://${BUCKET}/${COS_RELEASE_DIR}/latest/${file##*/}"
else
coscmd upload "${file}" "${COS_RELEASE_DIR}/${OPENIM_GIT_VERSION}/"
coscmd upload "${file}" "${COS_RELEASE_DIR}/latest/"
@@ -139,6 +147,8 @@ function openim::release::package_src_tarball() {
\( -path "${OPENIM_ROOT}"/_\* -o \
-path "${OPENIM_ROOT}"/.git\* -o \
-path "${OPENIM_ROOT}"/.github\* -o \
+ -path "${OPENIM_ROOT}"/components\* -o \
+ -path "${OPENIM_ROOT}"/logs\* -o \
-path "${OPENIM_ROOT}"/.gitignore\* -o \
-path "${OPENIM_ROOT}"/.gsemver.yml\* -o \
-path "${OPENIM_ROOT}"/.config\* -o \
@@ -158,6 +168,7 @@ function openim::release::package_src_tarball() {
function openim::release::package_server_tarballs() {
# Find all of the built client binaries
local long_platforms=("${LOCAL_OUTPUT_BINPATH}"/*/*)
+
if [[ -n ${OPENIM_BUILD_PLATFORMS-} ]]; then
read -ra long_platforms <<< "${OPENIM_BUILD_PLATFORMS}"
fi
@@ -167,68 +178,81 @@ function openim::release::package_server_tarballs() {
local platform_tag
platform=${platform_long##${LOCAL_OUTPUT_BINPATH}/} # Strip LOCAL_OUTPUT_BINPATH
platform_tag=${platform/\//-} # Replace a "/" for a "-"
+
openim::log::status "Starting tarball: server $platform_tag"
(
local release_stage="${RELEASE_STAGE}/server/${platform_tag}/openim"
+ openim::log::info "release_stage: ${release_stage}"
+
rm -rf "${release_stage}"
mkdir -p "${release_stage}/server/bin"
local server_bins=("${OPENIM_SERVER_BINARIES[@]}")
- # This fancy expression will expand to prepend a path
- # (${LOCAL_OUTPUT_BINPATH}/${platform}/) to every item in the
- # server_bins array.
- cp "${server_bins[@]/bin/#/${LOCAL_OUTPUT_BINPATH}/${platform}/}" \
+ openim::log::info " Copy client binaries: ${client_bins[@]/#/${LOCAL_OUTPUT_BINPATH}/${platform}/}"
+ openim::log::info " Copy client binaries to: ${release_stage}/server/bin"
+
+ # Copy server binaries
+ cp "${server_bins[@]/#/${LOCAL_OUTPUT_BINPATH}/${platform}/}" \
"${release_stage}/server/bin/"
- openim::release::clean_cruft
+ openim::release::clean_cruft
- local package_name="${RELEASE_TARS}/openim-server-${platform_tag}.tar.gz"
- openim::release::create_tarball "${package_name}" "${release_stage}/.."
- ) &
- done
-
- openim::log::status "Waiting on tarballs"
- openim::util::wait-for-jobs || { openim::log::error "server tarball creation failed"; exit 1; }
- }
+ local package_name="${RELEASE_TARS}/openim-server-${platform_tag}.tar.gz"
+ openim::release::create_tarball "${package_name}" "${release_stage}/.."
+ ) &
+ done
+ openim::log::status "Waiting on tarballs"
+ openim::util::wait-for-jobs || { openim::log::error "server tarball creation failed"; exit 1; }
+}
+# Package up all of the cross compiled clients. Over time this should grow into
+# a full SDK
# Package up all of the cross compiled clients. Over time this should grow into
# a full SDK
function openim::release::package_client_tarballs() {
# Find all of the built client binaries
- local long_platforms=("${LOCAL_OUTPUT_BINPATH}"/*/*)
+ local long_platforms=("${LOCAL_OUTPUT_BINTOOLSPATH}"/*/*)
if [[ -n ${OPENIM_BUILD_PLATFORMS-} ]]; then
read -ra long_platforms <<< "${OPENIM_BUILD_PLATFORMS}"
fi
+ # echo "++++ LOCAL_OUTPUT_BINTOOLSPATH: ${LOCAL_OUTPUT_BINTOOLSPATH}"
+ # LOCAL_OUTPUT_BINTOOLSPATH: /data/workspaces/open-im-server/_output/bin/tools
+ # echo "++++ long_platforms: ${long_platforms[@]}"
+ # long_platforms: /data/workspaces/open-im-server/_output/bin/tools/darwin/amd64 /data/workspaces/open-im-server/_output/bin/tools/darwin/arm64 /data/workspaces/open-im-server/_output/bin/tools/linux/amd64 /data/workspaces/open-im-server/_output/bin/tools/linux/arm64 /data/workspaces/open-im-server/_output/bin/tools/linux/mips64 /data/workspaces/open-im-server/_output/bin/tools/linux/mips64le /data/workspaces/open-im-server/_output/bin/tools/linux/ppc64le /data/workspaces/open-im-server/_output/bin/tools/linux/s390x /data/workspaces/open-im-server/_output/bin/tools/windows/amd64
for platform_long in "${long_platforms[@]}"; do
local platform
local platform_tag
- platform=${platform_long##${LOCAL_OUTPUT_BINPATH}/} # Strip LOCAL_OUTPUT_BINPATH
+ platform=${platform_long##${LOCAL_OUTPUT_BINTOOLSPATH}/} # Strip LOCAL_OUTPUT_BINTOOLSPATH
platform_tag=${platform/\//-} # Replace a "/" for a "-"
- openim::log::status "Starting tarball: client $platform_tag"
+ openim::log::status "Starting tarball: client $platform_tag" # darwin-amd64
(
local release_stage="${RELEASE_STAGE}/client/${platform_tag}/openim"
+
+ openim::log::info "release_stage: ${release_stage}"
+ # ++++ release_stage: /data/workspaces/open-im-server/_output/release-stage/client/darwin-amd64/openim
rm -rf "${release_stage}"
mkdir -p "${release_stage}/client/bin"
local client_bins=("${OPENIM_CLIENT_BINARIES[@]}")
- # This fancy expression will expand to prepend a path
- # (${LOCAL_OUTPUT_BINPATH}/${platform}/) to every item in the
- # client_bins array.
- cp "${client_bins[@]/bin/#/${LOCAL_OUTPUT_BINPATH}/${platform}/}" \
+ # client_bins: changelog component conversion-msg conversion-mysql formitychecker imctl infra ncpu openim-web up35 versionchecker yamlfmt
+ # Copy client binclient_bins:aries
+ openim::log::info " Copy client binaries: ${client_bins[@]/#/${LOCAL_OUTPUT_BINTOOLSPATH}/${platform}/}"
+ openim::log::info " Copy client binaries to: ${release_stage}/client/bin"
+
+ cp "${client_bins[@]/#/${LOCAL_OUTPUT_BINTOOLSPATH}/${platform}/}" \
"${release_stage}/client/bin/"
- openim::release::clean_cruft
+ openim::release::clean_cruft
- local package_name="${RELEASE_TARS}/openim-client-${platform_tag}.tar.gz"
- openim::release::create_tarball "${package_name}" "${release_stage}/.."
+ local package_name="${RELEASE_TARS}/openim-client-${platform_tag}.tar.gz"
+ openim::release::create_tarball "${package_name}" "${release_stage}/.."
) &
done
-
openim::log::status "Waiting on tarballs"
openim::util::wait-for-jobs || { openim::log::error "client tarball creation failed"; exit 1; }
}
@@ -354,7 +378,7 @@ function openim::release::create_docker_images_for_server() {
rm -rf "${docker_build_path}"
mkdir -p "${docker_build_path}"
ln "${binary_file_path}" "${docker_build_path}/${binary_name}"
- ln ""${OPENIM_ROOT}"/build/nsswitch.conf" "${docker_build_path}/nsswitch.conf"
+ ln "${OPENIM_ROOT}/build/nsswitch.conf" "${docker_build_path}/nsswitch.conf"
chmod 0644 "${docker_build_path}/nsswitch.conf"
cat < "${docker_file_path}"
FROM ${base_image}
@@ -399,7 +423,7 @@ EOF
function openim::release::package_openim_manifests_tarball() {
openim::log::status "Building tarball: manifests"
- local src_dir=""${OPENIM_ROOT}"/deployments"
+ local src_dir="${OPENIM_ROOT}/deployments"
local release_stage="${RELEASE_STAGE}/manifests/openim"
rm -rf "${release_stage}"
@@ -420,7 +444,7 @@ function openim::release::package_openim_manifests_tarball() {
#cp "${src_dir}/openim-rpc-msg.yaml" "${dst_dir}"
#cp "${src_dir}/openim-rpc-third.yaml" "${dst_dir}"
#cp "${src_dir}/openim-rpc-user.yaml" "${dst_dir}"
- #cp ""${OPENIM_ROOT}"/cluster/gce/gci/health-monitor.sh" "${dst_dir}/health-monitor.sh"
+ #cp "${OPENIM_ROOT}/cluster/gce/gci/health-monitor.sh" "${dst_dir}/health-monitor.sh"
openim::release::clean_cruft
@@ -442,6 +466,7 @@ function openim::release::package_final_tarball() {
# This isn't a "full" tarball anymore, but the release lib still expects
# artifacts under "full/openim/"
local release_stage="${RELEASE_STAGE}/full/openim"
+ openim::log::info "release_stage(final): ${release_stage}"
rm -rf "${release_stage}"
mkdir -p "${release_stage}"
@@ -454,7 +479,8 @@ EOF
# We want everything in /scripts.
mkdir -p "${release_stage}/release"
- cp -R ""${OPENIM_ROOT}"/scripts/release" "${release_stage}/"
+ mkdir -p "${OPENIM_ROOT}/scripts/release"
+ cp -R "${OPENIM_ROOT}/scripts/release" "${release_stage}/"
cat < "${release_stage}/release/get-openim-binaries.sh"
#!/usr/bin/env bash
# This file download openim client and server binaries from tencent cos bucket.
@@ -471,11 +497,11 @@ Server binary tarballs are no longer included in the OpenIM final tarball.
Run release/get-openim-binaries.sh to download client and server binaries.
EOF
- # Include hack/lib as a dependency for the cluster/ scripts
+ # Include scripts/lib as a dependency for the cluster/ scripts
#mkdir -p "${release_stage}/hack"
- #cp -R ""${OPENIM_ROOT}"/hack/lib" "${release_stage}/hack/"
+ #cp -R "${OPENIM_ROOT}/scripts/lib" "${release_stage}/scripts/"
- cp -R "${OPENIM_ROOT}"/{docs,configs,scripts,deployments,init,README.md,LICENSE} "${release_stage}/"
+ cp -R "${OPENIM_ROOT}"/{docs,config,scripts,deployments,README.md,LICENSE} "${release_stage}/"
echo "${OPENIM_GIT_VERSION}" > "${release_stage}/version"
@@ -507,7 +533,7 @@ function openim::release::install_github_release(){
# - git-chglog
# - coscmd or coscli
function openim::release::verify_prereqs(){
- if [ -z "$(which github-release 2>/dev/null)" ]; then
+ if [ -z "$(which ${TOOLS_DIR}/github-release 2>/dev/null)" ]; then
openim::log::info "'github-release' tool not installed, try to install it."
if ! openim::release::install_github_release; then
@@ -516,7 +542,7 @@ function openim::release::verify_prereqs(){
fi
fi
- if [ -z "$(which git-chglog 2>/dev/null)" ]; then
+ if [ -z "$(which ${TOOLS_DIR}/git-chglog 2>/dev/null)" ]; then
openim::log::info "'git-chglog' tool not installed, try to install it."
if ! go install github.com/git-chglog/git-chglog/cmd/git-chglog@latest &>/dev/null; then
@@ -525,7 +551,7 @@ function openim::release::verify_prereqs(){
fi
fi
- if [ -z "$(which gsemver 2>/dev/null)" ]; then
+ if [ -z "$(which ${TOOLS_DIR}/gsemver 2>/dev/null)" ]; then
openim::log::info "'gsemver' tool not installed, try to install it."
if ! go install github.com/arnaud-deprez/gsemver@latest &>/dev/null; then
@@ -534,8 +560,7 @@ function openim::release::verify_prereqs(){
fi
fi
-
- if [ -z "$(which ${COSTOOL} 2>/dev/null)" ]; then
+ if [ -z "$(which ${TOOLS_DIR}/${COSTOOL} 2>/dev/null)" ]; then
openim::log::info "${COSTOOL} tool not installed, try to install it."
if ! make -C "${OPENIM_ROOT}" tools.install.${COSTOOL}; then
@@ -545,6 +570,7 @@ function openim::release::verify_prereqs(){
fi
if [ -z "${TENCENT_SECRET_ID}" -o -z "${TENCENT_SECRET_KEY}" ];then
+ openim::log::info "You need set env: TENCENT_SECRET_ID(cos secretid) and TENCENT_SECRET_KEY(cos secretkey)"
openim::log::error "can not find env: TENCENT_SECRET_ID and TENCENT_SECRET_KEY"
return 1
fi
@@ -584,39 +610,57 @@ EOF
# https://github.com/github-release/github-release
function openim::release::github_release() {
# create a github release
+ if [ -z "${GITHUB_TOKEN}" ];then
+ openim::log::error "can not find env: GITHUB_TOKEN"
+ return 1
+ fi
openim::log::info "create a new github release with tag ${OPENIM_GIT_VERSION}"
- github-release release \
+ ${TOOLS_DIR}/github-release release \
--user ${OPENIM_GITHUB_ORG} \
--repo ${OPENIM_GITHUB_REPO} \
--tag ${OPENIM_GIT_VERSION} \
--description "" \
- --pre-release
+ --pre-release \
+ --draft
# update openim tarballs
openim::log::info "upload ${ARTIFACT} to release ${OPENIM_GIT_VERSION}"
- github-release upload \
+ ${TOOLS_DIR}/github-release upload \
--user ${OPENIM_GITHUB_ORG} \
--repo ${OPENIM_GITHUB_REPO} \
--tag ${OPENIM_GIT_VERSION} \
--name ${ARTIFACT} \
+ --label "openim-${OPENIM_GIT_VERSION}" \
--file ${RELEASE_TARS}/${ARTIFACT}
- openim::log::info "upload openim-src.tar.gz to release ${OPENIM_GIT_VERSION}"
- github-release upload \
- --user ${OPENIM_GITHUB_ORG} \
- --repo ${OPENIM_GITHUB_REPO} \
- --tag ${OPENIM_GIT_VERSION} \
- --name "openim-src.tar.gz" \
- --file ${RELEASE_TARS}/openim-src.tar.gz
+ for file in ${RELEASE_TARS}/*.tar.gz; do
+ if [[ -f "$file" ]]; then
+ filename=$(basename "$file")
+ openim::log::info "Update file ${filename} to release vertion ${OPENIM_GIT_VERSION}"
+ ${TOOLS_DIR}/github-release upload \
+ --user ${OPENIM_GITHUB_ORG} \
+ --repo ${OPENIM_GITHUB_REPO} \
+ --tag ${OPENIM_GIT_VERSION} \
+ --name "${filename}" \
+ --file "${file}"
+ fi
+ done
}
function openim::release::generate_changelog() {
openim::log::info "generate CHANGELOG-${OPENIM_GIT_VERSION#v}.md and commit it"
- git-chglog ${OPENIM_GIT_VERSION} > "${OPENIM_ROOT}"/CHANGELOG/CHANGELOG-${OPENIM_GIT_VERSION#v}.md
+ local major_version=$(echo ${OPENIM_GIT_VERSION} | cut -d '+' -f 1)
+
+ ${TOOLS_DIR}/git-chglog --config ${OPENIM_ROOT}/CHANGELOG/.chglog/config.yml ${OPENIM_GIT_VERSION} > ${OPENIM_ROOT}/CHANGELOG/CHANGELOG-${major_version#v}.md
set +o errexit
- git add "${OPENIM_ROOT}"/CHANGELOG/CHANGELOG-${OPENIM_GIT_VERSION#v}.md
- git commit -a -m "docs(changelog): add CHANGELOG-${OPENIM_GIT_VERSION#v}.md"
- git push -f origin main # 最后将 CHANGELOG 也 push 上去
+ git add "${OPENIM_ROOT}"/CHANGELOG/CHANGELOG-${major_version#v}.md
+ git commit -a -m "docs(changelog): add CHANGELOG-${major_version#v}.md"
+ echo ""
+ echo "##########################################################################"
+ echo "git commit -a -m \"docs(changelog): add CHANGELOG-${major_version#v}.md\""
+ openim::log::info "You need git push CHANGELOG-${major_version#v}.md to remote"
+ echo "##########################################################################"
+ echo ""
}
diff --git a/scripts/lib/util.sh b/scripts/lib/util.sh
index 4de240972..1ec722d8f 100755
--- a/scripts/lib/util.sh
+++ b/scripts/lib/util.sh
@@ -301,29 +301,1275 @@ openim::util::check_ports() {
openim::log::info "Checking ports: $*"
# Iterate over each given port.
for port in "$@"; do
- # Use the `ss` command to find process information related to the given port.
- if command -v ss > /dev/null 2>&1; then
- info=$(ss -ltnp | grep ":$port" || true)
+ # Initialize variables
+ # Check the OS and use the appropriate command
+ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
+ if command -v ss > /dev/null 2>&1; then
+ info=$(ss -ltnp | grep ":$port" || true)
+ else
+ info=$(netstat -ltnp | grep ":$port" || true)
+ fi
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
+ # For macOS, use lsof
+ info=$(lsof -i:"$port" | grep "\*:$port" || true)
+ fi
+
+ # Check if any process is using the port
+ if [[ -z $info ]]; then
+ not_started+=($port)
+ else
+ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
+ # Extract relevant details for Linux: Process Name, PID, and FD.
+ details=$(echo $info | sed -n 's/.*users:(("\([^"]*\)",pid=\([^,]*\),fd=\([^)]*\))).*/\1 \2 \3/p')
+ command=$(echo $details | awk '{print $1}')
+ pid=$(echo $details | awk '{print $2}')
+ fd=$(echo $details | awk '{print $3}')
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
+ # Handle extraction for macOS
+ pid=$(echo $info | awk '{print $2}' | cut -d'/' -f1)
+ command=$(ps -p $pid -o comm= | xargs basename)
+ fd=$(echo $info | awk '{print $4}' | cut -d'/' -f1)
+ fi
+
+ # Get the start time of the process using the PID
+ if [[ -z $pid ]]; then
+ start_time="N/A"
+ else
+ start_time=$(ps -p $pid -o lstart=)
+ fi
+
+ started+=("Port $port - Command: $command, PID: $pid, FD: $fd, Started: $start_time")
+ fi
+ done
+
+ # Print information about ports whose processes are not running.
+ if [[ ${#not_started[@]} -ne 0 ]]; then
+ openim::log::info "\n### Not started ports:"
+ for port in "${not_started[@]}"; do
+ openim::log::error "Port $port is not started."
+ done
+ fi
+
+ # Print information about ports whose processes are running.
+ if [[ ${#started[@]} -ne 0 ]]; then
+ openim::log::info "\n### Started ports:"
+ for info in "${started[@]}"; do
+ openim::log::info "$info"
+ done
+ fi
+
+ # If any of the processes is not running, return a status of 1.
+ if [[ ${#not_started[@]} -ne 0 ]]; then
+ echo "++++ OpenIM Log >> cat ${LOG_FILE}"
+ return 1
+ else
+ openim::log::success "All specified processes are running."
+ return 0
+ fi
+}
+
+# set +o errexit
+# Sample call for testing:
+# openim::util::check_ports 10002 1004 12345 13306
+# set -o errexit
+
+# The `openim::util::check_process_names` function analyzes the state of processes based on given names.
+# It accepts multiple process names as arguments and prints:
+# 1. The state of the process (whether it's running or not).
+# 2. The start time of the process if it's running.
+# User:
+# openim::util::check_process_names nginx mysql redis
+# The function returns a status of 1 if any of the processes is not running.
+openim::util::check_process_names() {
+ # Function to get the port of a process
+ get_port() {
+ local pid=$1
+ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
+ # Linux
+ ss -ltnp 2>/dev/null | grep $pid | awk '{print $4}' | cut -d ':' -f2
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
+ # macOS
+ lsof -nP -iTCP -sTCP:LISTEN -a -p $pid | awk 'NR>1 {print $9}' | sed 's/.*://'
+ else
+ echo "Unsupported OS"
+ return 1
+ fi
+ }
+
+ # Arrays to collect details of processes
+ local not_started=()
+ local started=()
+
+ openim::log::info "Checking processes: $*"
+ # Iterate over each given process name
+ for process_name in "$@"; do
+ # Use `pgrep` to find process IDs related to the given process name
+ local pids=($(pgrep -f $process_name))
+
+ # Check if any process IDs were found
+ if [[ ${#pids[@]} -eq 0 ]]; then
+ not_started+=($process_name)
+ else
+ # If there are PIDs, loop through each one
+ for pid in "${pids[@]}"; do
+ local command=$(ps -p $pid -o cmd=)
+ local start_time=$(ps -p $pid -o lstart=)
+ local port=$(get_port $pid)
+
+ # Check if port information was found for the PID
+ if [[ -z $port ]]; then
+ port="N/A"
+ fi
+
+ started+=("Process $process_name - Command: $command, PID: $pid, Port: $port, Start time: $start_time")
+ done
+ fi
+ done
+
+ # Print information
+ if [[ ${#not_started[@]} -ne 0 ]]; then
+ openim::log::info "Not started processes:"
+ for process_name in "${not_started[@]}"; do
+ openim::log::error "Process $process_name is not started."
+ done
+ fi
+
+ if [[ ${#started[@]} -ne 0 ]]; then
+ echo
+ openim::log::info "Started processes:"
+ for info in "${started[@]}"; do
+ openim::log::info "$info"
+ done
+ fi
+
+ # Return status
+ if [[ ${#not_started[@]} -ne 0 ]]; then
+ echo "++++ OpenIM Log >> cat ${LOG_FILE}"
+ return 1
+ else
+ openim::log::success "All processes are running."
+ return 0
+ fi
+}
+
+# openim::util::check_process_names docker-pr
+
+# The `openim::util::stop_services_on_ports` function stops services running on specified ports.
+# It accepts multiple ports as arguments and performs the following:
+# 1. Attempts to stop any services running on the specified ports.
+# 2. Prints details of services successfully stopped and those that failed to stop.
+# Usage:
+# openim::util::stop_services_on_ports 8080 8081 8082
+# The function returns a status of 1 if any service couldn't be stopped.
+openim::util::stop_services_on_ports() {
+ # An array to collect ports of processes that couldn't be stopped.
+ local not_stopped=()
+
+ # An array to collect information about processes that were stopped.
+ local stopped=()
+
+ openim::log::info "Stopping services on ports: $*"
+ # Iterate over each given port.
+ for port in "$@"; do
+ # Use the `lsof` command to find process information related to the given port.
+ info=$(lsof -i :$port -n -P | grep LISTEN || true)
+
+ # If there's process information, it means the process associated with the port is running.
+ if [[ -n $info ]]; then
+ # Extract the Process ID.
+ while read -r line; do
+ local pid=$(echo $line | awk '{print $2}')
+
+ # Try to stop the service by killing its process.
+ if kill -TERM $pid; then
+ stopped+=($port)
+ else
+ not_stopped+=($port)
+ fi
+ done <<< "$info"
+ fi
+ done
+
+ # Print information about ports whose processes couldn't be stopped.
+ if [[ ${#not_stopped[@]} -ne 0 ]]; then
+ openim::log::info "Ports that couldn't be stopped:"
+ for port in "${not_stopped[@]}"; do
+ openim::log::status "Failed to stop service on port $port."
+ done
+ fi
+
+ # Print information about ports whose processes were successfully stopped.
+ if [[ ${#stopped[@]} -ne 0 ]]; then
+ echo
+ openim::log::info "Stopped services on ports:"
+ for port in "${stopped[@]}"; do
+ openim::log::info "Successfully stopped service on port $port."
+ done
+ fi
+
+ # If any of the processes couldn't be stopped, return a status of 1.
+ if [[ ${#not_stopped[@]} -ne 0 ]]; then
+ return 1
+ else
+ openim::log::success "All specified services were stopped."
+ echo ""
+ return 0
+ fi
+}
+# nc -l -p 12345
+# nc -l -p 123456
+# ps -ef | grep "nc -l"
+# openim::util::stop_services_on_ports 1234 12345
+
+
+# The `openim::util::stop_services_with_name` function stops services with specified names.
+# It accepts multiple service names as arguments and performs the following:
+# 1. Attempts to stop any services with the specified names.
+# 2. Prints details of services successfully stopped and those that failed to stop.
+# Usage:
+# openim::util::stop_services_with_name nginx apache
+# The function returns a status of 1 if any service couldn't be stopped.
+openim::util::stop_services_with_name() {
+ # An array to collect names of processes that couldn't be stopped.
+ local not_stopped=()
+
+ # An array to collect information about processes that were stopped.
+ local stopped=()
+
+ openim::log::info "Stopping services with names: $*"
+ # Iterate over each given service name.
+ for server_name in "$@"; do
+ # Use the `pgrep` command to find process IDs related to the given service name.
+ local pids=$(pgrep -f "$server_name")
+
+ # If no process was found with the name, add it to the not_stopped list
+ if [[ -z $pids ]]; then
+ not_stopped+=("$server_name")
+ continue
+ fi
+ local stopped_this_time=false
+ for pid in $pids; do
+
+ # Exclude the PID of the current script
+ if [[ "$pid" == "$$" ]]; then
+ continue
+ fi
+
+ # If there's a Process ID, it means the service with the name is running.
+ if [[ -n $pid ]]; then
+ # Try to stop the service by killing its process.
+ if kill -TERM $pid 2>/dev/null; then
+ stopped_this_time=true
+ fi
+ fi
+ done
+
+ if $stopped_this_time; then
+ stopped+=("$server_name")
else
- info=$(netstat -ltnp | grep ":$port" || true)
+ not_stopped+=("$server_name")
+ fi
+ done
+
+ # Print information about services whose processes couldn't be stopped.
+ if [[ ${#not_stopped[@]} -ne 0 ]]; then
+ openim::log::info "Services that couldn't be stopped:"
+ for name in "${not_stopped[@]}"; do
+ openim::log::status "Failed to stop the $name service."
+ done
+ fi
+
+ # Print information about services whose processes were successfully stopped.
+ if [[ ${#stopped[@]} -ne 0 ]]; then
+ echo
+ openim::log::info "Stopped services:"
+ for name in "${stopped[@]}"; do
+ openim::log::info "Successfully stopped the $name service."
+ done
+ fi
+
+ openim::log::success "All specified services were stopped."
+ echo ""
+}
+# sleep 333333&
+# sleep 444444&
+# ps -ef | grep "sleep"
+# openim::util::stop_services_with_name "sleep 333333" "sleep 444444"
+
+# This figures out the host platform without relying on golang. We need this as
+# we don't want a golang install to be a prerequisite to building yet we need
+# this info to figure out where the final binaries are placed.
+openim::util::host_platform() {
+ echo "$(openim::util::host_os)/$(openim::util::host_arch)"
+}
+
+# looks for $1 in well-known output locations for the platform ($2)
+# $OPENIM_ROOT must be set
+openim::util::find-binary-for-platform() {
+ local -r lookfor="$1"
+ local -r platform="$2"
+ local locations=(
+ "${OPENIM_ROOT}/_output/bin/${lookfor}"
+ "${OPENIM_ROOT}/_output/${platform}/${lookfor}"
+ "${OPENIM_ROOT}/_output/local/bin/${platform}/${lookfor}"
+ "${OPENIM_ROOT}/_output/platforms/${platform}/${lookfor}"
+ "${OPENIM_ROOT}/_output/platforms/bin/${platform}/${lookfor}"
+ )
+
+ # List most recently-updated location.
+ local -r bin=$( (ls -t "${locations[@]}" 2>/dev/null || true) | head -1 )
+ echo -n "${bin}"
+}
+
+# looks for $1 in well-known output locations for the host platform
+# $OPENIM_ROOT must be set
+openim::util::find-binary() {
+ openim::util::find-binary-for-platform "$1" "$(openim::util::host_platform)"
+}
+
+# Run all known doc generators (today gendocs and genman for openimctl)
+# $1 is the directory to put those generated documents
+openim::util::gen-docs() {
+ local dest="$1"
+
+ # Find binary
+ gendocs=$(openim::util::find-binary "gendocs")
+ genopenimdocs=$(openim::util::find-binary "genopenimdocs")
+ genman=$(openim::util::find-binary "genman")
+ genyaml=$(openim::util::find-binary "genyaml")
+ genfeddocs=$(openim::util::find-binary "genfeddocs")
+
+ # TODO: If ${genfeddocs} is not used from anywhere (it isn't used at
+ # least from k/k tree), remove it completely.
+ openim::util::sourced_variable "${genfeddocs}"
+
+ mkdir -p "${dest}/docs/guide/en-US/cmd/openimctl/"
+ "${gendocs}" "${dest}/docs/guide/en-US/cmd/openimctl/"
+
+ mkdir -p "${dest}/docs/guide/en-US/cmd/"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-api"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-cmdutils"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-crontask"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-msggateway"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-msgtransfer"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-push"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-auth"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-conversation"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-friend"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-group"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-msg"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-third"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-user"
+ "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/openimctl" "openimctl"
+
+ mkdir -p "${dest}/docs/man/man1/"
+"${genman}" "${dest}/docs/man/man1/" "openim-api"
+"${genman}" "${dest}/docs/man/man1/" "openim-cmdutils"
+"${genman}" "${dest}/docs/man/man1/" "openim-crontask"
+"${genman}" "${dest}/docs/man/man1/" "openim-msggateway"
+"${genman}" "${dest}/docs/man/man1/" "openim-msgtransfer"
+"${genman}" "${dest}/docs/man/man1/" "openim-push"
+"${genman}" "${dest}/docs/man/man1/" "openim-rpc-auth"
+"${genman}" "${dest}/docs/man/man1/" "openim-rpc-conversation"
+"${genman}" "${dest}/docs/man/man1/" "openim-rpc-friend"
+"${genman}" "${dest}/docs/man/man1/" "openim-rpc-group"
+"${genman}" "${dest}/docs/man/man1/" "openim-rpc-msg"
+"${genman}" "${dest}/docs/man/man1/" "openim-rpc-third"
+"${genman}" "${dest}/docs/man/man1/" "openim-rpc-user"
+
+ mkdir -p "${dest}/docs/guide/en-US/yaml/openimctl/"
+ "${genyaml}" "${dest}/docs/guide/en-US/yaml/openimctl/"
+
+ # create the list of generated files
+ pushd "${dest}" > /dev/null || return 1
+ touch docs/.generated_docs
+ find . -type f | cut -sd / -f 2- | LC_ALL=C sort > docs/.generated_docs
+ popd > /dev/null || return 1
+}
+
+# Removes previously generated docs-- we don't want to check them in. $OPENIM_ROOT
+# must be set.
+openim::util::remove-gen-docs() {
+ if [ -e "${OPENIM_ROOT}/docs/.generated_docs" ]; then
+ # remove all of the old docs; we don't want to check them in.
+ while read -r file; do
+ rm "${OPENIM_ROOT}/${file}" 2>/dev/null || true
+ done <"${OPENIM_ROOT}/docs/.generated_docs"
+ # The docs/.generated_docs file lists itself, so we don't need to explicitly
+ # delete it.
+ fi
+}
+
+# Returns the name of the upstream remote repository name for the local git
+# repo, e.g. "upstream" or "origin".
+openim::util::git_upstream_remote_name() {
+ git remote -v | grep fetch |\
+ grep -E 'github.com[/:]openimsdk/open-im-server|openim.cc/server' |\
+ head -n 1 | awk '{print $1}'
+}
+
+# Exits script if working directory is dirty. If it's run interactively in the terminal
+# the user can commit changes in a second terminal. This script will wait.
+openim::util::ensure_clean_working_dir() {
+ while ! git diff HEAD --exit-code &>/dev/null; do
+ echo -e "\nUnexpected dirty working directory:\n"
+ if tty -s; then
+ git status -s
+ else
+ git diff -a # be more verbose in log files without tty
+ exit 1
+ fi | sed 's/^/ /'
+ echo -e "\nCommit your changes in another terminal and then continue here by pressing enter."
+ read -r
+ done 1>&2
+}
+
+# Find the base commit using:
+# $PULL_BASE_SHA if set (from Prow)
+# current ref from the remote upstream branch
+openim::util::base_ref() {
+ local -r git_branch=$1
+
+ if [[ -n ${PULL_BASE_SHA:-} ]]; then
+ echo "${PULL_BASE_SHA}"
+ return
+ fi
+
+ full_branch="$(openim::util::git_upstream_remote_name)/${git_branch}"
+
+ # make sure the branch is valid, otherwise the check will pass erroneously.
+ if ! git describe "${full_branch}" >/dev/null; then
+ # abort!
+ exit 1
+ fi
+
+ echo "${full_branch}"
+}
+
+# Checks whether there are any files matching pattern $2 changed between the
+# current branch and upstream branch named by $1.
+# Returns 1 (false) if there are no changes
+# 0 (true) if there are changes detected.
+openim::util::has_changes() {
+ local -r git_branch=$1
+ local -r pattern=$2
+ local -r not_pattern=${3:-totallyimpossiblepattern}
+
+ local base_ref
+ base_ref=$(openim::util::base_ref "${git_branch}")
+ echo "Checking for '${pattern}' changes against '${base_ref}'"
+
+ # notice this uses ... to find the first shared ancestor
+ if git diff --name-only "${base_ref}...HEAD" | grep -v -E "${not_pattern}" | grep "${pattern}" > /dev/null; then
+ return 0
+ fi
+ # also check for pending changes
+ if git status --porcelain | grep -v -E "${not_pattern}" | grep "${pattern}" > /dev/null; then
+ echo "Detected '${pattern}' uncommitted changes."
+ return 0
+ fi
+ echo "No '${pattern}' changes detected."
+ return 1
+}
+
+openim::util::download_file() {
+ local -r url=$1
+ local -r destination_file=$2
+
+ rm "${destination_file}" 2&> /dev/null || true
+
+ for i in $(seq 5)
+ do
+ if ! curl -fsSL --retry 3 --keepalive-time 2 "${url}" -o "${destination_file}"; then
+ echo "Downloading ${url} failed. $((5-i)) retries left."
+ sleep 1
+ else
+ echo "Downloading ${url} succeed"
+ return 0
+ fi
+ done
+ return 1
+}
+
+# Test whether openssl is installed.
+# Sets:
+# OPENSSL_BIN: The path to the openssl binary to use
+function openim::util::test_openssl_installed {
+ if ! openssl version >& /dev/null; then
+ echo "Failed to run openssl. Please ensure openssl is installed"
+ exit 1
+ fi
+
+ OPENSSL_BIN=$(command -v openssl)
+}
+
+# creates a client CA, args are sudo, dest-dir, ca-id, purpose
+# purpose is dropped in after "key encipherment", you usually want
+# '"client auth"'
+# '"server auth"'
+# '"client auth","server auth"'
+function openim::util::create_signing_certkey {
+ local sudo=$1
+ local dest_dir=$2
+ local id=$3
+ local purpose=$4
+ # Create client ca
+ ${sudo} /usr/bin/env bash -e < "${dest_dir}/${id}-ca-config.json"
+EOF
+}
+
+# signs a client certificate: args are sudo, dest-dir, CA, filename (roughly), username, groups...
+function openim::util::create_client_certkey {
+ local sudo=$1
+ local dest_dir=$2
+ local ca=$3
+ local id=$4
+ local cn=${5:-$4}
+ local groups=""
+ local SEP=""
+ shift 5
+ while [ -n "${1:-}" ]; do
+ groups+="${SEP}{\"O\":\"$1\"}"
+ SEP=","
+ shift 1
+ done
+ ${sudo} /usr/bin/env bash -e < /dev/null
+apiVersion: v1
+kind: Config
+clusters:
+ - cluster:
+ certificate-authority: ${ca_file}
+ server: https://${api_host}:${api_port}/
+ name: local-up-cluster
+users:
+ - user:
+ token: ${token}
+ client-certificate: ${dest_dir}/client-${client_id}.crt
+ client-key: ${dest_dir}/client-${client_id}.key
+ name: local-up-cluster
+contexts:
+ - context:
+ cluster: local-up-cluster
+ user: local-up-cluster
+ name: local-up-cluster
+current-context: local-up-cluster
+EOF
+
+ # flatten the openimconfig files to make them self contained
+ username=$(whoami)
+ ${sudo} /usr/bin/env bash -e < "/tmp/${client_id}.openimconfig"
+ mv -f "/tmp/${client_id}.openimconfig" "${dest_dir}/${client_id}.openimconfig"
+ chown ${username} "${dest_dir}/${client_id}.openimconfig"
+EOF
+}
+
+# Determines if docker can be run, failures may simply require that the user be added to the docker group.
+function openim::util::ensure_docker_daemon_connectivity {
+ IFS=" " read -ra DOCKER <<< "${DOCKER_OPTS}"
+ # Expand ${DOCKER[@]} only if it's not unset. This is to work around
+ # Bash 3 issue with unbound variable.
+ DOCKER=(docker ${DOCKER[@]:+"${DOCKER[@]}"})
+ if ! "${DOCKER[@]}" info > /dev/null 2>&1 ; then
+ cat <<'EOF' >&2
+Can't connect to 'docker' daemon. please fix and retry.
+
+Possible causes:
+ - Docker Daemon not started
+ - Linux: confirm via your init system
+ - macOS w/ docker-machine: run `docker-machine ls` and `docker-machine start `
+ - macOS w/ Docker for Mac: Check the menu bar and start the Docker application
+ - DOCKER_HOST hasn't been set or is set incorrectly
+ - Linux: domain socket is used, DOCKER_* should be unset. In Bash run `unset ${!DOCKER_*}`
+ - macOS w/ docker-machine: run `eval "$(docker-machine env )"`
+ - macOS w/ Docker for Mac: domain socket is used, DOCKER_* should be unset. In Bash run `unset ${!DOCKER_*}`
+ - Other things to check:
+ - Linux: User isn't in 'docker' group. Add and relogin.
+ - Something like 'sudo usermod -a -G docker ${USER}'
+ - RHEL7 bug and workaround: https://bugzilla.redhat.com/show_bug.cgi?id=1119282#c8
+EOF
+ return 1
+ fi
+}
+
+# Wait for background jobs to finish. Return with
+# an error status if any of the jobs failed.
+openim::util::wait-for-jobs() {
+ local fail=0
+ local job
+ for job in $(jobs -p); do
+ wait "${job}" || fail=$((fail + 1))
+ done
+ return ${fail}
+}
+
+# openim::util::join
+# Concatenates the list elements with the delimiter passed as first parameter
+#
+# Ex: openim::util::join , a b c
+# -> a,b,c
+function openim::util::join {
+ local IFS="$1"
+ shift
+ echo "$*"
+}
+
+# Function: openim::util::list-to-string
+# Description: Converts a list to a string, removing spaces, brackets, and commas.
+# Example input: [1002 3 , 2 32 3 , 3 434 ,]
+# Example output: 10023 2323 3434
+# Example usage:
+# result=$(openim::util::list-to-string "[10023, 2323, 3434]")
+# echo $result
+function openim::util::list-to-string() {
+ # Capture all arguments into a single string
+ ports_list="$*"
+
+ # Use sed for transformations:
+ # 1. Remove spaces
+ # 2. Replace commas with spaces
+ # 3. Remove opening and closing brackets
+ ports_array=$(echo "$ports_list" | sed 's/ //g; s/,/ /g; s/^\[\(.*\)\]$/\1/')
+ # For external use, we might want to echo the result so that it can be captured by callers
+ echo "$ports_array"
+}
+# MSG_GATEWAY_PROM_PORTS=$(openim::util::list-to-string "10023, 2323, 34 34")
+# read -a MSG_GATEWAY_PROM_PORTS <<< $(openim::util::list-to-string "10023, 2323, 34 34")
+# echo ${MSG_GATEWAY_PROM_PORTS}
+# echo "${#MSG_GATEWAY_PROM_PORTS[@]}"
+# Downloads cfssl/cfssljson/cfssl-certinfo into $1 directory if they do not already exist in PATH
+#
+# Assumed vars:
+# $1 (cfssl directory) (optional)
+#
+# Sets:
+# CFSSL_BIN: The path of the installed cfssl binary
+# CFSSLJSON_BIN: The path of the installed cfssljson binary
+# CFSSLCERTINFO_BIN: The path of the installed cfssl-certinfo binary
+#
+function openim::util::ensure-cfssl {
+ if command -v cfssl &>/dev/null && command -v cfssljson &>/dev/null && command -v cfssl-certinfo &>/dev/null; then
+ CFSSL_BIN=$(command -v cfssl)
+ CFSSLJSON_BIN=$(command -v cfssljson)
+ CFSSLCERTINFO_BIN=$(command -v cfssl-certinfo)
+ return 0
+ fi
+
+ host_arch=$(openim::util::host_arch)
+
+ if [[ "${host_arch}" != "amd64" ]]; then
+ echo "Cannot download cfssl on non-amd64 hosts and cfssl does not appear to be installed."
+ echo "Please install cfssl, cfssljson and cfssl-certinfo and verify they are in \$PATH."
+ echo "Hint: export PATH=\$PATH:\$GOPATH/bin; go get -u github.com/cloudflare/cfssl/cmd/..."
+ exit 1
+ fi
+
+ # Create a temp dir for cfssl if no directory was given
+ local cfssldir=${1:-}
+ if [[ -z "${cfssldir}" ]]; then
+ cfssldir="$HOME/bin"
+ fi
+
+ mkdir -p "${cfssldir}"
+ pushd "${cfssldir}" > /dev/null || return 1
+
+ echo "Unable to successfully run 'cfssl' from ${PATH}; downloading instead..."
+ kernel=$(uname -s)
+ case "${kernel}" in
+ Linux)
+ curl --retry 10 -L -o cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
+ curl --retry 10 -L -o cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
+ curl --retry 10 -L -o cfssl-certinfo https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
+ ;;
+ Darwin)
+ curl --retry 10 -L -o cfssl https://pkg.cfssl.org/R1.2/cfssl_darwin-amd64
+ curl --retry 10 -L -o cfssljson https://pkg.cfssl.org/R1.2/cfssljson_darwin-amd64
+ curl --retry 10 -L -o cfssl-certinfo https://pkg.cfssl.org/R1.2/cfssl-certinfo_darwin-amd64
+ ;;
+ *)
+ echo "Unknown, unsupported platform: ${kernel}." >&2
+ echo "Supported platforms: Linux, Darwin." >&2
+ exit 2
+ esac
+
+ chmod +x cfssl || true
+ chmod +x cfssljson || true
+ chmod +x cfssl-certinfo || true
+
+ CFSSL_BIN="${cfssldir}/cfssl"
+ CFSSLJSON_BIN="${cfssldir}/cfssljson"
+ CFSSLCERTINFO_BIN="${cfssldir}/cfssl-certinfo"
+ if [[ ! -x ${CFSSL_BIN} || ! -x ${CFSSLJSON_BIN} || ! -x ${CFSSLCERTINFO_BIN} ]]; then
+ echo "Failed to download 'cfssl'."
+ echo "Please install cfssl, cfssljson and cfssl-certinfo and verify they are in \$PATH."
+ echo "Hint: export PATH=\$PATH:\$GOPATH/bin; go get -u github.com/cloudflare/cfssl/cmd/..."
+ exit 1
+ fi
+ popd > /dev/null || return 1
+}
+
+function openim::util::ensure-docker-buildx {
+ # podman returns 0 on `docker buildx version`, docker on `docker buildx`. One of them must succeed.
+ if docker buildx version >/dev/null 2>&1 || docker buildx >/dev/null 2>&1; then
+ return 0
+ else
+ echo "ERROR: docker buildx not available. Docker 19.03 or higher is required with experimental features enabled"
+ exit 1
+ fi
+}
+
+# openim::util::ensure-bash-version
+# Check if we are using a supported bash version
+#
+function openim::util::ensure-bash-version {
+ # shellcheck disable=SC2004
+ if ((${BASH_VERSINFO[0]}<4)) || ( ((${BASH_VERSINFO[0]}==4)) && ((${BASH_VERSINFO[1]}<2)) ); then
+ echo "ERROR: This script requires a minimum bash version of 4.2, but got version of ${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}"
+ if [ "$(uname)" = 'Darwin' ]; then
+ echo "On macOS with homebrew 'brew install bash' is sufficient."
+ fi
+ exit 1
+ fi
+}
+
+# openim::util::ensure-install-nginx
+# Check if nginx is installed
+#
+function openim::util::ensure-install-nginx {
+ if ! command -v nginx &>/dev/null; then
+ echo "ERROR: nginx not found. Please install nginx."
+ exit 1
+ fi
+
+ for port in 80
+ do
+ if echo |telnet 127.0.0.1 $port 2>&1|grep refused &>/dev/null;then
+ exit 1
+ fi
+ done
+}
+
+# openim::util::ensure-gnu-sed
+# Determines which sed binary is gnu-sed on linux/darwin
+#
+# Sets:
+# SED: The name of the gnu-sed binary
+#
+function openim::util::ensure-gnu-sed {
+ # NOTE: the echo below is a workaround to ensure sed is executed before the grep.
+ # see: https://github.com/openimrnetes/openimrnetes/issues/87251
+ sed_help="$(LANG=C sed --help 2>&1 || true)"
+ if echo "${sed_help}" | grep -q "GNU\|BusyBox"; then
+ SED="sed"
+ elif command -v gsed &>/dev/null; then
+ SED="gsed"
+ else
+ openim::log::error "Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed." >&2
+ return 1
+ fi
+ openim::util::sourced_variable "${SED}"
+}
+
+# openim::util::ensure-gnu-date
+# Determines which date binary is gnu-date on linux/darwin
+#
+# Sets:
+# DATE: The name of the gnu-date binary
+#
+function openim::util::ensure-gnu-date {
+ # NOTE: the echo below is a workaround to ensure date is executed before the grep.
+ date_help="$(LANG=C date --help 2>&1 || true)"
+ if echo "${date_help}" | grep -q "GNU\|BusyBox"; then
+ DATE="date"
+ elif command -v gdate &>/dev/null; then
+ DATE="gdate"
+ else
+ openim::log::error "Failed to find GNU date as date or gdate. If you are on Mac: brew install coreutils." >&2
+ return 1
+ fi
+ openim::util::sourced_variable "${DATE}"
+}
+
+# openim::util::check-file-in-alphabetical-order
+# Check that the file is in alphabetical order
+#
+function openim::util::check-file-in-alphabetical-order {
+ local failure_file="$1"
+ if ! diff -u "${failure_file}" <(LC_ALL=C sort "${failure_file}"); then
+ {
+ echo
+ echo "${failure_file} is not in alphabetical order. Please sort it:"
+ echo
+ echo " LC_ALL=C sort -o ${failure_file} ${failure_file}"
+ echo
+ } >&2
+ false
+ fi
+}
+
+# openim::util::require-jq
+# Checks whether jq is installed.
+function openim::util::require-jq {
+ if ! command -v jq &>/dev/null; then
+ openim::log::errexit "jq not found. Please install." 1>&2
+ fi
+}
+
+# openim::util::require-dig
+# Checks whether dig is installed and provides installation instructions if it is not.
+function openim::util::require-dig {
+ if ! command -v dig &>/dev/null; then
+ openim::log::error "Please install 'dig' to use this feature. OR Set the environment variable for OPENIM_IP"
+ openim::log::error "Installation instructions:"
+ openim::log::error " For Ubuntu/Debian: sudo apt-get install dnsutils"
+ openim::log::error " For CentOS/RedHat: sudo yum install bind-utils"
+ openim::log::error " For macOS: 'dig' should be preinstalled. If missing, try: brew install bind"
+ openim::log::error " For Windows: Install BIND9 tools from https://www.isc.org/download/"
+ openim::log::error_exit "dig command not found."
+ fi
+ return 0
+}
+
+# outputs md5 hash of $1, works on macOS and Linux
+function openim::util::md5() {
+ if which md5 >/dev/null 2>&1; then
+ md5 -q "$1"
+ else
+ md5sum "$1" | awk '{ print $1 }'
+ fi
+}
+
+# openim::util::read-array
+# Reads in stdin and adds it line by line to the array provided. This can be
+# used instead of "mapfile -t", and is bash 3 compatible.
+#
+# Assumed vars:
+# $1 (name of array to create/modify)
+#
+# Example usage:
+# openim::util::read-array files < <(ls -1)
+#
+function openim::util::read-array {
+ local i=0
+ unset -v "$1"
+ while IFS= read -r "$1[i++]"; do :; done
+ eval "[[ \${$1[--i]} ]]" || unset "$1[i]" # ensures last element isn't empty
+}
+
+# Some useful colors.
+if [[ -z "${color_start-}" ]]; then
+ declare -r color_start="\033["
+ declare -r color_red="${color_start}0;31m"
+ declare -r color_yellow="${color_start}0;33m"
+ declare -r color_green="${color_start}0;32m"
+ declare -r color_blue="${color_start}1;34m"
+ declare -r color_cyan="${color_start}1;36m"
+ declare -r color_norm="${color_start}0m"
+
+ openim::util::sourced_variable "${color_start}"
+ openim::util::sourced_variable "${color_red}"
+ openim::util::sourced_variable "${color_yellow}"
+ openim::util::sourced_variable "${color_green}"
+ openim::util::sourced_variable "${color_blue}"
+ openim::util::sourced_variable "${color_cyan}"
+ openim::util::sourced_variable "${color_norm}"
+fi
+
+# ex: ts=2 sw=2 et filetype=sh
+
+function openim::util::desc() {
+ openim::util:run::maybe_first_prompt
+ rate=25
+ if [ -n "$DEMO_RUN_FAST" ]; then
+ rate=1000
+ fi
+ echo "$blue# $@$reset" | pv -qL $rate#!/usr/bin/env bash
+# Copyright © 2023 OpenIM. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
+# this script is used to check whether the code is formatted by gofmt or not
+#
+# Usage: source scripts/lib/util.sh
+################################################################################
+
+# TODO Debug: Just for testing, please comment out
+# OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P)
+# source "${OPENIM_ROOT}/scripts/lib/logging.sh"
+
+#1、将IP写在一个文件里,比如文件名为hosts_file,一行一个IP地址。
+#2、修改ssh-mutual-trust.sh里面的用户名及密码,默认为root用户及密码123。
+# hosts_file_path="path/to/your/hosts/file"
+# openim:util::setup_ssh_key_copy "$hosts_file_path" "root" "123"
+function openim:util::setup_ssh_key_copy() {
+ local hosts_file="$1"
+ local username="${2:-root}"
+ local password="${3:-123}"
+
+ local sshkey_file=~/.ssh/id_rsa.pub
+
+ # check sshkey file
+ if [[ ! -e $sshkey_file ]]; then
+ expect -c "
+ spawn ssh-keygen -t rsa
+ expect \"Enter*\" { send \"\n\"; exp_continue; }
+ "
+ fi
+
+ # get hosts list
+ local hosts=$(awk '/^[^#]/ {print $1}' "${hosts_file}")
+
+ ssh_key_copy() {
+ local target=$1
+
+ # delete history
+ sed -i "/$target/d" ~/.ssh/known_hosts
+
+ # copy key
+ expect -c "
+ set timeout 100
+ spawn ssh-copy-id $username@$target
+ expect {
+ \"yes/no\" { send \"yes\n\"; exp_continue; }
+ \"*assword\" { send \"$password\n\"; }
+ \"already exist on the remote system\" { exit 1; }
+ }
+ expect eof
+ "
+ }
+
+ # auto sshkey pair
+ for host in $hosts; do
+ if ! ping -i 0.2 -c 3 -W 1 "$host" > /dev/null 2>&1; then
+ echo "[ERROR]: Can't connect $host"
+ continue
+ fi
+
+ local host_entry=$(awk "/$host/"'{print $1, $2}' /etc/hosts)
+ if [[ $host_entry ]]; then
+ local hostaddr=$(echo "$host_entry" | awk '{print $1}')
+ local hostname=$(echo "$host_entry" | awk '{print $2}')
+ ssh_key_copy "$hostaddr"
+ ssh_key_copy "$hostname"
+ else
+ ssh_key_copy "$host"
+ fi
+ done
+}
+
+function openim::util::sourced_variable {
+ # Call this function to tell shellcheck that a variable is supposed to
+ # be used from other calling context. This helps quiet an "unused
+ # variable" warning from shellcheck and also document your code.
+ true
+}
+
+openim::util::sortable_date() {
+ date "+%Y%m%d-%H%M%S"
+}
+
+# arguments: target, item1, item2, item3, ...
+# returns 0 if target is in the given items, 1 otherwise.
+openim::util::array_contains() {
+ local search="$1"
+ local element
+ shift
+ for element; do
+ if [[ "${element}" == "${search}" ]]; then
+ return 0
+ fi
+ done
+ return 1
+}
+
+openim::util::wait_for_url() {
+ local url=$1
+ local prefix=${2:-}
+ local wait=${3:-1}
+ local times=${4:-30}
+ local maxtime=${5:-1}
+
+ command -v curl >/dev/null || {
+ openim::log::usage "curl must be installed"
+ exit 1
+ }
+
+ local i
+ for i in $(seq 1 "${times}"); do
+ local out
+ if out=$(curl --max-time "${maxtime}" -gkfs "${url}" 2>/dev/null); then
+ openim::log::status "On try ${i}, ${prefix}: ${out}"
+ return 0
+ fi
+ sleep "${wait}"
+ done
+ openim::log::error "Timed out waiting for ${prefix} to answer at ${url}; tried ${times} waiting ${wait} between each"
+ return 1
+}
+
+# Example: openim::util::wait_for_success 120 5 "openimctl get nodes|grep localhost"
+# arguments: wait time, sleep time, shell command
+# returns 0 if the shell command get output, 1 otherwise.
+openim::util::wait_for_success(){
+ local wait_time="$1"
+ local sleep_time="$2"
+ local cmd="$3"
+ while [ "$wait_time" -gt 0 ]; do
+ if eval "$cmd"; then
+ return 0
+ else
+ sleep "$sleep_time"
+ wait_time=$((wait_time-sleep_time))
+ fi
+ done
+ return 1
+}
+
+# Example: openim::util::trap_add 'echo "in trap DEBUG"' DEBUG
+# See: http://stackoverflow.com/questions/3338030/multiple-bash-traps-for-the-same-signal
+openim::util::trap_add() {
+ local trap_add_cmd
+ trap_add_cmd=$1
+ shift
+
+ for trap_add_name in "$@"; do
+ local existing_cmd
+ local new_cmd
+
+ # Grab the currently defined trap commands for this trap
+ existing_cmd=$(trap -p "${trap_add_name}" | awk -F"'" '{print $2}')
+
+ if [[ -z "${existing_cmd}" ]]; then
+ new_cmd="${trap_add_cmd}"
+ else
+ new_cmd="${trap_add_cmd};${existing_cmd}"
+ fi
+
+ # Assign the test. Disable the shellcheck warning telling that trap
+ # commands should be single quoted to avoid evaluating them at this
+ # point instead evaluating them at run time. The logic of adding new
+ # commands to a single trap requires them to be evaluated right away.
+ # shellcheck disable=SC2064
+ trap "${new_cmd}" "${trap_add_name}"
+ done
+}
+
+# Opposite of openim::util::ensure-temp-dir()
+openim::util::cleanup-temp-dir() {
+ rm -rf "${OPENIM_TEMP}"
+}
+
+# Create a temp dir that'll be deleted at the end of this bash session.
+#
+# Vars set:
+# OPENIM_TEMP
+openim::util::ensure-temp-dir() {
+ if [[ -z ${OPENIM_TEMP-} ]]; then
+ OPENIM_TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t openimrnetes.XXXXXX)
+ openim::util::trap_add openim::util::cleanup-temp-dir EXIT
+ fi
+}
+
+openim::util::host_os() {
+ local host_os
+ case "$(uname -s)" in
+ Darwin)
+ host_os=darwin
+ ;;
+ Linux)
+ host_os=linux
+ ;;
+ *)
+ openim::log::error "Unsupported host OS. Must be Linux or Mac OS X."
+ exit 1
+ ;;
+ esac
+ echo "${host_os}"
+}
+
+openim::util::host_arch() {
+ local host_arch
+ case "$(uname -m)" in
+ x86_64*)
+ host_arch=amd64
+ ;;
+ i?86_64*)
+ host_arch=amd64
+ ;;
+ amd64*)
+ host_arch=amd64
+ ;;
+ aarch64*)
+ host_arch=arm64
+ ;;
+ arm64*)
+ host_arch=arm64
+ ;;
+ arm*)
+ host_arch=arm
+ ;;
+ i?86*)
+ host_arch=x86
+ ;;
+ s390x*)
+ host_arch=s390x
+ ;;
+ ppc64le*)
+ host_arch=ppc64le
+ ;;
+ *)
+ openim::log::error "Unsupported host arch. Must be x86_64, 386, arm, arm64, s390x or ppc64le."
+ exit 1
+ ;;
+ esac
+ echo "${host_arch}"
+}
+
+# Define a bash function to check the versions of Docker and Docker Compose
+openim::util::check_docker_and_compose_versions() {
+ # Define the required versions of Docker and Docker Compose
+ required_docker_version="20.10.0"
+ required_compose_version="2.0"
+
+ # Get the currently installed Docker version
+ installed_docker_version=$(docker --version | awk '{print $3}' | sed 's/,//')
+
+ # Check if the installed Docker version matches the required version
+ if [[ "$installed_docker_version" < "$required_docker_version" ]]; then
+ echo "Docker version mismatch. Installed: $installed_docker_version, Required: $required_docker_version"
+ return 1
+ fi
+
+ # Check if the docker compose sub-command is available
+ if ! docker compose version &> /dev/null; then
+ echo "Docker does not support the docker compose sub-command"
+ echo "You need to upgrade Docker to the right version"
+ return 1
+ fi
+
+ # Get the currently installed Docker Compose version
+ installed_compose_version=$(docker compose version --short)
+
+ # Check if the installed Docker Compose version matches the required version
+ if [[ "$installed_compose_version" < "$required_compose_version" ]]; then
+ echo "Docker Compose version mismatch. Installed: $installed_compose_version, Required: $required_compose_version"
+ return 1
+ fi
+
+}
+
+
+# The `openim::util::check_ports` function analyzes the state of processes based on given ports.
+# It accepts multiple ports as arguments and prints:
+# 1. The state of the process (whether it's running or not).
+# 2. The start time of the process if it's running.
+# User:
+# openim::util::check_ports 8080 8081 8082
+# The function returns a status of 1 if any of the processes is not running.
+openim::util::check_ports() {
+ # An array to collect ports of processes that are not running.
+ local not_started=()
+
+ # An array to collect information about processes that are running.
+ local started=()
+
+ openim::log::info "Checking ports: $*"
+ # Iterate over each given port.
+ for port in "$@"; do
+ # Initialize variables
+ # Check the OS and use the appropriate command
+ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
+ if command -v ss > /dev/null 2>&1; then
+ info=$(ss -ltnp | grep ":$port" || true)
+ echo "!!!!!!!!!!! port=$port"
+ echo "!!!!!!!!!!! info=$info"
+ else
+ info=$(netstat -ltnp | grep ":$port" || true)
+ echo "!!!!!!!!!!! port=$port"
+ echo "!!!!!!!!!!! info=$info"
+ fi
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
+ # For macOS, use lsof
+ info=$(lsof -i:"$port" | grep "\*:$port" || true)
fi
- # If there's no process information, it means the process associated with the port is not running.
+ # Check if any process is using the port
if [[ -z $info ]]; then
not_started+=($port)
else
- # Extract relevant details: Process Name, PID, and FD.
- local details=$(echo $info | sed -n 's/.*users:(("\([^"]*\)",pid=\([^,]*\),fd=\([^)]*\))).*/\1 \2 \3/p')
- local command=$(echo $details | awk '{print $1}')
- local pid=$(echo $details | awk '{print $2}')
- local fd=$(echo $details | awk '{print $3}')
-
+ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
+ # Extract relevant details for Linux: Process Name, PID, and FD.
+ details=$(echo $info | sed -n 's/.*users:(("\([^"]*\)",pid=\([^,]*\),fd=\([^)]*\))).*/\1 \2 \3/p')
+ command=$(echo $details | awk '{print $1}')
+ pid=$(echo $details | awk '{print $2}')
+ fd=$(echo $details | awk '{print $3}')
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
+ # Handle extraction for macOS
+ pid=$(echo $info | awk '{print $2}' | cut -d'/' -f1)
+ command=$(ps -p $pid -o comm= | xargs basename)
+ fd=$(echo $info | awk '{print $4}' | cut -d'/' -f1)
+ fi
+
# Get the start time of the process using the PID
if [[ -z $pid ]]; then
- local start_time="N/A"
+ start_time="N/A"
else
- # Get the start time of the process using the PID
- local start_time=$(ps -p $pid -o lstart=)
+ start_time=$(ps -p $pid -o lstart=)
fi
started+=("Port $port - Command: $command, PID: $pid, FD: $fd, Started: $start_time")
@@ -355,6 +1601,7 @@ openim::util::check_ports() {
return 0
fi
}
+
# set +o errexit
# Sample call for testing:
# openim::util::check_ports 10002 1004 12345 13306
@@ -371,12 +1618,15 @@ openim::util::check_process_names() {
# Function to get the port of a process
get_port() {
local pid=$1
- if command -v ss > /dev/null 2>&1; then
- # used ss comment
+ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
+ # Linux
ss -ltnp 2>/dev/null | grep $pid | awk '{print $4}' | cut -d ':' -f2
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
+ # macOS
+ lsof -nP -iTCP -sTCP:LISTEN -a -p $pid | awk 'NR>1 {print $9}' | sed 's/.*://'
else
- # used netstat comment replace ss
- netstat -ltnp 2>/dev/null | grep $pid | awk '{print $4}' | sed 's/.*://'
+ echo "Unsupported OS"
+ return 1
fi
}
@@ -457,7 +1707,7 @@ openim::util::stop_services_on_ports() {
for port in "$@"; do
# Use the `lsof` command to find process information related to the given port.
info=$(lsof -i :$port -n -P | grep LISTEN || true)
-
+
# If there's process information, it means the process associated with the port is running.
if [[ -n $info ]]; then
# Extract the Process ID.
@@ -496,6 +1746,7 @@ openim::util::stop_services_on_ports() {
return 1
else
openim::log::success "All specified services were stopped."
+ echo ""
return 0
fi
}
@@ -572,6 +1823,7 @@ openim::util::stop_services_with_name() {
fi
openim::log::success "All specified services were stopped."
+ echo ""
}
# sleep 333333&
# sleep 444444&
@@ -591,11 +1843,11 @@ openim::util::find-binary-for-platform() {
local -r lookfor="$1"
local -r platform="$2"
local locations=(
- ""${OPENIM_ROOT}"/_output/bin/${lookfor}"
- ""${OPENIM_ROOT}"/_output/${platform}/${lookfor}"
- ""${OPENIM_ROOT}"/_output/local/bin/${platform}/${lookfor}"
- ""${OPENIM_ROOT}"/_output/platforms/${platform}/${lookfor}"
- ""${OPENIM_ROOT}"/_output/platforms/bin/${platform}/${lookfor}"
+ "${OPENIM_ROOT}/_output/bin/${lookfor}"
+ "${OPENIM_ROOT}/_output/${platform}/${lookfor}"
+ "${OPENIM_ROOT}/_output/local/bin/${platform}/${lookfor}"
+ "${OPENIM_ROOT}/_output/platforms/${platform}/${lookfor}"
+ "${OPENIM_ROOT}/_output/platforms/bin/${platform}/${lookfor}"
)
# List most recently-updated location.
@@ -672,11 +1924,11 @@ openim::util::gen-docs() {
# Removes previously generated docs-- we don't want to check them in. $OPENIM_ROOT
# must be set.
openim::util::remove-gen-docs() {
- if [ -e ""${OPENIM_ROOT}"/docs/.generated_docs" ]; then
+ if [ -e "${OPENIM_ROOT}/docs/.generated_docs" ]; then
# remove all of the old docs; we don't want to check them in.
while read -r file; do
- rm ""${OPENIM_ROOT}"/${file}" 2>/dev/null || true
- done <""${OPENIM_ROOT}"/docs/.generated_docs"
+ rm "${OPENIM_ROOT}/${file}" 2>/dev/null || true
+ done <"${OPENIM_ROOT}/docs/.generated_docs"
# The docs/.generated_docs file lists itself, so we don't need to explicitly
# delete it.
fi
@@ -1146,7 +2398,7 @@ function openim::util::require-jq {
# Checks whether dig is installed and provides installation instructions if it is not.
function openim::util::require-dig {
if ! command -v dig &>/dev/null; then
- openim::log::error "Please install 'dig' to use this feature."
+ openim::log::error "Please install 'dig' to use this feature. OR Set the environment variable for OPENIM_IP"
openim::log::error "Installation instructions:"
openim::log::error " For Ubuntu/Debian: sudo apt-get install dnsutils"
openim::log::error " For CentOS/RedHat: sudo yum install bind-utils"
@@ -1389,4 +2641,184 @@ function openim::util::gen_os_arch() {
if [[ "$*" =~ openim::util:: ]];then
eval $*
-fi
\ No newline at end of file
+fi
+
+ openim::util:run::prompt
+}
+
+function openim::util:run::prompt() {
+ echo -n "$yellow\$ $reset"
+}
+
+started=""
+function openim::util:run::maybe_first_prompt() {
+ if [ -z "$started" ]; then
+ openim::util:run::prompt
+ started=true
+ fi
+}
+
+# After a `run` this variable will hold the stdout of the command that was run.
+# If the command was interactive, this will likely be garbage.
+DEMO_RUN_STDOUT=""
+
+function openim::util::run() {
+ openim::util:run::maybe_first_prompt
+ rate=25
+ if [ -n "$DEMO_RUN_FAST" ]; then
+ rate=1000
+ fi
+ echo "$green$1$reset" | pv -qL $rate
+ if [ -n "$DEMO_RUN_FAST" ]; then
+ sleep 0.5
+ fi
+ OFILE="$(mktemp -t $(basename $0).XXXXXX)"
+ if [ "$(uname)" == "Darwin" ]; then
+ script -q "$OFILE" $1
+ else
+ script -eq -c "$1" -f "$OFILE"
+ fi
+ r=$?
+ read -d '' -t "${timeout}" -n 10000 # clear stdin
+ openim::util:run::prompt
+ if [ -z "$DEMO_AUTO_RUN" ]; then
+ read -s
+ fi
+ DEMO_RUN_STDOUT="$(tail -n +2 $OFILE | sed 's/\r//g')"
+ return $r
+}
+
+function openim::util::run::relative() {
+ for arg; do
+ echo "$(realpath $(dirname $(which $0)))/$arg" | sed "s|$(realpath $(pwd))|.|"
+ done
+}
+
+# This function retrieves the IP address of the current server.
+# It primarily uses the `curl` command to fetch the public IP address from ifconfig.me.
+# If curl or the service is not available, it falls back
+# to the internal IP address provided by the hostname command.
+# TODO: If a delay is found, the delay needs to be addressed
+function openim::util::get_server_ip() {
+ # Check if the 'curl' command is available
+ if command -v curl &> /dev/null; then
+ # Try to retrieve the public IP address using curl and ifconfig.me
+ IP=$(dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | sed 's/"//g' | tr -d '\n')
+
+ # Check if IP retrieval was successful
+ if [[ -z "$IP" ]]; then
+ # If not, get the internal IP address
+ IP=$(ip addr show | grep 'inet ' | grep -v 127.0.0.1 | awk '{print $2}' | cut -d'/' -f1 | head -n 1)
+ fi
+ else
+ # If curl is not available, get the internal IP address
+ IP=$(ip addr show | grep 'inet ' | grep -v 127.0.0.1 | awk '{print $2}' | cut -d'/' -f1 | head -n 1)
+ fi
+
+ # Return the fetched IP address
+ echo "$IP"
+}
+
+function openim::util::onCtrlC() {
+ echo -e "\n${t_reset}Ctrl+C Press it. It's exiting openim make init..."
+ exit 1
+}
+
+# Function Function: Remove Spaces in the string
+function openim::util::remove_space() {
+ value=$* # 获取传入的参数
+ result=$(echo $value | sed 's/ //g') # 去除空格
+}
+
+function openim::util::gencpu() {
+ # Check the system type
+ system_type=$(uname)
+
+ if [[ "$system_type" == "Darwin" ]]; then
+ # macOS (using sysctl)
+ cpu_count=$(sysctl -n hw.ncpu)
+ elif [[ "$system_type" == "Linux" ]]; then
+ # Linux (using lscpu)
+ cpu_count=$(lscpu --parse | grep -E '^([^#].*,){3}[^#]' | sort -u | wc -l)
+ else
+ echo "Unsupported operating system: $system_type"
+ exit 1
+ fi
+ echo $cpu_count
+}
+
+function openim::util::set_max_fd() {
+ local desired_fd=$1
+ local max_fd_limit
+
+ # Check if we're not on cygwin or darwin.
+ if [ "$(uname -s | tr '[:upper:]' '[:lower:]')" != "cygwin" ] && [ "$(uname -s | tr '[:upper:]' '[:lower:]')" != "darwin" ]; then
+ # Try to get the hard limit.
+ max_fd_limit=$(ulimit -H -n)
+ if [ $? -eq 0 ]; then
+ # If desired_fd is 'maximum' or 'max', set it to the hard limit.
+ if [ "$desired_fd" = "maximum" ] || [ "$desired_fd" = "max" ]; then
+ desired_fd="$max_fd_limit"
+ fi
+
+ # Check if desired_fd is less than or equal to max_fd_limit.
+ if [ "$desired_fd" -le "$max_fd_limit" ]; then
+ ulimit -n "$desired_fd"
+ if [ $? -ne 0 ]; then
+ echo "Warning: Could not set maximum file descriptor limit to $desired_fd"
+ fi
+ else
+ echo "Warning: Desired file descriptor limit ($desired_fd) is greater than the hard limit ($max_fd_limit)"
+ fi
+ else
+ echo "Warning: Could not query the maximum file descriptor hard limit."
+ fi
+ else
+ echo "Warning: Not attempting to modify file descriptor limit on Cygwin or Darwin."
+ fi
+}
+
+
+function openim::util::gen_os_arch() {
+ # Get the current operating system and architecture
+ OS=$(uname -s | tr '[:upper:]' '[:lower:]')
+ ARCH=$(uname -m)
+
+ # Select the repository home directory based on the operating system and architecture
+ if [[ "$OS" == "darwin" ]]; then
+ if [[ "$ARCH" == "x86_64" ]]; then
+ REPO_DIR="darwin/amd64"
+ else
+ REPO_DIR="darwin/386"
+ fi
+ elif [[ "$OS" == "linux" ]]; then
+ if [[ "$ARCH" == "x86_64" ]]; then
+ REPO_DIR="linux/amd64"
+ elif [[ "$ARCH" == "arm64" ]]; then
+ REPO_DIR="linux/arm64"
+ elif [[ "$ARCH" == "mips64" ]]; then
+ REPO_DIR="linux/mips64"
+ elif [[ "$ARCH" == "mips64le" ]]; then
+ REPO_DIR="linux/mips64le"
+ elif [[ "$ARCH" == "ppc64le" ]]; then
+ REPO_DIR="linux/ppc64le"
+ elif [[ "$ARCH" == "s390x" ]]; then
+ REPO_DIR="linux/s390x"
+ else
+ REPO_DIR="linux/386"
+ fi
+ elif [[ "$OS" == "windows" ]]; then
+ if [[ "$ARCH" == "x86_64" ]]; then
+ REPO_DIR="windows/amd64"
+ else
+ REPO_DIR="windows/386"
+ fi
+ else
+ echo -e "${RED_PREFIX}Unsupported OS: $OS${COLOR_SUFFIX}"
+ exit 1
+ fi
+}
+
+if [[ "$*" =~ openim::util:: ]];then
+ eval $*
+fi
diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk
index c56f9f071..5fda9b927 100644
--- a/scripts/make-rules/common.mk
+++ b/scripts/make-rules/common.mk
@@ -73,7 +73,8 @@ endif
ifeq ($(origin VERSION), undefined)
# VERSION := $(shell git describe --tags --always --match='v*')
# git describe --tags --always --match="v*" --dirty
-VERSION := $(shell git describe --tags --always --match="v*" --dirty | sed 's/-/./g') #v2.3.3.631.g00abdc9b.dirty
+# VERSION := $(shell git describe --tags --always --match="v*" --dirty | sed 's/-/./g') #v2.3.3.631.g00abdc9b.dirty
+VERSION := $(shell git describe --tags --always --match='v*')
# v2.3.3: git tag
endif
@@ -100,7 +101,7 @@ endif
# The OS must be linux when building docker images
# PLATFORMS ?= linux_amd64 linux_arm64
# The OS can be linux/windows/darwin when building binaries
-PLATFORMS ?= linux_s390x linux_mips64 linux_mips64le darwin_amd64 windows_amd64 linux_amd64 linux_arm64 linux_ppc64le # wasip1_wasm
+PLATFORMS ?= linux_s390x linux_mips64 linux_mips64le darwin_amd64 darwin_arm64 windows_amd64 linux_amd64 linux_arm64 linux_ppc64le # wasip1_wasm
# set a specific PLATFORM, defaults to the host platform
ifeq ($(origin PLATFORM), undefined)
diff --git a/scripts/make-rules/tools.mk b/scripts/make-rules/tools.mk
index 7fe7305fb..5f076d6e7 100644
--- a/scripts/make-rules/tools.mk
+++ b/scripts/make-rules/tools.mk
@@ -146,7 +146,7 @@ install.github-release:
# amd64
.PHONY: install.coscli
install.coscli:
- @wget -q https://ghproxy.com/https://github.com/tencentyun/coscli/releases/download/v0.13.0-beta/coscli-linux -O ${TOOLS_DIR}/coscli
+ @wget -q https://github.com/tencentyun/coscli/releases/download/v0.19.0-beta/coscli-linux -O ${TOOLS_DIR}/coscli
@chmod +x ${TOOLS_DIR}/coscli
## install.coscmd: Install coscmd, used to upload files to cos
diff --git a/scripts/release.sh b/scripts/release.sh
index 9e1f99bc4..042a6c3a0 100755
--- a/scripts/release.sh
+++ b/scripts/release.sh
@@ -13,27 +13,138 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
+# Description:
+# This script automates the process of building and releasing OpenIM,
+# including tasks like setting up the environment, verifying prerequisites,
+# building commands, packaging tarballs, uploading tarballs, creating GitHub
+# releases, and generating changelogs.
+#
+# Usage:
+# ./scripts/release.sh [options]
+# Options include:
+# -h, --help : Show help message
+# -se, --setup-env : Execute setup environment
+# -vp, --verify-prereqs : Execute prerequisites verification
+# -bc, --build-command : Execute build command
+# -bi, --build-image : Execute build image (default: not executed)
+# -pt, --package-tarballs : Execute package tarballs
+# -ut, --upload-tarballs : Execute upload tarballs
+# -gr, --github-release : Execute GitHub release
+# -gc, --generate-changelog: Execute generate changelog
+#
+# This script can also be executed via the 'make release' command as an alternative.
+#
+# Dependencies:
+# This script depends on external scripts found in the 'scripts' directory and
+# assumes the presence of necessary tools and permissions for building and
+# releasing software.
+#
+# Note:
+# The script uses standard bash script practices with error handling,
+# and it defaults to executing all steps if no specific option is provided.
+#
# Build a OpenIM release. This will build the binaries, create the Docker
# images and other build artifacts.
+# Build a OpenIM release. This script supports various flags for flexible execution control.
set -o errexit
set -o nounset
set -o pipefail
-
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
source "${OPENIM_ROOT}/scripts/common.sh"
source "${OPENIM_ROOT}/scripts/lib/release.sh"
OPENIM_RELEASE_RUN_TESTS=${OPENIM_RELEASE_RUN_TESTS-y}
-openim::golang::setup_env
-openim::build::verify_prereqs
-openim::release::verify_prereqs
-#openim::build::build_image
-openim::build::build_command
-openim::release::package_tarballs
-openim::release::updload_tarballs
-git push origin ${VERSION}
-#openim::release::github_release
-#openim::release::generate_changelog
+# Function to show help message
+show_help() {
+ echo "Usage: $(basename $0) [options]"
+ echo "Options:"
+ echo " -h, --help Show this help message"
+ echo " -se, --setup-env Execute setup environment"
+ echo " -vp, --verify-prereqs Execute prerequisites verification"
+ echo " -bc, --build-command Execute build command"
+ echo " -bi, --build-image Execute build image (default: not executed)"
+ echo " -pt, --package-tarballs Execute package tarballs"
+ echo " -ut, --upload-tarballs Execute upload tarballs"
+ echo " -gr, --github-release Execute GitHub release"
+ echo " -gc, --generate-changelog Execute generate changelog"
+}
+
+# Initialize all actions to false
+perform_setup_env=false
+perform_verify_prereqs=false
+perform_build_command=false
+perform_build_image=false # New flag for build image
+perform_package_tarballs=false
+perform_upload_tarballs=false
+perform_github_release=false
+perform_generate_changelog=false
+
+# Process command-line arguments
+while getopts "hsevpbciptutgrgc-" opt; do
+ case "${opt}" in
+ h) show_help; exit 0 ;;
+ se) perform_setup_env=true ;;
+ vp) perform_verify_prereqs=true ;;
+ bc) perform_build_command=true ;;
+ bi) perform_build_image=true ;; # Handling new option
+ pt) perform_package_tarballs=true ;;
+ ut) perform_upload_tarballs=true ;;
+ gr) perform_github_release=true ;;
+ gc) perform_generate_changelog=true ;;
+ --) case "${OPTARG}" in
+ help) show_help; exit 0 ;;
+ setup-env) perform_setup_env=true ;;
+ verify-prereqs) perform_verify_prereqs=true ;;
+ build-command) perform_build_command=true ;;
+ build-image) perform_build_image=true ;; # Handling new long option
+ package-tarballs) perform_package_tarballs=true ;;
+ upload-tarballs) perform_upload_tarballs=true ;;
+ github-release) perform_github_release=true ;;
+ generate-changelog) perform_generate_changelog=true ;;
+ *) echo "Invalid option: --${OPTARG}"; show_help; exit 1 ;;
+ esac ;;
+ *) show_help; exit 1 ;;
+ esac
+done
+
+# Enable all actions by default if no options are provided
+if [ "$#" -eq 0 ]; then
+ perform_setup_env=true
+ perform_verify_prereqs=true
+ perform_build_command=true
+ perform_package_tarballs=true
+ perform_upload_tarballs=true
+ perform_github_release=true
+ perform_generate_changelog=true
+ # TODO: Not enabling build_image by default
+ # perform_build_image=true
+fi
+
+# Function to perform actions
+perform_action() {
+ local flag=$1
+ local message=$2
+ local command=$3
+
+ if [ "$flag" == true ]; then
+ openim::log::info "## $message..."
+ if ! $command; then
+ openim::log::errexit "Error in $message"
+ fi
+ fi
+}
+
+echo "Starting script execution..."
+
+perform_action $perform_setup_env "Setting up environment" "openim::golang::setup_env"
+perform_action $perform_verify_prereqs "Verifying prerequisites" "openim::build::verify_prereqs && openim::release::verify_prereqs"
+perform_action $perform_build_command "Executing build command" "openim::build::build_command"
+perform_action $perform_build_image "Building image" "openim::build::build_image"
+perform_action $perform_package_tarballs "Packaging tarballs" "openim::release::package_tarballs"
+perform_action $perform_upload_tarballs "Uploading tarballs" "openim::release::upload_tarballs"
+perform_action $perform_github_release "Creating GitHub release" "openim::release::github_release"
+perform_action $perform_generate_changelog "Generating changelog" "openim::release::generate_changelog"
+
+openim::log::success "OpenIM Relase Script Execution Completed."
diff --git a/scripts/stop-all.sh b/scripts/stop-all.sh
index 090c48b0d..692d2d1e4 100755
--- a/scripts/stop-all.sh
+++ b/scripts/stop-all.sh
@@ -34,4 +34,13 @@ openim::util::stop_services_on_ports ${OPENIM_SERVER_PORT_LISTARIES[@]}
echo -e "\n++ Stop all processes in the path ${OPENIM_OUTPUT_HOSTBIN}"
-openim::util::stop_services_with_name "${OPENIM_OUTPUT_HOSTBIN}"
\ No newline at end of file
+openim::util::stop_services_with_name "${OPENIM_OUTPUT_HOSTBIN}"
+
+echo -n "Stopping services 15 seconds."
+for i in {1..15}; do
+ echo -n "."
+ sleep 1
+done
+echo -e "\nServices stopped."
+
+openim::log::success "✨ Wait 15 seconds for all processes to be killed"
\ No newline at end of file
diff --git a/scripts/update-generated-docs.sh b/scripts/update-generated-docs.sh
index 008cf63ed..93f0f86c1 100755
--- a/scripts/update-generated-docs.sh
+++ b/scripts/update-generated-docs.sh
@@ -23,7 +23,7 @@ set -o nounset
set -o pipefail
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
-source "${OPENIM_ROOT}/hack/lib/init.sh"
+source "${OPENIM_ROOT}/scripts/lib/init.sh"
openim::golang::setup_env
diff --git a/scripts/update-yamlfmt.sh b/scripts/update-yamlfmt.sh
index 1e4ad513f..90ec8aa62 100755
--- a/scripts/update-yamlfmt.sh
+++ b/scripts/update-yamlfmt.sh
@@ -19,9 +19,9 @@ set -o nounset
set -o pipefail
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
-source "${OPENIM_ROOT}/hack/lib/init.sh"
+source "${OPENIM_ROOT}/scripts/lib/init.sh"
-kube::golang::setup_env
+openim::golang::setup_env
cd "${OPENIM_ROOT}"
@@ -40,4 +40,4 @@ find_files() {
}
export GO111MODULE=on
-find_files | xargs go run tools/yamlfmt/main.go
\ No newline at end of file
+find_files | xargs go run tools/yamlfmt/yamlfmt.go
\ No newline at end of file
diff --git a/scripts/verify-shellcheck.sh b/scripts/verify-shellcheck.sh
index 12162dd8b..de860115e 100755
--- a/scripts/verify-shellcheck.sh
+++ b/scripts/verify-shellcheck.sh
@@ -113,7 +113,7 @@ if ${HAVE_SHELLCHECK}; then
else
openim::log::info "Using shellcheck ${SHELLCHECK_VERSION} docker image."
"${DOCKER}" run \
- --rm -v ""${OPENIM_ROOT}":"${OPENIM_ROOT}"" -w "${OPENIM_ROOT}" \
+ --rm -v "${OPENIM_ROOT}:"${OPENIM_ROOT}"" -w "${OPENIM_ROOT}" \
"${SHELLCHECK_IMAGE}" \
shellcheck "${SHELLCHECK_OPTIONS[@]}" "${all_shell_scripts[@]}" >&2 || res=$?
fi
diff --git a/scripts/verify-spelling.sh b/scripts/verify-spelling.sh
index f3ed7886d..487c68cde 100755
--- a/scripts/verify-spelling.sh
+++ b/scripts/verify-spelling.sh
@@ -30,12 +30,12 @@ export GOBIN="${KUBE_OUTPUT_BINPATH}"
PATH="${GOBIN}:${PATH}"
# Install tools we need
-pushd ""${OPENIM_ROOT}"/tools" >/dev/null
+pushd "${OPENIM_ROOT}/tools" >/dev/null
GO111MODULE=on go install github.com/client9/misspell/cmd/misspell
popd >/dev/null
# Spell checking
# All the skipping files are defined in scripts/.spelling_failures
-skipping_file=""${OPENIM_ROOT}"/scripts/.spelling_failures"
+skipping_file="${OPENIM_ROOT}/scripts/.spelling_failures"
failing_packages=$(sed "s| | -e |g" "${skipping_file}")
git ls-files | grep -v -e "${failing_packages}" | xargs misspell -i "Creater,creater,ect" -error -o stderr
diff --git a/scripts/verify-yamlfmt.sh b/scripts/verify-yamlfmt.sh
index 82e1c528d..3d0a0180d 100755
--- a/scripts/verify-yamlfmt.sh
+++ b/scripts/verify-yamlfmt.sh
@@ -36,13 +36,13 @@ openim::util::trap_add "git worktree remove -f ${_tmpdir}" EXIT
cd "${_tmpdir}"
# Format YAML files
-hack/update-yamlfmt.sh
+scripts/update-yamlfmt.sh
# Test for diffs
diffs=$(git status --porcelain | wc -l)
if [[ ${diffs} -gt 0 ]]; then
echo "YAML files need to be formatted" >&2
git diff
- echo "Please run 'hack/update-yamlfmt.sh'" >&2
+ echo "Please run 'scripts/update-yamlfmt.sh'" >&2
exit 1
fi
\ No newline at end of file
diff --git a/test/typecheck/typecheck.go b/test/typecheck/typecheck.go
index 83e3c63ed..8f353881b 100644
--- a/test/typecheck/typecheck.go
+++ b/test/typecheck/typecheck.go
@@ -47,23 +47,27 @@ var (
crossPlatforms = []string{
"linux/amd64", "windows/386",
"darwin/amd64", "darwin/arm64",
- "linux/arm", "linux/386",
+ "linux/386",
"windows/amd64", "linux/arm64",
"linux/ppc64le", "linux/s390x",
"windows/arm64",
}
+ // "linux/arm",
+
// directories we always ignore
standardIgnoreDirs = []string{
// Staging code is symlinked from vendor/k8s.io, and uses import
// paths as if it were inside of vendor/. It fails typechecking
// inside of staging/, but works when typechecked as part of vendor/.
"staging",
+ "components",
// OS-specific vendor code tends to be imported by OS-specific
// packages. We recursively typecheck imported vendored packages for
// each OS, but don't typecheck everything for every OS.
"vendor",
"_output",
+ "OpenIMSKD/tools",
// This is a weird one. /testdata/ is *mostly* ignored by Go,
// and this translates to kubernetes/vendor not working.
// edit/record.go doesn't compile without gopkg.in/yaml.v2
@@ -71,7 +75,7 @@ var (
"pkg/kubectl/cmd/testdata/edit",
// Tools we use for maintaining the code base but not necessarily
// ship as part of the release
- "hack/tools",
+ "sopenim::golang::setup_env:tools/yamlfmt/yamlfmt.go:tools",
}
)
diff --git a/test/wrktest.sh b/test/wrktest.sh
index 01617676a..a97ebf043 100755
--- a/test/wrktest.sh
+++ b/test/wrktest.sh
@@ -45,7 +45,7 @@ openim::wrk::setup() {
cmd="wrk -t${threads} -d${duration} -T30s --latency"
}
-# Print usage infomation
+# Print usage
openim::wrk::usage() {
cat << EOF
diff --git a/tools/changelog/changelog.go b/tools/changelog/changelog.go
index 17a9e5404..ff9a7eab9 100644
--- a/tools/changelog/changelog.go
+++ b/tools/changelog/changelog.go
@@ -61,7 +61,7 @@ var (
{"template", "template"},
{"etcd", "server"},
{"pod", "node"},
- {"hack/", "hack"},
+ {"scripts/", "hack"},
{"e2e", "test"},
{"integration", "test"},
{"cluster", "cluster"},
diff --git a/tools/component/component.go b/tools/component/component.go
index 62f2c60ac..220b845ee 100644
--- a/tools/component/component.go
+++ b/tools/component/component.go
@@ -33,19 +33,20 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
- "github.com/minio/minio-go/v7/pkg/credentials"
"github.com/minio/minio-go/v7"
- "github.com/redis/go-redis/v9"
- "gopkg.in/yaml.v3"
+ "github.com/minio/minio-go/v7/pkg/credentials"
+ "github.com/redis/go-redis/v9"
+ "gopkg.in/yaml.v3"
)
const (
// defaultCfgPath is the default path of the configuration file.
defaultCfgPath = "../../../../../config/config.yaml"
minioHealthCheckDuration = 1
- maxRetry = 100
+ maxRetry = 300
componentStartErrCode = 6000
configErrCode = 6001
+ mongoConnTimeout = 30 * time.Second
)
const (
@@ -55,8 +56,7 @@ const (
)
var (
- cfgPath = flag.String("c", defaultCfgPath, "Path to the configuration file")
-
+ cfgPath = flag.String("c", defaultCfgPath, "Path to the configuration file")
ErrComponentStart = errs.NewCodeError(componentStartErrCode, "ComponentStartErr")
ErrConfig = errs.NewCodeError(configErrCode, "Config file is incorrect")
)
@@ -95,7 +95,7 @@ func main() {
for i := 0; i < maxRetry; i++ {
if i != 0 {
- time.Sleep(3 * time.Second)
+ time.Sleep(1 * time.Second)
}
fmt.Printf("Checking components Round %v...\n", i+1)
@@ -141,19 +141,25 @@ func getEnv(key, fallback string) string {
return fallback
}
-// checkMongo checks the MongoDB connection
+// checkMongo checks the MongoDB connection without retries
func checkMongo() (string, error) {
- // Use environment variables or fallback to config
uri := getEnv("MONGO_URI", buildMongoURI())
- client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
+ ctx, cancel := context.WithTimeout(context.Background(), mongoConnTimeout)
+ defer cancel()
+
str := "ths addr is:" + strings.Join(config.Config.Mongo.Address, ",")
+
+ client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri))
if err != nil {
return "", errs.Wrap(errStr(err, str))
}
- defer client.Disconnect(context.TODO())
+ defer client.Disconnect(context.Background())
+
+ ctx, cancel = context.WithTimeout(context.Background(), mongoConnTimeout)
+ defer cancel()
- if err = client.Ping(context.TODO(), nil); err != nil {
+ if err = client.Ping(ctx, nil); err != nil {
return "", errs.Wrap(errStr(err, str))
}
@@ -222,8 +228,8 @@ func checkMinio() (string, error) {
defer cancel()
if minioClient.IsOffline() {
- // str := fmt.Sprintf("Minio server is offline;%s", str)
- // return "", ErrComponentStart.Wrap(str)
+ str := fmt.Sprintf("Minio server is offline;%s", str)
+ return "", ErrComponentStart.Wrap(str)
}
// Check for localhost in API URL and Minio SignEndpoint
diff --git a/tools/formitychecker/README.md b/tools/formitychecker/README.md
new file mode 100644
index 000000000..7cabf8a66
--- /dev/null
+++ b/tools/formitychecker/README.md
@@ -0,0 +1,102 @@
+# Development of a Go-Based Conformity Checker for Project File and Directory Naming Standards
+
+### 1. Project Overview
+
+#### Project Name
+
+- `GoConformityChecker`
+
+#### Functionality Description
+
+- Checks if the file and subdirectory names in a specified directory adhere to specific naming conventions.
+- Supports specific file types (e.g., `.go`, `.yml`, `.yaml`, `.md`, `.sh`, etc.).
+- Allows users to specify directories to be checked and directories to be ignored.
+- More read https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/code-conventions.md
+
+#### Naming Conventions
+
+- Go files: Only underscores are allowed.
+- YAML, YML, and Markdown files: Only hyphens are allowed.
+- Directories: Only underscores are allowed.
+
+### 2. File Structure
+
+- `main.go`: Entry point of the program, handles command-line arguments.
+- `checker/checker.go`: Contains the core logic.
+- `config/config.go`: Parses and stores configuration information.
+
+### 3. Core Code Design
+
+#### main.go
+
+- Parses command-line arguments, including the directory to be checked and directories to be ignored.
+- Calls the `checker` module for checking.
+
+#### config.go
+
+- Defines a configuration structure, such as directories to check and ignore.
+
+#### checker.go
+
+- Iterates through the specified directory.
+- Applies different naming rules based on file types and directory names.
+- Records files or directories that do not conform to the standards.
+
+### 4. Pseudocode Example
+
+#### main.go
+
+```go
+package main
+
+import (
+ "flag"
+ "fmt"
+ "GoConformityChecker/checker"
+)
+
+func main() {
+ // Parse command-line arguments
+ var targetDir string
+ var ignoreDirs string
+ flag.StringVar(&targetDir, "target", ".", "Directory to check")
+ flag.StringVar(&ignoreDirs, "ignore", "", "Directories to ignore")
+ flag.Parse()
+
+ // Call the checker
+ err := checker.CheckDirectory(targetDir, ignoreDirs)
+ if err != nil {
+ fmt.Println("Error:", err)
+ }
+}
+```
+
+#### checker.go
+
+```go
+package checker
+
+import (
+ // Import necessary packages
+)
+
+func CheckDirectory(targetDir, ignoreDirs string) error {
+ // Iterate through the directory, applying rules to check file and directory names
+ // Return any found errors or non-conformities
+ return nil
+}
+```
+
+### 5. Implementation Details
+
+- **File and Directory Traversal**: Use Go's `path/filepath` package to traverse directories and subdirectories.
+- **Naming Rules Checking**: Apply different regex expressions for naming checks based on file extensions.
+- **Error Handling and Reporting**: Record files or directories that do not conform and report to the user.
+
+### 6. Future Development and Extensions
+
+- Support more file types and naming rules.
+- Provide more detailed error reports, such as showing line numbers and specific naming mistakes.
+- Add a graphical or web interface for non-command-line users.
+
+The above is an overview of the entire project's design. Following this design, specific coding implementation can begin. Note that the actual implementation may need adjustments based on real-world conditions.
\ No newline at end of file
diff --git a/tools/formitychecker/checker/checker.go b/tools/formitychecker/checker/checker.go
new file mode 100644
index 000000000..187b509bc
--- /dev/null
+++ b/tools/formitychecker/checker/checker.go
@@ -0,0 +1,97 @@
+package checker
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+
+ "github.com/openimsdk/open-im-server/tools/formitychecker/config"
+)
+
+var (
+ underscoreRegex = regexp.MustCompile(`^[a-zA-Z0-9_]+\.[a-zA-Z0-9]+$`)
+ hyphenRegex = regexp.MustCompile(`^[a-zA-Z0-9\-]+\.[a-zA-Z0-9]+$`)
+)
+
+// CheckDirectoCheckDirectoryries initiates the checking process for the specified directories using configuration from config.Config.
+func CheckDirectory(cfg *config.Config) error {
+ ignoreMap := make(map[string]struct{})
+ for _, dir := range cfg.IgnoreDirs {
+ ignoreMap[dir] = struct{}{}
+ }
+
+ for _, targetDir := range cfg.TargetDirs {
+ err := filepath.Walk(targetDir, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+
+ // Skip if the directory is in the ignore list
+ dirName := filepath.Base(filepath.Dir(path))
+ if _, ok := ignoreMap[dirName]; ok && info.IsDir() {
+ return filepath.SkipDir
+ }
+
+ // Check the naming convention
+ if err := checkNamingConvention(path, info); err != nil {
+ fmt.Println(err)
+ }
+
+ return nil
+ })
+
+ if err != nil {
+ return fmt.Errorf("error checking directory '%s': %w", targetDir, err)
+ }
+ }
+
+ return nil
+}
+
+// checkNamingConvention checks if the file or directory name conforms to the standard naming conventions.
+func checkNamingConvention(path string, info os.FileInfo) error {
+ fileName := info.Name()
+
+ // Handle special cases for directories like .git
+ if info.IsDir() && strings.HasPrefix(fileName, ".") {
+ return nil // Skip special directories
+ }
+
+ // Extract the main part of the name (without extension for files)
+ mainName := fileName
+ if !info.IsDir() {
+ mainName = strings.TrimSuffix(fileName, filepath.Ext(fileName))
+ }
+
+ // Determine the type of file and apply corresponding naming rule
+ switch {
+ case info.IsDir():
+ if !isValidName(mainName, "_") { // Directory names must only contain underscores
+ return fmt.Errorf("!!! invalid directory name: %s", path)
+ }
+ case strings.HasSuffix(fileName, ".go"):
+ if !isValidName(mainName, "_") { // Go files must only contain underscores
+ return fmt.Errorf("!!! invalid Go file name: %s", path)
+ }
+ case strings.HasSuffix(fileName, ".yml"), strings.HasSuffix(fileName, ".yaml"), strings.HasSuffix(fileName, ".md"):
+ if !isValidName(mainName, "-") { // YML, YAML, and Markdown files must only contain hyphens
+ return fmt.Errorf("!!! invalid file name: %s", path)
+ }
+ }
+
+ return nil
+}
+
+// isValidName checks if the file name conforms to the specified rule (underscore or hyphen).
+func isValidName(name, charType string) bool {
+ switch charType {
+ case "_":
+ return underscoreRegex.MatchString(name)
+ case "-":
+ return hyphenRegex.MatchString(name)
+ default:
+ return false
+ }
+}
diff --git a/tools/formitychecker/config/config.go b/tools/formitychecker/config/config.go
new file mode 100644
index 000000000..95bcee346
--- /dev/null
+++ b/tools/formitychecker/config/config.go
@@ -0,0 +1,27 @@
+package config
+
+import (
+ "strings"
+)
+
+// Config holds all the configuration parameters for the checker.
+type Config struct {
+ TargetDirs []string // Directories to check
+ IgnoreDirs []string // Directories to ignore
+}
+
+// NewConfig creates and returns a new Config instance.
+func NewConfig(targetDirs, ignoreDirs string) *Config {
+ return &Config{
+ TargetDirs: parseDirs(targetDirs),
+ IgnoreDirs: parseDirs(ignoreDirs),
+ }
+}
+
+// parseDirs splits a comma-separated string into a slice of directory names.
+func parseDirs(dirs string) []string {
+ if dirs == "" {
+ return nil
+ }
+ return strings.Split(dirs, ",")
+}
diff --git a/tools/formitychecker/formitychecker.go b/tools/formitychecker/formitychecker.go
new file mode 100644
index 000000000..d078009b6
--- /dev/null
+++ b/tools/formitychecker/formitychecker.go
@@ -0,0 +1,27 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+
+ "github.com/openimsdk/open-im-server/tools/formitychecker/checker"
+ "github.com/openimsdk/open-im-server/tools/formitychecker/config"
+)
+
+func main() {
+ defaultTargetDirs := "."
+ defaultIgnoreDirs := "components,.git"
+
+ var targetDirs string
+ var ignoreDirs string
+ flag.StringVar(&targetDirs, "target", defaultTargetDirs, "Directories to check (default: current directory)")
+ flag.StringVar(&ignoreDirs, "ignore", defaultIgnoreDirs, "Directories to ignore (default: A/, B/)")
+ flag.Parse()
+
+ conf := config.NewConfig(targetDirs, ignoreDirs)
+
+ err := checker.CheckDirectory(conf)
+ if err != nil {
+ fmt.Println("Error:", err)
+ }
+}
diff --git a/tools/formitychecker/go.mod b/tools/formitychecker/go.mod
new file mode 100644
index 000000000..698b77647
--- /dev/null
+++ b/tools/formitychecker/go.mod
@@ -0,0 +1,3 @@
+module github.com/openimsdk/open-im-server/tools/formitychecker
+
+go 1.19
diff --git a/tools/imctl/imctl.go b/tools/imctl/imctl.go
new file mode 100644
index 000000000..1a501cafc
--- /dev/null
+++ b/tools/imctl/imctl.go
@@ -0,0 +1,8 @@
+package main
+
+import "fmt"
+
+func main() {
+
+ fmt.Println("imctl")
+}
diff --git a/tools/up35/pkg/convert.go b/tools/up35/pkg/convert.go
index 24d3a2781..53ada0e04 100644
--- a/tools/up35/pkg/convert.go
+++ b/tools/up35/pkg/convert.go
@@ -17,16 +17,16 @@ package pkg
import (
"time"
- mongoModel "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
- mysqlModel "github.com/openimsdk/open-im-server/v3/tools/data-conversion/openim/mysql/v3"
- mongoModelRtc "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mongo/table"
- mysqlModelRtc "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mysql"
+ mongomodel "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
+ mysqlmodel "github.com/openimsdk/open-im-server/v3/tools/data-conversion/openim/mysql/v3"
+ mongomodelrtc "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mongo/table"
+ mysqlmodelrtc "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mysql"
)
type convert struct{}
-func (convert) User(v mysqlModel.UserModel) mongoModel.UserModel {
- return mongoModel.UserModel{
+func (convert) User(v mysqlmodel.UserModel) mongomodel.UserModel {
+ return mongomodel.UserModel{
UserID: v.UserID,
Nickname: v.Nickname,
FaceURL: v.FaceURL,
@@ -37,8 +37,8 @@ func (convert) User(v mysqlModel.UserModel) mongoModel.UserModel {
}
}
-func (convert) Friend(v mysqlModel.FriendModel) mongoModel.FriendModel {
- return mongoModel.FriendModel{
+func (convert) Friend(v mysqlmodel.FriendModel) mongomodel.FriendModel {
+ return mongomodel.FriendModel{
OwnerUserID: v.OwnerUserID,
FriendUserID: v.FriendUserID,
Remark: v.Remark,
@@ -49,8 +49,8 @@ func (convert) Friend(v mysqlModel.FriendModel) mongoModel.FriendModel {
}
}
-func (convert) FriendRequest(v mysqlModel.FriendRequestModel) mongoModel.FriendRequestModel {
- return mongoModel.FriendRequestModel{
+func (convert) FriendRequest(v mysqlmodel.FriendRequestModel) mongomodel.FriendRequestModel {
+ return mongomodel.FriendRequestModel{
FromUserID: v.FromUserID,
ToUserID: v.ToUserID,
HandleResult: v.HandleResult,
@@ -63,8 +63,8 @@ func (convert) FriendRequest(v mysqlModel.FriendRequestModel) mongoModel.FriendR
}
}
-func (convert) Black(v mysqlModel.BlackModel) mongoModel.BlackModel {
- return mongoModel.BlackModel{
+func (convert) Black(v mysqlmodel.BlackModel) mongomodel.BlackModel {
+ return mongomodel.BlackModel{
OwnerUserID: v.OwnerUserID,
BlockUserID: v.BlockUserID,
CreateTime: v.CreateTime,
@@ -74,8 +74,8 @@ func (convert) Black(v mysqlModel.BlackModel) mongoModel.BlackModel {
}
}
-func (convert) Group(v mysqlModel.GroupModel) mongoModel.GroupModel {
- return mongoModel.GroupModel{
+func (convert) Group(v mysqlmodel.GroupModel) mongomodel.GroupModel {
+ return mongomodel.GroupModel{
GroupID: v.GroupID,
GroupName: v.GroupName,
Notification: v.Notification,
@@ -94,8 +94,8 @@ func (convert) Group(v mysqlModel.GroupModel) mongoModel.GroupModel {
}
}
-func (convert) GroupMember(v mysqlModel.GroupMemberModel) mongoModel.GroupMemberModel {
- return mongoModel.GroupMemberModel{
+func (convert) GroupMember(v mysqlmodel.GroupMemberModel) mongomodel.GroupMemberModel {
+ return mongomodel.GroupMemberModel{
GroupID: v.GroupID,
UserID: v.UserID,
Nickname: v.Nickname,
@@ -110,8 +110,8 @@ func (convert) GroupMember(v mysqlModel.GroupMemberModel) mongoModel.GroupMember
}
}
-func (convert) GroupRequest(v mysqlModel.GroupRequestModel) mongoModel.GroupRequestModel {
- return mongoModel.GroupRequestModel{
+func (convert) GroupRequest(v mysqlmodel.GroupRequestModel) mongomodel.GroupRequestModel {
+ return mongomodel.GroupRequestModel{
UserID: v.UserID,
GroupID: v.GroupID,
HandleResult: v.HandleResult,
@@ -126,8 +126,8 @@ func (convert) GroupRequest(v mysqlModel.GroupRequestModel) mongoModel.GroupRequ
}
}
-func (convert) Conversation(v mysqlModel.ConversationModel) mongoModel.ConversationModel {
- return mongoModel.ConversationModel{
+func (convert) Conversation(v mysqlmodel.ConversationModel) mongomodel.ConversationModel {
+ return mongomodel.ConversationModel{
OwnerUserID: v.OwnerUserID,
ConversationID: v.ConversationID,
ConversationType: v.ConversationType,
@@ -149,9 +149,9 @@ func (convert) Conversation(v mysqlModel.ConversationModel) mongoModel.Conversat
}
}
-func (convert) Object(engine string) func(v mysqlModel.ObjectModel) mongoModel.ObjectModel {
- return func(v mysqlModel.ObjectModel) mongoModel.ObjectModel {
- return mongoModel.ObjectModel{
+func (convert) Object(engine string) func(v mysqlmodel.ObjectModel) mongomodel.ObjectModel {
+ return func(v mysqlmodel.ObjectModel) mongomodel.ObjectModel {
+ return mongomodel.ObjectModel{
Name: v.Name,
UserID: v.UserID,
Hash: v.Hash,
@@ -165,8 +165,8 @@ func (convert) Object(engine string) func(v mysqlModel.ObjectModel) mongoModel.O
}
}
-func (convert) Log(v mysqlModel.Log) mongoModel.LogModel {
- return mongoModel.LogModel{
+func (convert) Log(v mysqlmodel.Log) mongomodel.LogModel {
+ return mongomodel.LogModel{
LogID: v.LogID,
Platform: v.Platform,
UserID: v.UserID,
@@ -179,8 +179,8 @@ func (convert) Log(v mysqlModel.Log) mongoModel.LogModel {
}
}
-func (convert) SignalModel(v mysqlModelRtc.SignalModel) mongoModelRtc.SignalModel {
- return mongoModelRtc.SignalModel{
+func (convert) SignalModel(v mysqlmodelrtc.SignalModel) mongomodelrtc.SignalModel {
+ return mongomodelrtc.SignalModel{
SID: v.SID,
InviterUserID: v.InviterUserID,
CustomData: v.CustomData,
@@ -202,8 +202,8 @@ func (convert) SignalModel(v mysqlModelRtc.SignalModel) mongoModelRtc.SignalMode
}
}
-func (convert) SignalInvitationModel(v mysqlModelRtc.SignalInvitationModel) mongoModelRtc.SignalInvitationModel {
- return mongoModelRtc.SignalInvitationModel{
+func (convert) SignalInvitationModel(v mysqlmodelrtc.SignalInvitationModel) mongomodelrtc.SignalInvitationModel {
+ return mongomodelrtc.SignalInvitationModel{
SID: v.SID,
UserID: v.UserID,
Status: v.Status,
@@ -212,8 +212,8 @@ func (convert) SignalInvitationModel(v mysqlModelRtc.SignalInvitationModel) mong
}
}
-func (convert) Meeting(v mysqlModelRtc.MeetingInfo) mongoModelRtc.MeetingInfo {
- return mongoModelRtc.MeetingInfo{
+func (convert) Meeting(v mysqlmodelrtc.MeetingInfo) mongomodelrtc.MeetingInfo {
+ return mongomodelrtc.MeetingInfo{
RoomID: v.RoomID,
MeetingName: v.MeetingName,
HostUserID: v.HostUserID,
@@ -225,16 +225,16 @@ func (convert) Meeting(v mysqlModelRtc.MeetingInfo) mongoModelRtc.MeetingInfo {
}
}
-func (convert) MeetingInvitationInfo(v mysqlModelRtc.MeetingInvitationInfo) mongoModelRtc.MeetingInvitationInfo {
- return mongoModelRtc.MeetingInvitationInfo{
+func (convert) MeetingInvitationInfo(v mysqlmodelrtc.MeetingInvitationInfo) mongomodelrtc.MeetingInvitationInfo {
+ return mongomodelrtc.MeetingInvitationInfo{
RoomID: v.RoomID,
UserID: v.UserID,
CreateTime: v.CreateTime,
}
}
-func (convert) MeetingVideoRecord(v mysqlModelRtc.MeetingVideoRecord) mongoModelRtc.MeetingVideoRecord {
- return mongoModelRtc.MeetingVideoRecord{
+func (convert) MeetingVideoRecord(v mysqlmodelrtc.MeetingVideoRecord) mongomodelrtc.MeetingVideoRecord {
+ return mongomodelrtc.MeetingVideoRecord{
RoomID: v.RoomID,
FileURL: v.FileURL,
CreateTime: v.CreateTime,
diff --git a/tools/up35/pkg/pkg.go b/tools/up35/pkg/pkg.go
index 6d16817ec..b7e7c01f5 100644
--- a/tools/up35/pkg/pkg.go
+++ b/tools/up35/pkg/pkg.go
@@ -29,14 +29,14 @@ import (
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
- gormMysql "gorm.io/driver/mysql"
+ gormmysql "gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
- rtcMgo "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mongo/mgo"
+ rtcmgo "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mongo/mgo"
)
const (
@@ -56,7 +56,7 @@ func InitConfig(path string) error {
func GetMysql() (*gorm.DB, error) {
conf := config.Config.Mysql
mysqlDSN := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", conf.Username, conf.Password, conf.Address[0], conf.Database)
- return gorm.Open(gormMysql.Open(mysqlDSN), &gorm.Config{Logger: logger.Discard})
+ return gorm.Open(gormmysql.Open(mysqlDSN), &gorm.Config{Logger: logger.Discard})
}
func GetMongo() (*mongo.Database, error) {
@@ -116,11 +116,11 @@ func Main(path string) error {
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewS3Mongo, c.Object(config.Config.Object.Enable)) },
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewLogMongo, c.Log) },
- func() error { return NewTask(mysqlDB, mongoDB, rtcMgo.NewSignal, c.SignalModel) },
- func() error { return NewTask(mysqlDB, mongoDB, rtcMgo.NewSignalInvitation, c.SignalInvitationModel) },
- func() error { return NewTask(mysqlDB, mongoDB, rtcMgo.NewMeeting, c.Meeting) },
- func() error { return NewTask(mysqlDB, mongoDB, rtcMgo.NewMeetingInvitation, c.MeetingInvitationInfo) },
- func() error { return NewTask(mysqlDB, mongoDB, rtcMgo.NewMeetingRecord, c.MeetingVideoRecord) },
+ func() error { return NewTask(mysqlDB, mongoDB, rtcmgo.NewSignal, c.SignalModel) },
+ func() error { return NewTask(mysqlDB, mongoDB, rtcmgo.NewSignalInvitation, c.SignalInvitationModel) },
+ func() error { return NewTask(mysqlDB, mongoDB, rtcmgo.NewMeeting, c.Meeting) },
+ func() error { return NewTask(mysqlDB, mongoDB, rtcmgo.NewMeetingInvitation, c.MeetingInvitationInfo) },
+ func() error { return NewTask(mysqlDB, mongoDB, rtcmgo.NewMeetingRecord, c.MeetingVideoRecord) },
)
for _, task := range tasks {
diff --git a/tools/yamlfmt/OWNERS b/tools/yamlfmt/OWNERS
deleted file mode 100644
index b7a5428e7..000000000
--- a/tools/yamlfmt/OWNERS
+++ /dev/null
@@ -1,10 +0,0 @@
-# See the OWNERS docs at https://go.k8s.io/owners
-
-reviewers:
- - cubxxw
- - kubbot
-approvers:
- - cubxxw
-labels:
- - sig/testing
- - sig/contributor-experience
\ No newline at end of file
From 955520471fc47b2315cadc355ebb5c09026a81a9 Mon Sep 17 00:00:00 2001
From: AndrewZuo01 <59896149+AndrewZuo01@users.noreply.github.com>
Date: Fri, 12 Jan 2024 18:58:29 +0800
Subject: [PATCH 13/20] Rename devcontainer.json to devcontainer.json (#1756)
---
{.devcontainer => .devcontainer}/devcontainer.json | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename {.devcontainer => .devcontainer}/devcontainer.json (100%)
diff --git a/.devcontainer /devcontainer.json b/.devcontainer/devcontainer.json
similarity index 100%
rename from .devcontainer /devcontainer.json
rename to .devcontainer/devcontainer.json
From 0375361294b4dbc320fd4a795b4f86d6a2491bed Mon Sep 17 00:00:00 2001
From: Xinwei Xiong <3293172751@qq.com>
Date: Fri, 12 Jan 2024 20:12:38 +0800
Subject: [PATCH 14/20] Rename README.md to README.md (#1757)
---
{.devcontainer => .devcontainer}/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
rename {.devcontainer => .devcontainer}/README.md (99%)
diff --git a/.devcontainer /README.md b/.devcontainer/README.md
similarity index 99%
rename from .devcontainer /README.md
rename to .devcontainer/README.md
index 7abba5ac1..24778f8ee 100644
--- a/.devcontainer /README.md
+++ b/.devcontainer/README.md
@@ -137,4 +137,4 @@ In addition, you can also configure Codespaces secrets on your personal profile
The container comes with VS Code Insiders installed. To run it from an Integrated Terminal use `VSCODE_IPC_HOOK_CLI= /usr/bin/code-insiders .`.
-[def]: https://www.realvnc.com/en/connect/download/viewer/
\ No newline at end of file
+[def]: https://www.realvnc.com/en/connect/download/viewer/
From a24eedb66d57c5301bc00b9b5d264acc412ad52a Mon Sep 17 00:00:00 2001
From: Xinwei Xiong <3293172751@qq.com>
Date: Fri, 12 Jan 2024 21:17:45 +0800
Subject: [PATCH 15/20] Update docker-compose.yml (#1759)
---
docker-compose.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docker-compose.yml b/docker-compose.yml
index de4b30d48..9496fe76a 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -119,7 +119,7 @@ services:
- OPENIM_WEB_PORT=${OPENIM_WEB_PORT:-11001}
restart: always
ports:
- - "${OPENIM_WEB_PORT:-11001}:11001"
+ - "${OPENIM_WEB_PORT:-11001}:80"
networks:
server:
ipv4_address: ${OPENIM_WEB_NETWORK_ADDRESS:-172.28.0.7}
From fdf055d328627a6bbc0053f11869f3f88a5e531a Mon Sep 17 00:00:00 2001
From: Xinwei Xiong <3293172751@qq.com>
Date: Fri, 12 Jan 2024 22:02:56 +0800
Subject: [PATCH 16/20] fix: mac deployment (#1761)
---
scripts/lib/util.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/lib/util.sh b/scripts/lib/util.sh
index 1ec722d8f..f15a26346 100755
--- a/scripts/lib/util.sh
+++ b/scripts/lib/util.sh
@@ -311,7 +311,7 @@ openim::util::check_ports() {
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
# For macOS, use lsof
- info=$(lsof -i:"$port" | grep "\*:$port" || true)
+ info=$(lsof -P -i:"$port" | grep "LISTEN" || true)
fi
# Check if any process is using the port
From 98d36461677dc82b8fb9b1c3dad23ab565f9bbc6 Mon Sep 17 00:00:00 2001
From: Xinwei Xiong <3293172751NSS@gmail.com>
Date: Sat, 13 Jan 2024 09:38:52 +0800
Subject: [PATCH 17/20] Stability Enhancement: Pin Docker Compose Images for
minio and openim-web (#1762)
* Update docker-compose.yml
* Update docker-compose.yml
* Update docker-compose.yml
---
docker-compose.yml | 53 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 50 insertions(+), 3 deletions(-)
diff --git a/docker-compose.yml b/docker-compose.yml
index 9496fe76a..78632f163 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -94,7 +94,7 @@ services:
ipv4_address: ${KAFKA_NETWORK_ADDRESS:-172.28.0.4}
minio:
- image: minio/minio:${MINIO_IMAGE_VERSION:-latest}
+ image: minio/minio:${MINIO_IMAGE_VERSION:-RELEASE.2024-01-11T07-46-16Z}
ports:
- "${MINIO_PORT:-10005}:9000"
- "9090:9090"
@@ -112,7 +112,7 @@ services:
ipv4_address: ${MINIO_NETWORK_ADDRESS:-172.28.0.6}
openim-web:
- image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-web:${OPENIM_WEB_IMAGE_VERSION:-latest}
+ image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-web:${OPENIM_WEB_IMAGE_VERSION:-v3.5.0-docker}
container_name: openim-web
environment:
- OPENIM_WEB_DIST_PATH=${OPENIM_WEB_DIST_PATH:-/app/dist}
@@ -127,8 +127,55 @@ services:
### TODO: Uncomment, or deploy using openim docker: https://github.com/openimsdk/openim-docker
# Uncomment and configure the following services as needed
+ # openim-server:
+ # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-server:${SERVER_IMAGE_VERSION:-main}
+ # container_name: openim-server
+ # ports:
+ # - "${OPENIM_WS_PORT:-10001}:${OPENIM_WS_PORT:-10001}"
+ # - "${API_OPENIM_PORT:-10002}:${API_OPENIM_PORT:-10002}"
+ # - "${API_PROM_PORT:-20100}:${API_PROM_PORT:-20100}"
+ # - "${USER_PROM_PORT:-20110}:${USER_PROM_PORT:-20110}"
+ # - "${FRIEND_PROM_PORT:-20120}:${FRIEND_PROM_PORT:-20120}"
+ # - "${MESSAGE_PROM_PORT:-20130}:${MESSAGE_PROM_PORT:-20130}"
+ # - "${MSG_GATEWAY_PROM_PORT:-20140}:${MSG_GATEWAY_PROM_PORT:-20140}"
+ # - "${GROUP_PROM_PORT:-20150}:${GROUP_PROM_PORT:-20150}"
+ # - "${AUTH_PROM_PORT:-20160}:${AUTH_PROM_PORT:-20160}"
+ # - "${PUSH_PROM_PORT:-20170}:${PUSH_PROM_PORT:-20170}"
+ # - "${CONVERSATION_PROM_PORT:-20230}:${CONVERSATION_PROM_PORT:-20230}"
+ # - "${RTC_PROM_PORT:-21300}:${RTC_PROM_PORT:-21300}"
+ # - "${THIRD_PROM_PORT:-21301}:${THIRD_PROM_PORT:-21301}"
+ # - "21400-21403:21400-21403"
+ # healthcheck:
+ # test: ["CMD", "/openim/openim-server/scripts/check-all.sh"]
+ # interval: 120s
+ # timeout: 30s
+ # retries: 5
+ # env_file:
+ # - .env
+ # environment:
+ # - OPENIM_IP=${OPENIM_IP:-127.0.0.1}
+ # volumes:
+ # - "${DATA_DIR:-./}/openim-server/logs:/openim/openim-server/logs"
+ # - "${DATA_DIR:-./}/openim-server/_output/logs:/openim/openim-server/_output/logs"
+ # - "${DATA_DIR:-./}/openim-server/config:/openim/openim-server/config"
+ # restart: always
+ # depends_on:
+ # - kafka
+ # - mysql
+ # - mongodb
+ # - redis
+ # - minio
+ # logging:
+ # driver: json-file
+ # options:
+ # max-size: "1g"
+ # max-file: "2"
+ # networks:
+ # server:
+ # ipv4_address: ${OPENIM_SERVER_NETWORK_ADDRESS:-172.28.0.8}
+
# openim-chat:
- # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-chat:${CHAT_IMAGE_VERSION:-latest}
+ # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-chat:${CHAT_IMAGE_VERSION:-main}
# container_name: openim-chat
# healthcheck:
# test: ["CMD", "/openim/openim-chat/scripts/check_all.sh"]
From 64d6b0432087551313a8ea01eab9b28f204b6dfa Mon Sep 17 00:00:00 2001
From: Xinwei Xiong <3293172751NSS@gmail.com>
Date: Mon, 15 Jan 2024 16:39:44 +0800
Subject: [PATCH 18/20] feat: add openim docker compose deployment github
comment (#1769)
* feat: add openim v3.4 and v3.5 changelog
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* feat: add openim github comment
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* fix: fix openim docker compose images version form github comment
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* fix: fix openim docker compose images version form github comment
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
---------
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
---
config/templates/env.template | 8 --------
deployments/templates/env-template.yaml | 4 ----
docker-compose.yml | 10 ++--------
scripts/install/environment.sh | 2 --
tools/openim-web/README.md | 1 -
5 files changed, 2 insertions(+), 23 deletions(-)
diff --git a/config/templates/env.template b/config/templates/env.template
index ffcec89e5..a606704c5 100644
--- a/config/templates/env.template
+++ b/config/templates/env.template
@@ -176,18 +176,10 @@ GRAFANA_PORT=13000
# ============ OpenIM Web ===============
# ======================================
-# Path to the OpenIM web distribution.
-# Default: OPENIM_WEB_DIST_PATH=/app/dist
-OPENIM_WEB_DIST_PATH=/app/dist
-
# Port on which OpenIM web service is running.
# Default: OPENIM_WEB_PORT=11001
OPENIM_WEB_PORT=11001
-# Address or hostname for the OpenIM web service.
-# Default: OPENIM_WEB_ADDRESS=172.28.0.1
-OPENIM_WEB_ADDRESS=172.28.0.7
-
# ======================================
# ========= OpenIM Server ==============
# ======================================
diff --git a/deployments/templates/env-template.yaml b/deployments/templates/env-template.yaml
index e7166ff2d..cbe900c19 100644
--- a/deployments/templates/env-template.yaml
+++ b/deployments/templates/env-template.yaml
@@ -171,10 +171,6 @@ GRAFANA_PORT=${GRAFANA_PORT}
# ============ OpenIM Web ===============
# ======================================
-# Path to the OpenIM web distribution.
-# Default: OPENIM_WEB_DIST_PATH=/app/dist
-OPENIM_WEB_DIST_PATH=${OPENIM_WEB_DIST_PATH}
-
# Port on which OpenIM web service is running.
# Default: OPENIM_WEB_PORT=11001
OPENIM_WEB_PORT=${OPENIM_WEB_PORT}
diff --git a/docker-compose.yml b/docker-compose.yml
index 78632f163..e4449b5ad 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -114,9 +114,6 @@ services:
openim-web:
image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-web:${OPENIM_WEB_IMAGE_VERSION:-v3.5.0-docker}
container_name: openim-web
- environment:
- - OPENIM_WEB_DIST_PATH=${OPENIM_WEB_DIST_PATH:-/app/dist}
- - OPENIM_WEB_PORT=${OPENIM_WEB_PORT:-11001}
restart: always
ports:
- "${OPENIM_WEB_PORT:-11001}:80"
@@ -201,9 +198,6 @@ services:
# - "${DATA_DIR:-./}/components/openim-chat/config:/openim/openim-chat/config"
# restart: always
# # user: root:root
- # depends_on:
- # openim-server:
- # condition: service_healthy
# logging:
# driver: json-file
# options:
@@ -215,8 +209,8 @@ services:
# openim-admin:
# # https://github.com/openimsdk/open-im-server/issues/1662
- # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-admin:${ADMIN_FRONT_VERSION:-toc-base-open-docker.35}
- # container_name: openim-admin
+ # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-admin:${ADMIN_FRONT_VERSION:-toc-base-open-docker.35}
+ # container_name: openim-admin
# restart: always
# ports:
# - "${OPENIM_ADMIN_FRONT_PORT:-11002}:80"
diff --git a/scripts/install/environment.sh b/scripts/install/environment.sh
index f84cb924a..41a70c64d 100755
--- a/scripts/install/environment.sh
+++ b/scripts/install/environment.sh
@@ -243,8 +243,6 @@ def "KAFKA_CONSUMERGROUPID_PUSH" "push" # `Kafka` 的消费
###################### openim-web 配置信息 ######################
def "OPENIM_WEB_PORT" "11001" # openim-web的端口
-def "OPENIM_WEB_ADDRESS" "${DOCKER_BRIDGE_GATEWAY}" # openim-web的地址
-def "OPENIM_WEB_DIST_PATH" "/app/dist" # openim-web的dist路径
###################### openim-admin-front 配置信息 ######################
def "OPENIM_ADMIN_FRONT_PORT" "11002" # openim-admin-front的端口
diff --git a/tools/openim-web/README.md b/tools/openim-web/README.md
index afd5e9a96..5794a946d 100644
--- a/tools/openim-web/README.md
+++ b/tools/openim-web/README.md
@@ -37,7 +37,6 @@ Variables can be set as above, Environment variables can also be set
example:
```bash
-$ export OPENIM_WEB_DIST_PATH="/app/dist"
$ export OPENIM_WEB_PPRT="11001"
```
From 080ddb82cd2294902d277b1b2766a152ecbcd62e Mon Sep 17 00:00:00 2001
From: AndrewZuo01 <59896149+AndrewZuo01@users.noreply.github.com>
Date: Tue, 16 Jan 2024 14:34:41 +0800
Subject: [PATCH 19/20] fix(main): add more cases for get_users api, so it
accept users in older version. feat(main): also add search functionality
(#1751)
* update set pin friends
* update set pin friends
* update set pin friends
* update set pin friends
* update set pin friends
* update set pin friends
* fix bugs
* fix bugs
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* debug
* Update go.mod
* Update friend.go
* debug
* debug
* debug
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* add pin friend test
* I cannot solve todo in test.sh
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* update user command
* Update go.mod
* fix group notification
* fix group notification
* update openimsdk tools
* update openim server remove duplicate code
* update openim server remove duplicate code
* update user command get
* update user command get
* update response of callback response error
* update black ex
* update join group ex
* update user pb2map
* update go sum
* update go sum
* update updateUserInfoEx
* update updateUserInfoEx
* update updateUserInfoEx add callback functions
* fix dismiss group function
* fix dismiss group function
* fix dismiss group function
* fix dismiss group function
* update pin friend to update friend
* fix go mod
* fix err golangci-lint
* fix UserPb2DBMap
* update comments, update go.mod check for register username
* update comments, update go.mod check for register username
* update comments, update go.mod check for register username
* update comments, update go.mod check for register username
* fix callback
* fix go.mod
* fix debug
* fix bugs
* update notification
* update notification
* update notification
* update notification
* update notification
* update notification
* update notification
* update notification
* fix updateUserInfoEx
* fix updateUserInfoEx
* modify go.mod
* fix updateUserInfoEx
* fix updateUserInfoEx
* fix: fix the bug
* fix: fix the imAdmin permission and searchNoficitaion resp
* fix updateUserInfoEx
* 2023 Annual Summary Reflections and Aspirations
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* fix: dissmissGroup and lack of keyword bug (#1678)
* Update docker-start-all.sh
* Update env-template.yaml
* update user command notification
* Update docker-start-all.sh
* fix openim config mongo passwd env
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
* update user command get all notification
* update user command get all notification
* fix type = 0
* fix type = 0
* fix type = 0
* fix type = 0
* fix type = 0
* fix type = 0
* fix typing cause callback
* add ex to usercommand
* add ex to usercommand
* update updatefriends
* fix updatefriend map
* fix updatefriend FriendsInfoUpdateNotification
* fix push online and offline user, but why typing trigger callback push?
* fix push online and offline user, but why typing trigger callback push?
* update user command record not found and user access check
* update user command get all user access check
* update go.mod
* fix callback name and place
* fix: fix some bug
* fix: group messages sync failed.
* upadtae callback test
* fix callback typing
* fix callback typing
* fix callback typing
* fix callback typing
* fix lint on processusercommand
* fix: fix the valiable name
* fix: fix the getSortedConversation api
* fix: fix the mongo search error
* fix: GroupApplicationAcceptedNotification
(cherry picked from commit 4c3c4555a35ec8e31ffbf3e96a5dba3bceec09ee)
* fix: GroupApplicationAcceptedNotification
* fix update friends
* fix pageFindUser
* fix pageFindUser
* fix pageFindUser
* fix pageFindUser
* Delete .devcontainer directory
* revert
* more powerful PageFindUserWithKeyword
* more powerful PageFindUserWithKeyword
* more powerful PageFindUserWithKeyword
---------
Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
Co-authored-by: Xinwei Xiong <3293172751@qq.com>
Co-authored-by: luhaoling <2198702716@qq.com>
Co-authored-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
Co-authored-by: Brabem <69128477+luhaoling@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>
Co-authored-by: OpenIM Robot <139873238+openimbot@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
---
go.mod | 3 +++
internal/rpc/user/user.go | 28 +++++++++++++++-----
pkg/common/db/controller/user.go | 13 +++++++---
pkg/common/db/mgo/user.go | 39 ++++++++++++++++++++++++++--
pkg/common/db/table/relation/user.go | 3 ++-
5 files changed, 73 insertions(+), 13 deletions(-)
diff --git a/go.mod b/go.mod
index 5e8e7275b..b0eda8970 100644
--- a/go.mod
+++ b/go.mod
@@ -156,3 +156,6 @@ require (
golang.org/x/crypto v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
+replace (
+ github.com/OpenIMSDK/protocol v0.0.47 => github.com/AndrewZuo01/protocol v0.0.0-20240112093520-fd9c53e27b94
+)
\ No newline at end of file
diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go
index 158e37d70..f647d6686 100644
--- a/internal/rpc/user/user.go
+++ b/internal/rpc/user/user.go
@@ -229,11 +229,20 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR
}
func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPaginationUsersReq) (resp *pbuser.GetPaginationUsersResp, err error) {
- total, users, err := s.PageFindUser(ctx, constant.IMOrdinaryUser, req.Pagination)
- if err != nil {
- return nil, err
+ if req.UserID == "" && req.UserName == "" {
+ total, users, err := s.PageFindUser(ctx, constant.IMOrdinaryUser, constant.AppOrdinaryUsers, req.Pagination)
+ if err != nil {
+ return nil, err
+ }
+ return &pbuser.GetPaginationUsersResp{Total: int32(total), Users: convert.UsersDB2Pb(users)}, err
+ } else {
+ total, users, err := s.PageFindUserWithKeyword(ctx, constant.IMOrdinaryUser, constant.AppOrdinaryUsers, req.UserID, req.UserName, req.Pagination)
+ if err != nil {
+ return nil, err
+ }
+ return &pbuser.GetPaginationUsersResp{Total: int32(total), Users: convert.UsersDB2Pb(users)}, err
}
- return &pbuser.GetPaginationUsersResp{Total: int32(total), Users: convert.UsersDB2Pb(users)}, err
+
}
func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterReq) (resp *pbuser.UserRegisterResp, err error) {
@@ -591,31 +600,38 @@ func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context, req *pbu
}
func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.SearchNotificationAccountReq) (*pbuser.SearchNotificationAccountResp, error) {
+ // Check if user is an admin
if err := authverify.CheckIMAdmin(ctx); err != nil {
return nil, err
}
var users []*relation.UserModel
var err error
+
+ // If a keyword is provided in the request
if req.Keyword != "" {
+ // Find users by keyword
users, err = s.UserDatabase.Find(ctx, []string{req.Keyword})
if err != nil {
return nil, err
}
+
+ // Convert users to response format
resp := s.userModelToResp(users, req.Pagination)
if resp.Total != 0 {
return resp, nil
}
+
+ // Find users by nickname if no users found by keyword
users, err = s.UserDatabase.FindByNickname(ctx, req.Keyword)
if err != nil {
return nil, err
}
resp = s.userModelToResp(users, req.Pagination)
return resp, nil
-
- return resp, nil
}
+ // If no keyword, find users with notification settings
users, err = s.UserDatabase.FindNotification(ctx, constant.AppNotificationAdmin)
if err != nil {
return nil, err
diff --git a/pkg/common/db/controller/user.go b/pkg/common/db/controller/user.go
index cedae5c97..b1cace955 100644
--- a/pkg/common/db/controller/user.go
+++ b/pkg/common/db/controller/user.go
@@ -48,10 +48,12 @@ type UserDatabase interface {
//Update(ctx context.Context, user *relation.UserModel) (err error)
// UpdateByMap update (zero value) external guarantee userID exists
UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error)
+ // FindUser
+ PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
+ //FindUser with keyword
+ PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID string, userName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
// Page If not found, no error is returned
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
- // FindUser
- PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
// IsExist true as long as one exists
IsExist(ctx context.Context, userIDs []string) (exist bool, err error)
// GetAllUserID Get all user IDs
@@ -185,8 +187,11 @@ func (u *userDatabase) Page(ctx context.Context, pagination pagination.Paginatio
return u.userDB.Page(ctx, pagination)
}
-func (u *userDatabase) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
- return u.userDB.PageFindUser(ctx, level, pagination)
+func (u *userDatabase) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
+ return u.userDB.PageFindUser(ctx, level1, level2, pagination)
+}
+func (u *userDatabase) PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, userName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
+ return u.userDB.PageFindUserWithKeyword(ctx, level1, level2, userID, userName, pagination)
}
// IsExist Does userIDs exist? As long as there is one, it will be true.
diff --git a/pkg/common/db/mgo/user.go b/pkg/common/db/mgo/user.go
index b07f82928..3ab71b209 100644
--- a/pkg/common/db/mgo/user.go
+++ b/pkg/common/db/mgo/user.go
@@ -18,6 +18,7 @@ import (
"context"
"github.com/OpenIMSDK/protocol/user"
"github.com/OpenIMSDK/tools/errs"
+ "go.mongodb.org/mongo-driver/bson/primitive"
"time"
"github.com/OpenIMSDK/tools/mgoutil"
@@ -78,8 +79,42 @@ func (u *UserMgo) Page(ctx context.Context, pagination pagination.Pagination) (c
return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, pagination)
}
-func (u *UserMgo) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
- return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{"app_manger_level": level}, pagination)
+func (u *UserMgo) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
+ query := bson.M{
+ "$or": []bson.M{
+ {"app_manger_level": level1},
+ {"app_manger_level": level2},
+ },
+ }
+
+ return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, query, pagination)
+}
+func (u *UserMgo) PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID string, userName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
+ // Initialize the base query with level conditions
+ query := bson.M{
+ "$and": []bson.M{
+ {"app_manger_level": bson.M{"$in": []int64{level1, level2}}},
+ },
+ }
+
+ // Add userID and userName conditions to the query if they are provided
+ if userID != "" || userName != "" {
+ userConditions := []bson.M{}
+ if userID != "" {
+ // Use regex for userID
+ regexPattern := primitive.Regex{Pattern: userID, Options: "i"} // 'i' for case-insensitive matching
+ userConditions = append(userConditions, bson.M{"user_id": regexPattern})
+ }
+ if userName != "" {
+ // Use regex for userName
+ regexPattern := primitive.Regex{Pattern: userName, Options: "i"} // 'i' for case-insensitive matching
+ userConditions = append(userConditions, bson.M{"nickname": regexPattern})
+ }
+ query["$and"] = append(query["$and"].([]bson.M), bson.M{"$or": userConditions})
+ }
+
+ // Perform the paginated search
+ return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, query, pagination)
}
func (u *UserMgo) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) {
diff --git a/pkg/common/db/table/relation/user.go b/pkg/common/db/table/relation/user.go
index a1b4269d1..8d40a8f67 100644
--- a/pkg/common/db/table/relation/user.go
+++ b/pkg/common/db/table/relation/user.go
@@ -56,7 +56,8 @@ type UserModelInterface interface {
TakeNotification(ctx context.Context, level int64) (user []*UserModel, err error)
TakeByNickname(ctx context.Context, nickname string) (user []*UserModel, err error)
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*UserModel, err error)
- PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*UserModel, err error)
+ PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*UserModel, err error)
+ PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, userName string, pagination pagination.Pagination) (count int64, users []*UserModel, err error)
Exist(ctx context.Context, userID string) (exist bool, err error)
GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, err error)
GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error)
From 4e8fef558e06248778af5bd820ad613d0546f002 Mon Sep 17 00:00:00 2001
From: AndrewZuo01 <59896149+AndrewZuo01@users.noreply.github.com>
Date: Tue, 16 Jan 2024 17:25:20 +0800
Subject: [PATCH 20/20] Update user.go
---
internal/rpc/user/user.go | 4 ----
1 file changed, 4 deletions(-)
diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go
index 4ca10166c..9366fd11a 100644
--- a/internal/rpc/user/user.go
+++ b/internal/rpc/user/user.go
@@ -59,10 +59,6 @@ type userServer struct {
RegisterCenter registry.SvcDiscoveryRegistry
}
-func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.ProcessUserCommandGetAllReq) (*pbuser.ProcessUserCommandGetAllResp, error) {
- //TODO implement me
- panic("implement me")
-}
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
rdb, err := cache.NewRedis()