feat(main): 🚀 Database Name Correction and S3 Module Int32 Overflow Fix with Go Routine Integration for Automated Checks and Script Optimization (#1799)

* feat: replace mongo database openIM_v3 to openim_v3

* openim-building-an-efficient-version-control-and-testing-workflow

* feat: complete openim source deployment rpc start timeout

* feat: optimize config

Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>

* feat: add scripts format

* feat: use scripts format code

* fix cos and minio etc to typecheck

* feat: scripts make verify check ci

* fix: make file verify spelling

* fix: make file verify spelling

* Concurrent Type Checking and Cross-Platform Development in Go

* feat: add copyright make lint and format

* feat: add config examples file

Signed-off-by: Xinwei Xiong <3293172751@qq.com>

* feat: add config examples file

Signed-off-by: Xinwei Xiong <3293172751@qq.com>

---------

Signed-off-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
Signed-off-by: Xinwei Xiong <3293172751@qq.com>
pull/1816/head
Xinwei Xiong 5 months ago committed by GitHub
parent fa55c44113
commit d356f7a035
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -2,7 +2,6 @@
// Reference Doc: https://code.visualstudio.com/remote/advancedcontainers/overview // Reference Doc: https://code.visualstudio.com/remote/advancedcontainers/overview
"name": "OpenIM Dev Environment", "name": "OpenIM Dev Environment",
// Update the container version when you publish dev-container // Update the container version when you publish dev-container
"dockerComposeFile": "docker-compose.yml",
"build": { "dockerfile": "Dockerfile" }, "build": { "dockerfile": "Dockerfile" },
// Replace with uncommented line below to build your own local copy of the image // Replace with uncommented line below to build your own local copy of the image
// "dockerFile": "../docker/Dockerfile-dev", // "dockerFile": "../docker/Dockerfile-dev",

@ -17,6 +17,7 @@ on:
issues: issues:
types: types:
- labeled - labeled
jobs: jobs:
add-comment: add-comment:
if: github.event.label.name == 'help wanted' || github.event.label.name == 'good first issue' if: github.event.label.name == 'help wanted' || github.event.label.name == 'good first issue'

@ -23,6 +23,8 @@ on:
- "docs/**" - "docs/**"
- "README.md" - "README.md"
- "README_zh-CN.md" - "README_zh-CN.md"
- "**.md"
- "docs/**"
- "CONTRIBUTING.md" - "CONTRIBUTING.md"
pull_request: pull_request:
branches: branches:
@ -31,7 +33,8 @@ on:
paths-ignore: paths-ignore:
- "README.md" - "README.md"
- "README_zh-CN.md" - "README_zh-CN.md"
- "CONTRIBUTING.md" - "CONTRIBUTING/**"
- "**.md"
- "docs/**" - "docs/**"
env: env:
@ -67,6 +70,9 @@ jobs:
version: '3.x' # If available, use the latest major version that's compatible version: '3.x' # If available, use the latest major version that's compatible
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: OpenIM Scripts Verification(make verify)
run: sudo make verify
- name: Module Operations - name: Module Operations
run: | run: |
sudo make tidy sudo make tidy
@ -91,13 +97,6 @@ jobs:
- name: Cleanup Build - name: Cleanup Build
run: sudo make clean run: sudo make clean
- name: Push Changes to Main
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "cicd: robot automated Change"
branch: main
continue-on-error: true
- name: Set Current Directory - name: Set Current Directory
id: set_directory id: set_directory
run: echo "::set-output name=directory::$(pwd)" run: echo "::set-output name=directory::$(pwd)"

1
.gitignore vendored

@ -34,6 +34,7 @@ deployments/charts/generated-configs/
### OpenIM Config ### ### OpenIM Config ###
.env .env
config/config.yaml config/config.yaml
config/openim.yaml
config/alertmanager.yml config/alertmanager.yml
config/prometheus.yml config/prometheus.yml
config/email.tmpl config/email.tmpl

@ -1,15 +0,0 @@
# Version logging for OpenIM
<!-- BEGIN MUNGE: GENERATED_TOC -->
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v3.5.0+3.97baaac"></a>
## [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

@ -42,7 +42,7 @@ OpenIM is a service platform specifically designed for integrating chat, audio-v
- 🛡️ API wrapping - 🛡️ API wrapping
- 🌐 Connection management - 🌐 Connection management
## 📚 Main Modules: + 📚 Main Modules:
1. 🚀 Initialization and Login 1. 🚀 Initialization and Login
2. 👤 User Management 2. 👤 User Management
@ -70,11 +70,16 @@ It is built using Golang and supports cross-platform deployment, ensuring a cons
## :rocket: Quick Start ## :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/)**
🤲 To facilitate user experience, we offer various deployment solutions. You can choose your deployment method from 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)** + **[Source Code Deployment Guide](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
+ **[Docker Deployment Guide](https://docs.openim.io/guides/gettingStarted/dockerCompose)** + **[Docker Deployment Guide](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
+ **[Kubernetes Deployment Guide](https://docs.openim.io/guides/gettingStarted/k8s-deployment)** + **[Kubernetes Deployment Guide](https://docs.openim.io/guides/gettingStarted/k8s-deployment)**
+ **[Mac Developer Deployment Guide](https://docs.openim.io/guides/gettingstarted/mac-deployment-guide)**
## :hammer_and_wrench: To Start Developing OpenIM ## :hammer_and_wrench: To Start Developing OpenIM

@ -14,7 +14,7 @@
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# TODO: This config file is the template file # TODO: This config file is the template file
# --| source: deployments/templates/openim.yaml # --| source: deployments/templates/config.yaml
# --| env: scripts/install/environment # --| env: scripts/install/environment
# --| target: config/config.yaml # --| target: config/config.yaml
# ----------------------------------------------------------------- # -----------------------------------------------------------------
@ -52,8 +52,8 @@ mongo:
# Default MongoDB database name # Default MongoDB database name
# Maximum connection pool size # Maximum connection pool size
address: [ 172.28.0.1:37017 ] address: [ 172.28.0.1:37017 ]
database: openIM_v3 database: openim_v3
username: root username: openIM
password: openIM123 password: openIM123
maxPoolSize: 100 maxPoolSize: 100
@ -122,14 +122,14 @@ api:
# minio.signEndpoint is minio public network address # minio.signEndpoint is minio public network address
object: object:
enable: "minio" enable: "minio"
apiURL: "http://14.155.64.202:10002" apiURL: "http://172.28.0.1:10002"
minio: minio:
bucket: "openim" bucket: "openim"
endpoint: "http://172.28.0.1:10005" endpoint: "http://172.28.0.1:10005"
accessKeyID: "root" accessKeyID: "root"
secretAccessKey: "openIM123" secretAccessKey: "openIM123"
sessionToken: '' sessionToken: ''
signEndpoint: "http://14.155.64.202:10005" signEndpoint: "http://172.28.0.1:10005"
publicRead: false publicRead: false
cos: cos:
bucketURL: https://temp-1252357374.cos.ap-chengdu.myqcloud.com bucketURL: https://temp-1252357374.cos.ap-chengdu.myqcloud.com
@ -193,7 +193,7 @@ rpcRegisterName:
# Whether to output in json format # Whether to output in json format
# Whether to include stack trace in logs # Whether to include stack trace in logs
log: log:
storageLocation: /data/workspaces/open-im-server/logs/ storageLocation: /workspaces/open-im-server/logs/
rotationTime: 24 rotationTime: 24
remainRotationCount: 2 remainRotationCount: 2
remainLogLevel: 6 remainLogLevel: 6
@ -247,6 +247,14 @@ manager:
userID: [ "openIM123456", "openIM654321", "openIMAdmin" ] userID: [ "openIM123456", "openIM654321", "openIMAdmin" ]
nickname: [ "system1", "system2", "system3" ] nickname: [ "system1", "system2", "system3" ]
# chatAdmin, use for send notification
#
# Built-in app system notification account ID
# Built-in app system notification account nickname
im-admin:
userID: [ "imAdmin" ]
nickname: [ "imAdmin" ]
# Multi-platform login policy # Multi-platform login policy
# For each platform(Android, iOS, Windows, Mac, web), only one can be online at a time # For each platform(Android, iOS, Windows, Mac, web), only one can be online at a time
multiLoginPolicy: 1 multiLoginPolicy: 1
@ -307,21 +315,21 @@ iosPush:
# Timeout in seconds # Timeout in seconds
# Whether to continue execution if callback fails # Whether to continue execution if callback fails
callback: callback:
url: "" url: "http://127.0.0.1:10008/callbackExample"
beforeSendSingleMsg: beforeSendSingleMsg:
enable: false enable: false
timeout: 5 timeout: 5
failedContinue: true failedContinue: true
beforeUpdateUserInfoEx: beforeUpdateUserInfoEx:
enable: false enable: false
timeout: 5 timeout: 5
failedContinue: true failedContinue: true
afterUpdateUserInfoEx: afterUpdateUserInfoEx:
enable: false enable: false
timeout: 5 timeout: 5
failedContinue: true failedContinue: true
afterSendSingleMsg: afterSendSingleMsg:
enable: false enable: true
timeout: 5 timeout: 5
failedContinue: true failedContinue: true
beforeSendGroupMsg: beforeSendGroupMsg:
@ -505,8 +513,8 @@ callback:
# The number of Prometheus ports per service needs to correspond to rpcPort # The number of Prometheus ports per service needs to correspond to rpcPort
# The number of ports needs to be consistent with msg_transfer_service_num in script/path_info.sh # The number of ports needs to be consistent with msg_transfer_service_num in script/path_info.sh
prometheus: prometheus:
enable: false enable: true
grafanaUrl: 172.28.0.1:13000 grafanaUrl: http://172.28.0.1:13000/
apiPrometheusPort: [20100] apiPrometheusPort: [20100]
userPrometheusPort: [ 20110 ] userPrometheusPort: [ 20110 ]
friendPrometheusPort: [ 20120 ] friendPrometheusPort: [ 20120 ]

@ -1,4 +1,4 @@
# Copyright © 2023 OpenIM. All rights reserved. # Copyright © 2024 OpenIM. All rights reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -12,31 +12,26 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# ====================================== # -----------------------------------------------------------------------------
# ========= Basic Configuration ======== # General Configuration
# ====================================== # This section contains general configuration options for the entire environment.
# These options can be set via environment variables. If both environment variables
# The user for authentication or system operations. # and settings in this .env file exist, the environment variables take precedence.
# Default: OPENIM_USER=root # -----------------------------------------------------------------------------
USER=root # ==========================
# General Configuration
# Password associated with the specified user for authentication. # ==========================
# Default: PASSWORD=openIM123 # These settings apply to the overall environment.
PASSWORD=openIM123
# Data storage directory for persistent data.
# Base URL for the application programming interface (API). # Example: DATA_DIR=/path/to/data
# Default: API_URL=http://172.28.0.1:10002 DATA_DIR=/workspaces/open-im-server
API_URL=http://14.155.64.202:10002
# Docker image registry. Uncomment the preferred one.
# Directory path for storing data files or related information. # Options: ghcr.io/openimsdk, openim, registry.cn-hangzhou.aliyuncs.com/openimsdk
# Default: DATA_DIR=./ # IMAGE_REGISTRY="ghcr.io/openimsdk"
DATA_DIR=/data/workspaces/open-im-server # IMAGE_REGISTRY="openim"
# IMAGE_REGISTRY="registry.cn-hangzhou.aliyuncs.com/openimsdk"
# Choose the appropriate image address, the default is GITHUB image,
# you can choose docker hub, for Chinese users can choose Ali Cloud
# export IMAGE_REGISTRY="ghcr.io/openimsdk"
# export IMAGE_REGISTRY="openim"
# export IMAGE_REGISTRY="registry.cn-hangzhou.aliyuncs.com/openimsdk"
IMAGE_REGISTRY=ghcr.io/openimsdk IMAGE_REGISTRY=ghcr.io/openimsdk
# ====================================== # ======================================
@ -47,10 +42,9 @@ IMAGE_REGISTRY=ghcr.io/openimsdk
# Default: DOCKER_BRIDGE_SUBNET=172.28.0.0/16 # Default: DOCKER_BRIDGE_SUBNET=172.28.0.0/16
DOCKER_BRIDGE_SUBNET=172.28.0.0/16 DOCKER_BRIDGE_SUBNET=172.28.0.0/16
# Gateway for the Docker network. # Set and specify the IP addresses of some containers. Generally speaking,
# Default: DOCKER_BRIDGE_GATEWAY=172.28.0.1 # you do not need to modify these configurations to facilitate debugging
DOCKER_BRIDGE_GATEWAY=172.28.0.1 DOCKER_BRIDGE_GATEWAY=172.28.0.1
MONGO_NETWORK_ADDRESS=172.28.0.2 MONGO_NETWORK_ADDRESS=172.28.0.2
REDIS_NETWORK_ADDRESS=172.28.0.3 REDIS_NETWORK_ADDRESS=172.28.0.3
KAFKA_NETWORK_ADDRESS=172.28.0.4 KAFKA_NETWORK_ADDRESS=172.28.0.4
@ -65,45 +59,66 @@ NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.12
OPENIM_ADMIN_FRONT_NETWORK_ADDRESS=172.28.0.13 OPENIM_ADMIN_FRONT_NETWORK_ADDRESS=172.28.0.13
ALERT_MANAGER_NETWORK_ADDRESS=172.28.0.14 ALERT_MANAGER_NETWORK_ADDRESS=172.28.0.14
# =============================================== # ==============================================================================
# = Component Extension Configuration = # Configuration Update Instructions
# =============================================== # ==============================================================================
# This header outlines the methods to update common variables in config.yaml and .env files.
# These instructions are vital for maintaining the OpenIM environment's configuration.
#
# METHOD 1: Regenerate All Configurations
# ----------------------------------------
# Use this method to regenerate all configurations.
# Steps:
# 1. Delete existing config files:
# - openim-server/config/config.yaml
# - openim-chat/config/config.yaml
# 2. Modify the .env file as required.
# 3. Run 'docker compose up -d'. This will regenerate:
# - config/config.yaml
#
# METHOD 2: Modify Individual Configuration Files
# -----------------------------------------------
# Use this method to update specific configuration files.
# Steps:
# 1. Modify the .env file as necessary.
# 2. Update the corresponding entries in:
# - config/config.yaml
# 3. Restart the services with 'docker compose up -d'.
# 4. Special Note: If you modify OPENIM_IP, API_OPENIM_PORT, or MINIO_PORT in .env,
# ensure to update the corresponding services and configurations accordingly.
#
# It is essential to follow these methods to ensure consistent and correct application behavior.
# ==============================================================================
# Local IP address of the service. Modify if necessary.
# Example: OPENIM_IP=172.28.0.1
OPENIM_IP=172.28.0.1
# ============ Component Extension Configuration ==========
# ----- ZooKeeper Configuration ----- # ----- ZooKeeper Configuration -----
# Address or hostname for the ZooKeeper service.
# Default: ZOOKEEPER_ADDRESS=172.28.0.1
ZOOKEEPER_ADDRESS=172.28.0.5
# Port for ZooKeeper service. # Port for ZooKeeper service.
# Default: ZOOKEEPER_PORT=12181 # Default: ZOOKEEPER_PORT=12181
ZOOKEEPER_PORT=12181 ZOOKEEPER_PORT=12181
# ----- MongoDB Configuration ----- # MongoDB service port configuration.
# Address or hostname for the MongoDB service.
# Default: MONGO_ADDRESS=172.28.0.1
MONGO_ADDRESS=172.28.0.2
# Port on which MongoDB service is running.
# Default: MONGO_PORT=37017 # Default: MONGO_PORT=37017
# MONGO_PORT=37017 # MONGO_PORT=37017
# Username to authenticate with the MongoDB service. # Password for MongoDB admin user. Used for service authentication.
# Default: MONGO_USERNAME=root
# MONGO_USERNAME=root
# Password to authenticate with the MongoDB service.
# Default: MONGO_PASSWORD=openIM123 # Default: MONGO_PASSWORD=openIM123
MONGO_PASSWORD=openIM123 MONGO_PASSWORD=openIM123
# Name of the database in MongoDB to be used. # Username for a regular OpenIM user in MongoDB.
# Default: MONGO_DATABASE=openIM_v3 # Default: MONGO_OPENIM_USERNAME=openIM
MONGO_DATABASE=openIM_v3 MONGO_OPENIM_USERNAME=openIM
# Password for a regular OpenIM user in MongoDB.
# Default: MONGO_OPENIM_PASSWORD=openIM123456
MONGO_OPENIM_PASSWORD=openIM123
# Specifies the database name to be used within MongoDB.
# Default: MONGO_DATABASE=openim_v3
MONGO_DATABASE=openim_v3
# ----- Redis Configuration ----- # ----- Redis Configuration -----
# Address or hostname for the Redis service.
# Default: REDIS_ADDRESS=172.28.0.1
REDIS_ADDRESS=172.28.0.3
# Port on which Redis in-memory data structure store is running. # Port on which Redis in-memory data structure store is running.
# Default: REDIS_PORT=16379 # Default: REDIS_PORT=16379
@ -113,11 +128,6 @@ REDIS_PORT=16379
# Default: REDIS_PASSWORD=openIM123 # Default: REDIS_PASSWORD=openIM123
REDIS_PASSWORD=openIM123 REDIS_PASSWORD=openIM123
# ----- Kafka Configuration -----
# Address or hostname for the Kafka service.
# Default: KAFKA_ADDRESS=172.28.0.1
KAFKA_ADDRESS=172.28.0.4
# Kakfa username to authenticate with the Kafka service. # Kakfa username to authenticate with the Kafka service.
# KAFKA_USERNAME='' # KAFKA_USERNAME=''
@ -129,20 +139,13 @@ KAFKA_PORT=19094
# Default: KAFKA_LATESTMSG_REDIS_TOPIC=latestMsgToRedis # Default: KAFKA_LATESTMSG_REDIS_TOPIC=latestMsgToRedis
KAFKA_LATESTMSG_REDIS_TOPIC=latestMsgToRedis KAFKA_LATESTMSG_REDIS_TOPIC=latestMsgToRedis
# Topic in Kafka for pushing messages (e.g. notifications or updates). # MINIO_PORT
# Default: KAFKA_MSG_PUSH_TOPIC=msgToPush # ----------
KAFKA_MSG_PUSH_TOPIC=msgToPush # MINIO_PORT sets the port for the MinIO object storage service.
# Upon changing this port, the MinIO endpoint URLs in the file must be updated
# Topic in Kafka for storing offline messages in MongoDB. # to reflect this change. The endpoints include both the 'endpoint' and 'signEndpoint'
# Default: KAFKA_OFFLINEMSG_MONGO_TOPIC=offlineMsgToMongoMysql # under the MinIO configuration.
KAFKA_OFFLINEMSG_MONGO_TOPIC=offlineMsgToMongoMysql #
# ----- MinIO Configuration ----
# Address or hostname for the MinIO object storage service.
# Default: MINIO_ADDRESS=172.28.0.1
MINIO_ADDRESS=172.28.0.6
# Port on which MinIO object storage service is running.
# Default: MINIO_PORT=10005 # Default: MINIO_PORT=10005
MINIO_PORT=10005 MINIO_PORT=10005
@ -155,19 +158,11 @@ MINIO_PORT=10005
MINIO_SECRET_KEY=openIM123 MINIO_SECRET_KEY=openIM123
# ----- Prometheus Configuration ----- # ----- Prometheus Configuration -----
# Address or hostname for the Prometheus service.
# Default: PROMETHEUS_ADDRESS=172.28.0.1
PROMETHEUS_ADDRESS=172.28.0.10
# Port on which Prometheus service is running. # Port on which Prometheus service is running.
# Default: PROMETHEUS_PORT=19090 # Default: PROMETHEUS_PORT=19090
PROMETHEUS_PORT=19090 PROMETHEUS_PORT=19090
# ----- Grafana Configuration ----- # ----- Grafana Configuration -----
# Address or hostname for the Grafana service.
# Default: GRAFANA_ADDRESS=172.28.0.1
GRAFANA_ADDRESS=172.28.0.11
# Port on which Grafana service is running. # Port on which Grafana service is running.
# Default: GRAFANA_PORT=13000 # Default: GRAFANA_PORT=13000
GRAFANA_PORT=13000 GRAFANA_PORT=13000
@ -183,41 +178,34 @@ OPENIM_WEB_PORT=11001
# ====================================== # ======================================
# ========= OpenIM Server ============== # ========= OpenIM Server ==============
# ====================================== # ======================================
# Address or hostname for the OpenIM server.
# Default: OPENIM_SERVER_ADDRESS=172.28.0.1
OPENIM_SERVER_ADDRESS=172.28.0.8
# Port for the OpenIM WebSockets. # Port for the OpenIM WebSockets.
# Default: OPENIM_WS_PORT=10001 # Default: OPENIM_WS_PORT=10001
OPENIM_WS_PORT=10001 OPENIM_WS_PORT=10001
# Port for the OpenIM API. # API_OPENIM_PORT
# ---------------
# This variable defines the port on which the OpenIM API service will listen.
# When changing this port, it's essential to update the apiURL in the config.yaml file
# to ensure the API service is accessible at the new port.
#
# Default: API_OPENIM_PORT=10002 # Default: API_OPENIM_PORT=10002
API_OPENIM_PORT=10002 API_OPENIM_PORT=10002
# ====================================== # ======================================
# ========== OpenIM Chat =============== # ========== OpenIM Chat ===============
# ====================================== # ======================================
# Branch name for OpenIM chat. # Branch name for OpenIM chat.
# Default: CHAT_IMAGE_VERSION=main # Default: CHAT_IMAGE_VERSION=main
# https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/version.md
CHAT_IMAGE_VERSION=main CHAT_IMAGE_VERSION=main
# Address or hostname for the OpenIM chat service.
# Default: OPENIM_CHAT_ADDRESS=172.28.0.1
OPENIM_CHAT_ADDRESS=172.28.0.9
# Port for the OpenIM chat API. # Port for the OpenIM chat API.
# Default: OPENIM_CHAT_API_PORT=10008 # Default: OPENIM_CHAT_API_PORT=10008
OPENIM_CHAT_API_PORT=10008 OPENIM_CHAT_API_PORT=10008
# Directory path for storing data files or related information for OpenIM chat. # Port for the OpenIM admin API.
# Default: OPENIM_CHAT_DATA_DIR=./openim-chat/main # Default: OPENIM_ADMIN_API_PORT=10009
OPENIM_CHAT_DATA_DIR=./openim-chat/main OPENIM_ADMIN_API_PORT=10009
# ====================================== # ======================================
# ========== OpenIM Admin ============== # ========== OpenIM Admin ==============
@ -227,10 +215,6 @@ OPENIM_CHAT_DATA_DIR=./openim-chat/main
# Default: SERVER_IMAGE_VERSION=main # Default: SERVER_IMAGE_VERSION=main
SERVER_IMAGE_VERSION=main SERVER_IMAGE_VERSION=main
# Port for the OpenIM admin API.
# Default: OPENIM_ADMIN_API_PORT=10009
OPENIM_ADMIN_API_PORT=10009
# Port for the node exporter. # Port for the node exporter.
# Default: NODE_EXPORTER_PORT=19100 # Default: NODE_EXPORTER_PORT=19100
NODE_EXPORTER_PORT=19100 NODE_EXPORTER_PORT=19100

@ -165,7 +165,7 @@ export MINIO_ENDPOINT="http://im-minio:9000"
export MINIO_SIGN_ENDPOINT="https://openim.server.com/im-minio-api" export MINIO_SIGN_ENDPOINT="https://openim.server.com/im-minio-api"
mkdir ./charts/generated-configs mkdir ./charts/generated-configs
../scripts/genconfig.sh ../scripts/install/environment.sh ./templates/openim.yaml > ./charts/generated-configs/config.yaml ../scripts/genconfig.sh ../scripts/install/environment.sh ./templates/config.yaml > ./charts/generated-configs/config.yaml
cp ../config/notification.yaml ./charts/generated-configs/notification.yaml cp ../config/notification.yaml ./charts/generated-configs/notification.yaml
../scripts/genconfig.sh ../scripts/install/environment.sh ./templates/helm-image.yaml > ./charts/generated-configs/helm-image.yaml ../scripts/genconfig.sh ../scripts/install/environment.sh ./templates/helm-image.yaml > ./charts/generated-configs/helm-image.yaml
``` ```

File diff suppressed because it is too large Load Diff

@ -14,7 +14,7 @@
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# TODO: This config file is the template file # TODO: This config file is the template file
# --| source: deployments/templates/openim.yaml # --| source: deployments/templates/config.yaml
# --| env: scripts/install/environment # --| env: scripts/install/environment
# --| target: config/config.yaml # --| target: config/config.yaml
# ----------------------------------------------------------------- # -----------------------------------------------------------------

@ -115,7 +115,7 @@ MONGO_OPENIM_USERNAME=${MONGO_OPENIM_USERNAME}
MONGO_OPENIM_PASSWORD=${MONGO_OPENIM_PASSWORD} MONGO_OPENIM_PASSWORD=${MONGO_OPENIM_PASSWORD}
# Specifies the database name to be used within MongoDB. # Specifies the database name to be used within MongoDB.
# Default: MONGO_DATABASE=openIM_v3 # Default: MONGO_DATABASE=openim_v3
MONGO_DATABASE=${MONGO_DATABASE} MONGO_DATABASE=${MONGO_DATABASE}
# ----- Redis Configuration ----- # ----- Redis Configuration -----

@ -27,7 +27,7 @@ services:
- wiredTigerCacheSizeGB=1 - wiredTigerCacheSizeGB=1
- MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME:-root} - MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME:-root}
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD:-openIM123} - MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD:-openIM123}
- MONGO_INITDB_DATABASE=${MONGO_DATABASE:-openIM_v3} - MONGO_INITDB_DATABASE=${MONGO_DATABASE:-openim_v3}
- MONGO_OPENIM_USERNAME=${MONGO_OPENIM_USERNAME:-openIM} # Non-root username - MONGO_OPENIM_USERNAME=${MONGO_OPENIM_USERNAME:-openIM} # Non-root username
- MONGO_OPENIM_PASSWORD=${MONGO_OPENIM_PASSWORD:-openIM123456} # Non-root password - MONGO_OPENIM_PASSWORD=${MONGO_OPENIM_PASSWORD:-openIM123456} # Non-root password
restart: always restart: always
@ -87,6 +87,7 @@ services:
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@<your_host>:9093 - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@<your_host>:9093
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094 - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}:${KAFKA_PORT:-19094} - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}:${KAFKA_PORT:-19094}
# - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://127.0.0.1:${KAFKA_PORT:-19094} # Mac Deployment
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
networks: networks:
@ -213,6 +214,7 @@ services:
# - "${OPENIM_ADMIN_API_PORT:-10009}:10009" # - "${OPENIM_ADMIN_API_PORT:-10009}:10009"
# volumes: # volumes:
# - "${DATA_DIR:-./}/components/openim-chat/logs:/openim/openim-chat/logs" # - "${DATA_DIR:-./}/components/openim-chat/logs:/openim/openim-chat/logs"
# - "${DATA_DIR:-./}/components/openim-chat/_output/logs:/openim/openim-chat/_output/logs"
# - "${DATA_DIR:-./}/components/openim-chat/config:/openim/openim-chat/config" # - "${DATA_DIR:-./}/components/openim-chat/config:/openim/openim-chat/config"
# restart: always # restart: always
# # user: root:root # # user: root:root

@ -31,7 +31,7 @@ docs/guide/en-US/cmd/openim/openim-rpc-user_list.md
docs/guide/en-US/cmd/openim/openim-rpc-user_update.md docs/guide/en-US/cmd/openim/openim-rpc-user_update.md
docs/guide/en-US/cmd/openim/openim_validate.md docs/guide/en-US/cmd/openim/openim_validate.md
docs/guide/en-US/cmd/openim/openim_version.md docs/guide/en-US/cmd/openim/openim_version.md
docs/guide/en-US/yaml/openim/openim.yaml docs/guide/en-US/yaml/openim/config.yaml
docs/guide/en-US/yaml/openim/openim_color.yaml docs/guide/en-US/yaml/openim/openim_color.yaml
docs/guide/en-US/yaml/openim/openim_completion.yaml docs/guide/en-US/yaml/openim/openim_completion.yaml
docs/guide/en-US/yaml/openim/openim_info.yaml docs/guide/en-US/yaml/openim/openim_info.yaml

@ -89,7 +89,7 @@ While the first two methods will be our main focus, it's worth noting that the t
### 1.2. <a name='SourceCodeDeployment'></a>Source Code Deployment ### 1.2. <a name='SourceCodeDeployment'></a>Source Code Deployment
In the source code deployment method, the configuration generation process involves executing `make init`, which fundamentally runs the script `./scripts/init-config.sh`. This script utilizes variables defined in the [`environment.sh`](https://github.com/openimsdk/open-im-server/blob/main/scripts/install/environment.sh) script to render the [`openim.yaml`](https://github.com/openimsdk/open-im-server/blob/main/deployments/templates/openim.yaml) template file, subsequently generating the [`config.yaml`](https://github.com/openimsdk/open-im-server/blob/main/config/config.yaml) configuration file. In the source code deployment method, the configuration generation process involves executing `make init`, which fundamentally runs the script `./scripts/init-config.sh`. This script utilizes variables defined in the [`environment.sh`](https://github.com/openimsdk/open-im-server/blob/main/scripts/install/environment.sh) script to render the [`config.yaml`](https://github.com/openimsdk/open-im-server/blob/main/deployments/templates/config.yaml) template file, subsequently generating the [`config.yaml`](https://github.com/openimsdk/open-im-server/blob/main/config/config.yaml) configuration file.
### 1.3. <a name='DockerComposeDeployment'></a>Docker Compose Deployment ### 1.3. <a name='DockerComposeDeployment'></a>Docker Compose Deployment

@ -45,86 +45,162 @@ Homebrew is an essential package manager for macOS. Install it using:
git config --global user.email "your.email@example.com" git config --global user.email "your.email@example.com"
``` ```
### Forking and Cloning the Repository ### Setting Up the Devcontainer
To optimize and add logic to your instructions, particularly regarding deploying on a Mac, you can modify them as follows: `Devcontainers` provide a Docker-based isolated development environment.
1. **Fork the OpenIM Repository**: Fork the OpenIM repository on GitHub to your account. 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.
2. **Clone Your Fork to Your Local Machine**: To set it up:
Open your terminal and execute the following commands:
```sh 1. Install Docker Desktop for Mac from [Docker Hub](https://docs.docker.com/desktop/install/mac-install/).
# Clone the repository 2. Install Visual Studio Code and the Remote - Containers extension.
git clone https://github.com/<your-username>/open-im-server.git 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.
# Set Docker bridging network mode for Mac ### Installing Go and Dependencies
export DOCKER_BRIDGE_SUBNET=127.0.0.0/16
# Set OpenIM IP Use Homebrew to install Go:
export OPENIM_IP=<your-ip>
# Initialize configuration ```sh
make init brew install go
```
# Start components using Docker Ensure the version of Go is compatible with the version required by OpenIM (refer to the main documentation for version requirements).
docker compose up -d
# Start OpenIM Server ### Additional Tools
make start
```
3. **Additional Steps for Mac Deployment**: Install other required tools like Docker, Vagrant, and necessary GNU utils as described in the main documentation.
If you are deploying on a Mac and wish to use the chat feature, you need to modify the `docker-compose` file. Specifically, you'll need to uncomment the sections related to `openim-chat` and `mysql`.
Here's how to do it: ## Mac Deployment openim-chat and openim-server
- Open the `docker-compose.yml` file in a text editor. To integrate the Chinese document into an English document for Linux deployment, we will first translate the content and then adapt it to suit the Linux environment. Here's how the translated and adapted content might look:
- Find the sections for `openim-chat` and `mysql`.
- Remove the comment marks (`#`) at the beginning of the lines in these sections to enable them.
- Save the file after making these changes.
4. **Update and Restart Services**: ### Ensure a Clean Environment
After modifying the `docker-compose` file, you need to update and restart the services to apply these changes. Run the following command in your terminal:
```sh - It's recommended to execute in a new directory.
# Update and restart services - Run `ps -ef | grep openim` to ensure no OpenIM processes are running.
docker compose up -d - Run `ps -ef | grep chat` to check for absence of chat-related processes.
- Execute `docker ps` to verify there are no related containers running.
# Check openim-chat start ### Source Code Deployment
docker compose logs openim-chat
```
This command will re-read the `docker-compose.yml` file, apply the new configuration, and restart the necessary containers. #### Deploying openim-server
Remember, replacing `<your-username>` and `<your-ip>` with your actual GitHub username and desired IP address for OpenIM is crucial. These steps should streamline the setup process, particularly for Mac users wishing to use the chat feature. Source code deployment is slightly more complex because Docker's networking on Linux differs from Mac.
### Setting Up the Devcontainer ```bash
git clone https://github.com/openimsdk/open-im-server
cd open-im-server
`Devcontainers` provide a Docker-based isolated development environment. export OPENIM_IP="Your IP" # If it's a cloud server, setting might not be needed
make init # Generates configuration files
```
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. Before deploying openim-server, modify the Kafka logic in the docker-compose.yml file. Replace:
To set it up: ```yaml
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}:${KAFKA_PORT:-19094}
```
1. Install Docker Desktop for Mac from [Docker Hub](https://docs.docker.com/desktop/install/mac-install/). With:
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 ```yaml
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://127.0.0.1:${KAFKA_PORT:-19094}
```
Use Homebrew to install Go: Then start the service:
```sh ```bash
brew install go docker compose up -d
``` ```
Ensure the version of Go is compatible with the version required by OpenIM (refer to the main documentation for version requirements). Before starting the openim-server source, set `config/config.yaml` by replacing all instances of `172.28.0.1` with `127.0.0.1`:
### Additional Tools ```bash
vim config/config.yaml -c "%s/172\.28\.0\.1/127.0.0.1/g" -c "wq"
```
Install other required tools like Docker, Vagrant, and necessary GNU utils as described in the main documentation. Then start openim-server:
```bash
make start
```
To check the startup:
```bash
make check
```
<aside>
🚧 To avoid mishaps, it's best to wait five minutes before running `make check` again.
</aside>
#### Deploying openim-chat
There are several ways to deploy openim-chat, either by source code or using Docker.
Navigate back to the parent directory:
```bash
cd ..
```
First, let's look at deploying chat from source:
```bash
git clone https://github.com/openimsdk/chat
cd chat
make init # Generates configuration files
```
If openim-chat has not deployed MySQL, you will need to deploy it. Note that the official Docker Hub for MySQL does not support architectures like ARM, so you can use the newer version of the open-source edition:
```bash
docker run -d \
--name mysql \
-p 13306:3306 \
-p 3306:33060 \
-v "$(pwd)/components/mysql/data:/var/lib/mysql" \
-v "/etc/localtime:/etc/localtime" \
-e MYSQL_ROOT_PASSWORD="openIM123" \
--restart always \
mariadb:10.6
```
Before starting the source code of openim-chat, set `config/config.yaml` by replacing all instances of `172.28.0.1` with `127.0.0.1`:
```bash
vim config/config.yaml -c "%s/172\.28\.0\.1/127.0.0.1/g" -c "wq"
```
Then start openim-chat from source:
```bash
make start
```
To check, ensure the following four processes start successfully:
```bash
make check
```
### Docker Deployment
Refer to https://github.com/openimsdk/openim-docker for Docker deployment instructions, which can be followed similarly on Linux.
```bash
git clone https://github.com/openimsdk/openim-docker
cd openim-docker
export OPENIM_IP="Your IP"
make init
docker compose up -d
docker compose logs -f openim-server
docker compose logs -f openim-chat
```
## GitHub Development Workflow ## GitHub Development Workflow

@ -5,7 +5,7 @@ go 1.19
require ( require (
firebase.google.com/go v3.13.0+incompatible firebase.google.com/go v3.13.0+incompatible
github.com/OpenIMSDK/protocol v0.0.48 github.com/OpenIMSDK/protocol v0.0.48
github.com/OpenIMSDK/tools v0.0.23 github.com/OpenIMSDK/tools v0.0.28
github.com/bwmarrin/snowflake v0.3.0 // indirect github.com/bwmarrin/snowflake v0.3.0 // indirect
github.com/dtm-labs/rockscache v0.1.1 github.com/dtm-labs/rockscache v0.1.1
github.com/gin-gonic/gin v1.9.1 github.com/gin-gonic/gin v1.9.1
@ -38,6 +38,7 @@ require (
github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible
github.com/go-redis/redis v6.15.9+incompatible github.com/go-redis/redis v6.15.9+incompatible
github.com/redis/go-redis/v9 v9.2.1 github.com/redis/go-redis/v9 v9.2.1
github.com/spf13/pflag v1.0.5
github.com/stathat/consistent v1.0.0 github.com/stathat/consistent v1.0.0
github.com/tencentyun/cos-go-sdk-v5 v0.7.45 github.com/tencentyun/cos-go-sdk-v5 v0.7.45
go.uber.org/automaxprocs v1.5.3 go.uber.org/automaxprocs v1.5.3
@ -116,7 +117,6 @@ require (
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rs/xid v1.5.0 // indirect github.com/rs/xid v1.5.0 // indirect
github.com/sergi/go-diff v1.0.0 // indirect github.com/sergi/go-diff v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/src-d/gcfg v1.4.0 // indirect github.com/src-d/gcfg v1.4.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect github.com/stretchr/objx v0.5.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect

@ -15,13 +15,13 @@ cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/o
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4= firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs= firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
github.com/AndrewZuo01/protocol v0.0.0-20240112093520-fd9c53e27b94 h1:o86vkek41ZrQqoBGqyKvS0z6N0uJj64mpzK72OkDZVM=
github.com/AndrewZuo01/protocol v0.0.0-20240112093520-fd9c53e27b94/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 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 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c=
github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ= github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ=
github.com/OpenIMSDK/tools v0.0.23 h1:xozfrGzhbpNPlDTap5DLVPk+JfgZ/ZyIj4Cuu3/bm9w= github.com/OpenIMSDK/protocol v0.0.48 h1:8MIMjyzJRsruYhVv2ZKArFiOveroaofDOb3dlAdgjsw=
github.com/OpenIMSDK/tools v0.0.23/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= github.com/OpenIMSDK/protocol v0.0.48/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
github.com/OpenIMSDK/tools v0.0.28 h1:UT0rN1ysCFvsxQXyuxAj2TEkHt4C/sUezy+ChKpgt2Y=
github.com/OpenIMSDK/tools v0.0.28/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= 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 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=

@ -201,27 +201,27 @@ func (u *UserApi) GetSubscribeUsersStatus(c *gin.Context) {
a2r.Call(user.UserClient.GetSubscribeUsersStatus, u.Client, c) a2r.Call(user.UserClient.GetSubscribeUsersStatus, u.Client, c)
} }
// ProcessUserCommandAdd user general function add // ProcessUserCommandAdd user general function add.
func (u *UserApi) ProcessUserCommandAdd(c *gin.Context) { func (u *UserApi) ProcessUserCommandAdd(c *gin.Context) {
a2r.Call(user.UserClient.ProcessUserCommandAdd, u.Client, c) a2r.Call(user.UserClient.ProcessUserCommandAdd, u.Client, c)
} }
// ProcessUserCommandDelete user general function delete // ProcessUserCommandDelete user general function delete.
func (u *UserApi) ProcessUserCommandDelete(c *gin.Context) { func (u *UserApi) ProcessUserCommandDelete(c *gin.Context) {
a2r.Call(user.UserClient.ProcessUserCommandDelete, u.Client, c) a2r.Call(user.UserClient.ProcessUserCommandDelete, u.Client, c)
} }
// ProcessUserCommandUpdate user general function update // ProcessUserCommandUpdate user general function update.
func (u *UserApi) ProcessUserCommandUpdate(c *gin.Context) { func (u *UserApi) ProcessUserCommandUpdate(c *gin.Context) {
a2r.Call(user.UserClient.ProcessUserCommandUpdate, u.Client, c) a2r.Call(user.UserClient.ProcessUserCommandUpdate, u.Client, c)
} }
// ProcessUserCommandGet user general function get // ProcessUserCommandGet user general function get.
func (u *UserApi) ProcessUserCommandGet(c *gin.Context) { func (u *UserApi) ProcessUserCommandGet(c *gin.Context) {
a2r.Call(user.UserClient.ProcessUserCommandGet, u.Client, c) a2r.Call(user.UserClient.ProcessUserCommandGet, u.Client, c)
} }
// ProcessUserCommandGet user general function get all // ProcessUserCommandGet user general function get all.
func (u *UserApi) ProcessUserCommandGetAll(c *gin.Context) { func (u *UserApi) ProcessUserCommandGetAll(c *gin.Context) {
a2r.Call(user.UserClient.ProcessUserCommandGetAll, u.Client, c) a2r.Call(user.UserClient.ProcessUserCommandGetAll, u.Client, c)
} }

@ -19,7 +19,6 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/OpenIMSDK/tools/apiresp"
"net/http" "net/http"
"os" "os"
"os/signal" "os/signal"
@ -29,6 +28,8 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/OpenIMSDK/tools/apiresp"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"

@ -16,9 +16,10 @@ package push
import ( import (
"context" "context"
"github.com/OpenIMSDK/tools/utils"
"sync" "sync"
"github.com/OpenIMSDK/tools/utils"
"google.golang.org/grpc" "google.golang.org/grpc"
"github.com/OpenIMSDK/protocol/constant" "github.com/OpenIMSDK/protocol/constant"

@ -18,9 +18,10 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"google.golang.org/grpc"
"sync" "sync"
"google.golang.org/grpc"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"github.com/OpenIMSDK/protocol/constant" "github.com/OpenIMSDK/protocol/constant"
@ -143,7 +144,7 @@ func (p *Pusher) UnmarshalNotificationElem(bytes []byte, t any) error {
} }
/* /*
k8s deployment,offline push group messages function k8s deployment,offline push group messages function.
*/ */
func (p *Pusher) k8sOfflinePush2SuperGroup(ctx context.Context, groupID string, msg *sdkws.MsgData, wsResults []*msggateway.SingleMsgToUserResults) error { func (p *Pusher) k8sOfflinePush2SuperGroup(ctx context.Context, groupID string, msg *sdkws.MsgData, wsResults []*msggateway.SingleMsgToUserResults) error {

@ -17,9 +17,10 @@ package conversation
import ( import (
"context" "context"
"errors" "errors"
"github.com/OpenIMSDK/protocol/sdkws"
"sort" "sort"
"github.com/OpenIMSDK/protocol/sdkws"
"github.com/OpenIMSDK/tools/tx" "github.com/OpenIMSDK/tools/tx"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"

@ -18,6 +18,7 @@ import (
"context" "context"
utils2 "github.com/OpenIMSDK/tools/utils" utils2 "github.com/OpenIMSDK/tools/utils"
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct" cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"

@ -16,6 +16,7 @@ package msg
import ( import (
"context" "context"
pbmsg "github.com/OpenIMSDK/protocol/msg" pbmsg "github.com/OpenIMSDK/protocol/msg"
) )

@ -19,12 +19,14 @@ import (
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"github.com/google/uuid"
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
"path" "path"
"strconv" "strconv"
"time" "time"
"github.com/google/uuid"
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3" "github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
"github.com/OpenIMSDK/protocol/third" "github.com/OpenIMSDK/protocol/third"

@ -16,6 +16,7 @@ package user
import ( import (
"context" "context"
pbuser "github.com/OpenIMSDK/protocol/user" pbuser "github.com/OpenIMSDK/protocol/user"
"github.com/OpenIMSDK/tools/utils" "github.com/OpenIMSDK/tools/utils"

@ -17,12 +17,14 @@ package user
import ( import (
"context" "context"
"errors" "errors"
"github.com/OpenIMSDK/tools/pagination"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
"math/rand" "math/rand"
"strings" "strings"
"time" "time"
"github.com/OpenIMSDK/tools/pagination"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
"github.com/OpenIMSDK/tools/tx" "github.com/OpenIMSDK/tools/tx"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
@ -387,7 +389,7 @@ func (s *userServer) GetSubscribeUsersStatus(ctx context.Context,
return &pbuser.GetSubscribeUsersStatusResp{StatusList: onlineStatusList}, nil return &pbuser.GetSubscribeUsersStatusResp{StatusList: onlineStatusList}, nil
} }
// ProcessUserCommandAdd user general function add // ProcessUserCommandAdd user general function add.
func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) { func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) {
err := authverify.CheckAccessV3(ctx, req.UserID) err := authverify.CheckAccessV3(ctx, req.UserID)
if err != nil { if err != nil {
@ -418,7 +420,7 @@ func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.Proc
return &pbuser.ProcessUserCommandAddResp{}, nil return &pbuser.ProcessUserCommandAddResp{}, nil
} }
// ProcessUserCommandDelete user general function delete // ProcessUserCommandDelete user general function delete.
func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) { func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) {
err := authverify.CheckAccessV3(ctx, req.UserID) err := authverify.CheckAccessV3(ctx, req.UserID)
if err != nil { if err != nil {
@ -440,7 +442,7 @@ func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.P
return &pbuser.ProcessUserCommandDeleteResp{}, nil return &pbuser.ProcessUserCommandDeleteResp{}, nil
} }
// ProcessUserCommandUpdate user general function update // ProcessUserCommandUpdate user general function update.
func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) { func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) {
err := authverify.CheckAccessV3(ctx, req.UserID) err := authverify.CheckAccessV3(ctx, req.UserID)
if err != nil { if err != nil {

@ -17,6 +17,7 @@ package convert
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/OpenIMSDK/protocol/sdkws" "github.com/OpenIMSDK/protocol/sdkws"
"github.com/OpenIMSDK/tools/utils" "github.com/OpenIMSDK/tools/utils"

@ -146,7 +146,7 @@ func Test_BatchInsertChat2DB(t *testing.T) {
func GetDB() *commonMsgDatabase { func GetDB() *commonMsgDatabase {
config.Config.Mongo.Address = []string{"203.56.175.233:37017"} config.Config.Mongo.Address = []string{"203.56.175.233:37017"}
// config.Config.Mongo.Timeout = 60 // config.Config.Mongo.Timeout = 60
config.Config.Mongo.Database = "openIM_v3" config.Config.Mongo.Database = "openim_v3"
// config.Config.Mongo.Source = "admin" // config.Config.Mongo.Source = "admin"
config.Config.Mongo.Username = "root" config.Config.Mongo.Username = "root"
config.Config.Mongo.Password = "openIM123" config.Config.Mongo.Password = "openIM123"

@ -142,12 +142,12 @@ func (u *userDatabase) Find(ctx context.Context, userIDs []string) (users []*rel
return u.cache.GetUsersInfo(ctx, userIDs) return u.cache.GetUsersInfo(ctx, userIDs)
} }
// Find userInfo By Nickname // Find userInfo By Nickname.
func (u *userDatabase) FindByNickname(ctx context.Context, nickname string) (users []*relation.UserModel, err error) { func (u *userDatabase) FindByNickname(ctx context.Context, nickname string) (users []*relation.UserModel, err error) {
return u.userDB.TakeByNickname(ctx, nickname) return u.userDB.TakeByNickname(ctx, nickname)
} }
// Find notificationAccouts // Find notificationAccouts.
func (u *userDatabase) FindNotification(ctx context.Context, level int64) (users []*relation.UserModel, err error) { func (u *userDatabase) FindNotification(ctx context.Context, level int64) (users []*relation.UserModel, err error) {
return u.userDB.TakeNotification(ctx, level) return u.userDB.TakeNotification(ctx, level)
} }
@ -190,7 +190,14 @@ func (u *userDatabase) Page(ctx context.Context, pagination pagination.Paginatio
func (u *userDatabase) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { 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) return u.userDB.PageFindUser(ctx, level1, level2, pagination)
} }
func (u *userDatabase) PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, nickName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
func (u *userDatabase) PageFindUserWithKeyword(
ctx context.Context,
level1 int64,
level2 int64,
userID, nickName string,
pagination pagination.Pagination,
) (count int64, users []*relation.UserModel, err error) {
return u.userDB.PageFindUserWithKeyword(ctx, level1, level2, userID, nickName, pagination) return u.userDB.PageFindUserWithKeyword(ctx, level1, level2, userID, nickName, pagination)
} }

@ -16,6 +16,7 @@ package mgo
import ( import (
"context" "context"
"github.com/OpenIMSDK/tools/mgoutil" "github.com/OpenIMSDK/tools/mgoutil"
"github.com/OpenIMSDK/tools/pagination" "github.com/OpenIMSDK/tools/pagination"
"go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/options"

@ -16,10 +16,11 @@ package mgo
import ( import (
"context" "context"
"time"
"github.com/OpenIMSDK/protocol/user" "github.com/OpenIMSDK/protocol/user"
"github.com/OpenIMSDK/tools/errs" "github.com/OpenIMSDK/tools/errs"
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/bson/primitive"
"time"
"github.com/OpenIMSDK/tools/mgoutil" "github.com/OpenIMSDK/tools/mgoutil"
"github.com/OpenIMSDK/tools/pagination" "github.com/OpenIMSDK/tools/pagination"
@ -89,7 +90,15 @@ func (u *UserMgo) PageFindUser(ctx context.Context, level1 int64, level2 int64,
return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, query, pagination) return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, query, pagination)
} }
func (u *UserMgo) PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID string, nickName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
func (u *UserMgo) PageFindUserWithKeyword(
ctx context.Context,
level1 int64,
level2 int64,
userID string,
nickName string,
pagination pagination.Pagination,
) (count int64, users []*relation.UserModel, err error) {
// Initialize the base query with level conditions // Initialize the base query with level conditions
query := bson.M{ query := bson.M{
"$and": []bson.M{ "$and": []bson.M{

@ -36,9 +36,9 @@ import (
) )
const ( const (
minPartSize = 1024 * 1024 * 1 // 1MB minPartSize int64 = 1024 * 1024 * 1 // 1MB
maxPartSize = 1024 * 1024 * 1024 * 5 // 5GB maxPartSize int64 = 1024 * 1024 * 1024 * 5 // 5GB
maxNumSize = 1000 maxNumSize int64 = 1000
) )
const ( const (
@ -133,7 +133,7 @@ func (c *Cos) PartSize(ctx context.Context, size int64) (int64, error) {
return 0, errors.New("size must be greater than 0") return 0, errors.New("size must be greater than 0")
} }
if size > maxPartSize*maxNumSize { if size > maxPartSize*maxNumSize {
return 0, fmt.Errorf("size must be less than %db", maxPartSize*maxNumSize) return 0, fmt.Errorf("COS size must be less than the maximum allowed limit")
} }
if size <= minPartSize*maxNumSize { if size <= minPartSize*maxNumSize {
return minPartSize, nil return minPartSize, nil

@ -45,9 +45,9 @@ const (
) )
const ( const (
minPartSize = 1024 * 1024 * 5 // 1MB minPartSize int64 = 1024 * 1024 * 5 // 1MB
maxPartSize = 1024 * 1024 * 1024 * 5 // 5GB maxPartSize int64 = 1024 * 1024 * 1024 * 5 // 5GB
maxNumSize = 10000 maxNumSize int64 = 10000
) )
const ( const (
@ -240,7 +240,7 @@ func (m *Minio) PartSize(ctx context.Context, size int64) (int64, error) {
return 0, errors.New("size must be greater than 0") return 0, errors.New("size must be greater than 0")
} }
if size > maxPartSize*maxNumSize { if size > maxPartSize*maxNumSize {
return 0, fmt.Errorf("size must be less than %db", maxPartSize*maxNumSize) return 0, fmt.Errorf("MINIO size must be less than the maximum allowed limit")
} }
if size <= minPartSize*maxNumSize { if size <= minPartSize*maxNumSize {
return minPartSize, nil return minPartSize, nil

@ -37,9 +37,9 @@ import (
) )
const ( const (
minPartSize = 1024 * 1024 * 1 // 1MB minPartSize int64 = 1024 * 1024 * 1 // 1MB
maxPartSize = 1024 * 1024 * 1024 * 5 // 5GB maxPartSize int64 = 1024 * 1024 * 1024 * 5 // 5GB
maxNumSize = 10000 maxNumSize int64 = 10000
) )
const ( const (
@ -141,7 +141,7 @@ func (o *OSS) PartSize(ctx context.Context, size int64) (int64, error) {
return 0, errors.New("size must be greater than 0") return 0, errors.New("size must be greater than 0")
} }
if size > maxPartSize*maxNumSize { if size > maxPartSize*maxNumSize {
return 0, fmt.Errorf("size must be less than %db", maxPartSize*maxNumSize) return 0, fmt.Errorf("OSS size must be less than the maximum allowed limit")
} }
if size <= minPartSize*maxNumSize { if size <= minPartSize*maxNumSize {
return minPartSize, nil return minPartSize, nil

@ -24,7 +24,7 @@ import (
type PartLimit struct { type PartLimit struct {
MinPartSize int64 `json:"minPartSize"` MinPartSize int64 `json:"minPartSize"`
MaxPartSize int64 `json:"maxPartSize"` MaxPartSize int64 `json:"maxPartSize"`
MaxNumSize int `json:"maxNumSize"` MaxNumSize int64 `json:"maxNumSize"`
} }
type InitiateMultipartUploadResult struct { type InitiateMultipartUploadResult struct {

@ -16,9 +16,10 @@ package relation
import ( import (
"context" "context"
"github.com/OpenIMSDK/protocol/user"
"time" "time"
"github.com/OpenIMSDK/protocol/user"
"github.com/OpenIMSDK/tools/pagination" "github.com/OpenIMSDK/tools/pagination"
) )

@ -18,15 +18,17 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"github.com/stathat/consistent"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"github.com/stathat/consistent"
"google.golang.org/grpc" "google.golang.org/grpc"
"github.com/OpenIMSDK/tools/discoveryregistry" "github.com/OpenIMSDK/tools/discoveryregistry"
"github.com/OpenIMSDK/tools/log" "github.com/OpenIMSDK/tools/log"
"github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/config"
) )
@ -102,7 +104,7 @@ func getSelfHost(ctx context.Context) string {
return host return host
} }
// like openimserver-openim-msggateway-0.openimserver-openim-msggateway-headless.openim-lin.svc.cluster.local:88 // like openimserver-openim-msggateway-0.openimserver-openim-msggateway-headless.openim-lin.svc.cluster.local:88.
func getMsgGatewayHost(ctx context.Context) []string { func getMsgGatewayHost(ctx context.Context) []string {
port := 88 port := 88
instance := "openimserver" instance := "openimserver"
@ -166,7 +168,7 @@ func (cli *K8sDR) CloseConn(conn *grpc.ClientConn) {
conn.Close() conn.Close()
} }
// do not use this method for call rpc // do not use this method for call rpc.
func (cli *K8sDR) GetClientLocalConns() map[string][]*grpc.ClientConn { func (cli *K8sDR) GetClientLocalConns() map[string][]*grpc.ClientConn {
fmt.Println("should not call this function!!!!!!!!!!!!!!!!!!!!!!!!!") fmt.Println("should not call this function!!!!!!!!!!!!!!!!!!!!!!!!!")
return nil return nil

@ -17,6 +17,7 @@ package rpcclient
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"

@ -1,7 +1,21 @@
// 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.
package flag package flag
import ( import (
goFlag "flag" "flag"
"log" "log"
"strings" "strings"
@ -29,7 +43,7 @@ func WarnWordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedNam
// InitFlags normalizes, parses, then logs the command line flags. // InitFlags normalizes, parses, then logs the command line flags.
func InitFlags() { func InitFlags() {
pflag.CommandLine.SetNormalizeFunc(WordSepNormalizeFunc) pflag.CommandLine.SetNormalizeFunc(WordSepNormalizeFunc)
pflag.CommandLine.AddGoFlagSet(goFlag.CommandLine) pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
} }
// PrintFlags logs the flags in the flagset. // PrintFlags logs the flags in the flagset.

@ -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.
package genutil package genutil
import ( import (

@ -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.
package genutil package genutil
import ( import (

@ -44,12 +44,12 @@ print_progress() {
} }
function openim_logo() { function openim_logo() {
# Set text color to cyan for header and URL # Set text color to cyan for header and URL
echo -e "\033[0;36m" echo -e "\033[0;36m"
# Display fancy ASCII Art logo # Display fancy ASCII Art logo
# look http://patorjk.com/software/taag/#p=display&h=1&v=1&f=Doh&t=OpenIM # look http://patorjk.com/software/taag/#p=display&h=1&v=1&f=Doh&t=OpenIM
print_with_delay ' print_with_delay '
OOOOOOOOO IIIIIIIIIIMMMMMMMM MMMMMMMM OOOOOOOOO IIIIIIIIIIMMMMMMMM MMMMMMMM
@ -75,38 +75,38 @@ O:::::::OOO:::::::O p:::::ppppp:::::::pe::::::::e n::::n n::::nII:
p:::::::p p:::::::p
ppppppppp ppppppppp
' 0.0001 ' 0.0001
# Display product URL # Display product URL
print_with_delay "Discover more and contribute at: https://github.com/openimsdk/open-im-server" 0.01 print_with_delay "Discover more and contribute at: https://github.com/openimsdk/open-im-server" 0.01
# Reset text color back to normal # Reset text color back to normal
echo -e "\033[0m" echo -e "\033[0m"
# Set text color to green for product description # Set text color to green for product description
echo -e "\033[1;32m" echo -e "\033[1;32m"
print_with_delay "Open-IM-Server: Reinventing Instant Messaging" 0.01 print_with_delay "Open-IM-Server: Reinventing Instant Messaging" 0.01
print_progress 50 0.02 print_progress 50 0.02
print_with_delay "Open-IM-Server is not just a product; it's a revolution. It's about bringing the power of seamless," 0.01 print_with_delay "Open-IM-Server is not just a product; it's a revolution. It's about bringing the power of seamless," 0.01
print_with_delay "real-time messaging to your fingertips. And it's about joining a global community of developers, dedicated to pushing the boundaries of what's possible." 0.01 print_with_delay "real-time messaging to your fingertips. And it's about joining a global community of developers, dedicated to pushing the boundaries of what's possible." 0.01
print_progress 50 0.02 print_progress 50 0.02
# Reset text color back to normal # Reset text color back to normal
echo -e "\033[0m" echo -e "\033[0m"
# Set text color to yellow for the Slack link # Set text color to yellow for the Slack link
echo -e "\033[1;33m" echo -e "\033[1;33m"
print_with_delay "Join our developer community on Slack: https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q" 0.01 print_with_delay "Join our developer community on Slack: https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q" 0.01
# Reset text color back to normal # Reset text color back to normal
echo -e "\033[0m" echo -e "\033[0m"
} }
function main() { function main() {
openim_logo openim_logo
} }
main "$@" main "$@"

@ -0,0 +1,173 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#**************************************************************************
# Copyright (C) 2011, Paul Lutus *
# *
# This program is free software; you can redistribute it and/or modify *
# it under the terms of the GNU General Public License as published by *
# the Free Software Foundation; either version 2 of the License, or *
# (at your option) any later version. *
# *
# This program is distributed in the hope that it will be useful, *
# but WITHOUT ANY WARRANTY; without even the implied warranty of *
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# GNU General Public License for more details. *
# *
# You should have received a copy of the GNU General Public License *
# along with this program; if not, write to the *
# Free Software Foundation, Inc., *
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
#**************************************************************************
import re
import sys
PVERSION = '1.0'
class BeautifyBash:
def __init__(self):
self.tab_str = ' '
self.tab_size = 2
def read_file(self, fp):
with open(fp) as f:
return f.read()
def write_file(self, fp, data):
with open(fp, 'w') as f:
f.write(data)
def beautify_string(self, data, path=''):
tab = 0
case_stack = []
in_here_doc = False
defer_ext_quote = False
in_ext_quote = False
ext_quote_string = ''
here_string = ''
output = []
line = 1
for record in re.split('\n', data):
record = record.rstrip()
stripped_record = record.strip()
# collapse multiple quotes between ' ... '
test_record = re.sub(r'\'.*?\'', '', stripped_record)
# collapse multiple quotes between " ... "
test_record = re.sub(r'".*?"', '', test_record)
# collapse multiple quotes between ` ... `
test_record = re.sub(r'`.*?`', '', test_record)
# collapse multiple quotes between \` ... ' (weird case)
test_record = re.sub(r'\\`.*?\'', '', test_record)
# strip out any escaped single characters
test_record = re.sub(r'\\.', '', test_record)
# remove '#' comments
test_record = re.sub(r'(\A|\s)(#.*)', '', test_record, 1)
if(not in_here_doc):
if(re.search('<<-?', test_record)):
here_string = re.sub(
'.*<<-?\s*[\'|"]?([_|\w]+)[\'|"]?.*', '\\1', stripped_record, 1)
in_here_doc = (len(here_string) > 0)
if(in_here_doc): # pass on with no changes
output.append(record)
# now test for here-doc termination string
if(re.search(here_string, test_record) and not re.search('<<', test_record)):
in_here_doc = False
else: # not in here doc
if(in_ext_quote):
if(re.search(ext_quote_string, test_record)):
# provide line after quotes
test_record = re.sub(
'.*%s(.*)' % ext_quote_string, '\\1', test_record, 1)
in_ext_quote = False
else: # not in ext quote
if(re.search(r'(\A|\s)(\'|")', test_record)):
# apply only after this line has been processed
defer_ext_quote = True
ext_quote_string = re.sub(
'.*([\'"]).*', '\\1', test_record, 1)
# provide line before quote
test_record = re.sub(
'(.*)%s.*' % ext_quote_string, '\\1', test_record, 1)
if(in_ext_quote):
# pass on unchanged
output.append(record)
else: # not in ext quote
inc = len(re.findall(
'(\s|\A|;)(case|then|do)(;|\Z|\s)', test_record))
inc += len(re.findall('(\{|\(|\[)', test_record))
outc = len(re.findall(
'(\s|\A|;)(esac|fi|done|elif)(;|\)|\||\Z|\s)', test_record))
outc += len(re.findall('(\}|\)|\])', test_record))
if(re.search(r'\besac\b', test_record)):
if(len(case_stack) == 0):
sys.stderr.write(
'File %s: error: "esac" before "case" in line %d.\n' % (
path, line)
)
else:
outc += case_stack.pop()
# sepcial handling for bad syntax within case ... esac
if(len(case_stack) > 0):
if(re.search('\A[^(]*\)', test_record)):
# avoid overcount
outc -= 2
case_stack[-1] += 1
if(re.search(';;', test_record)):
outc += 1
case_stack[-1] -= 1
# an ad-hoc solution for the "else" keyword
else_case = (
0, -1)[re.search('^(else)', test_record) != None]
net = inc - outc
tab += min(net, 0)
extab = tab + else_case
extab = max(0, extab)
output.append(
(self.tab_str * self.tab_size * extab) + stripped_record)
tab += max(net, 0)
if(defer_ext_quote):
in_ext_quote = True
defer_ext_quote = False
if(re.search(r'\bcase\b', test_record)):
case_stack.append(0)
line += 1
error = (tab != 0)
if(error):
sys.stderr.write(
'File %s: error: indent/outdent mismatch: %d.\n' % (path, tab))
return '\n'.join(output), error
def beautify_file(self, path):
error = False
if(path == '-'):
data = sys.stdin.read()
result, error = self.beautify_string(data, '(stdin)')
sys.stdout.write(result)
else: # named file
data = self.read_file(path)
result, error = self.beautify_string(data, path)
if(data != result):
# make a backup copy
self.write_file(path + '~', data)
self.write_file(path, result)
return error
def main(self):
error = False
sys.argv.pop(0)
if(len(sys.argv) < 1):
sys.stderr.write(
'usage: shell script filenames or \"-\" for stdin.\n')
else:
for path in sys.argv:
error |= self.beautify_file(path)
sys.exit((0, 1)[error])
# if not called as a module
if(__name__ == '__main__'):
BeautifyBash().main()

@ -31,7 +31,7 @@ source "${OPENIM_ROOT}/scripts/lib/init.sh"
# CPU core number # CPU core number
pushd "${OPENIM_ROOT}/tools/ncpu" >/dev/null pushd "${OPENIM_ROOT}/tools/ncpu" >/dev/null
cpu_count=$(go run .) cpu_count=$(go run .)
popd >/dev/null popd >/dev/null
openim::color::echo ${GREEN_PREFIX} "======> cpu_count=$cpu_count" openim::color::echo ${GREEN_PREFIX} "======> cpu_count=$cpu_count"
@ -42,7 +42,7 @@ compile_count=$((cpu_count / 2))
# For help output # For help output
ARGHELP="" ARGHELP=""
if [[ "$#" -gt 0 ]]; then if [[ "$#" -gt 0 ]]; then
ARGHELP="'$*'" ARGHELP="'$*'"
fi fi
openim::color::echo $COLOR_CYAN "NOTE: $0 has been replaced by 'make multiarch' or 'make build'" openim::color::echo $COLOR_CYAN "NOTE: $0 has been replaced by 'make multiarch' or 'make build'"
@ -61,15 +61,15 @@ echo " ./scripts/build-all-service.sh BINS=openim-api V=1 DEBUG=1"
echo echo
if [ -z "$*" ]; then if [ -z "$*" ]; then
openim::log::info "no args, build all service" openim::log::info "no args, build all service"
make --no-print-directory -C "${OPENIM_ROOT}" -j$compile_count build make --no-print-directory -C "${OPENIM_ROOT}" -j$compile_count build
else else
openim::log::info "build service: $*" openim::log::info "build service: $*"
make --no-print-directory -C "${OPENIM_ROOT}" -j$compile_count build "$*" make --no-print-directory -C "${OPENIM_ROOT}" -j$compile_count build "$*"
fi fi
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
openim::log::success "all service build success, run 'make start' or './scripts/start-all.sh'" openim::log::success "all service build success, run 'make start' or './scripts/start-all.sh'"
else else
openim::log::error "make build Error, script exits" openim::log::error "make build Error, script exits"
fi fi

@ -34,19 +34,19 @@ openim::log::status "Check all dependent service ports"
# Elegant printing function # Elegant printing function
# Elegant printing function # Elegant printing function
print_services_and_ports() { print_services_and_ports() {
local service_names=("$@") local service_names=("$@")
local half_length=$((${#service_names[@]} / 2)) local half_length=$((${#service_names[@]} / 2))
local service_ports=("${service_names[@]:half_length}") local service_ports=("${service_names[@]:half_length}")
echo "+-------------------------+----------+" echo "+-------------------------+----------+"
echo "| Service Name | Port |" echo "| Service Name | Port |"
echo "+-------------------------+----------+" echo "+-------------------------+----------+"
for ((index=0; index < half_length; index++)); do for ((index=0; index < half_length; index++)); do
printf "| %-23s | %-8s |\n" "${service_names[$index]}" "${service_ports[$index]}" printf "| %-23s | %-8s |\n" "${service_names[$index]}" "${service_ports[$index]}"
done done
echo "+-------------------------+----------+" echo "+-------------------------+----------+"
} }
# Assuming OPENIM_SERVER_NAME_TARGETS and OPENIM_SERVER_PORT_TARGETS are defined # Assuming OPENIM_SERVER_NAME_TARGETS and OPENIM_SERVER_PORT_TARGETS are defined
@ -67,10 +67,10 @@ set +e
# Later, after discarding Docker, the Docker keyword is unreliable, and Kubepods is used # Later, after discarding Docker, the Docker keyword is unreliable, and Kubepods is used
if grep -qE 'docker|kubepods' /proc/1/cgroup || [ -f /.dockerenv ]; then if grep -qE 'docker|kubepods' /proc/1/cgroup || [ -f /.dockerenv ]; then
openim::color::echo ${COLOR_CYAN} "Environment in the interior of the container" openim::color::echo ${COLOR_CYAN} "Environment in the interior of the container"
else else
openim::color::echo ${COLOR_CYAN} "The environment is outside the container" openim::color::echo ${COLOR_CYAN} "The environment is outside the container"
openim::util::check_ports ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]} || return 0 openim::util::check_ports ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]} || return 0
fi fi
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then

@ -153,7 +153,7 @@ For details on the cherry pick process, see the [cherry pick requests](https://g
EOF EOF
) )
gh pr create --title="Automated cherry pick of ${numandtitle}" --body="${prtext}" --head "${GITHUB_USER}:${NEWBRANCH}" --base "${rel}" --repo="${MAIN_REPO_ORG}/${MAIN_REPO_NAME}" gh pr create --title="Automated cherry pick of ${numandtitle}" --body="${prtext}" --head "${GITHUB_USER}:${NEWBRANCH}" --base "${rel}" --repo="${MAIN_REPO_ORG}/${MAIN_REPO_NAME}"
} }
git checkout -b "${NEWBRANCHUNIQ}" "${BRANCH}" git checkout -b "${NEWBRANCHUNIQ}" "${BRANCH}"
@ -161,84 +161,84 @@ cleanbranch="${NEWBRANCHUNIQ}"
gitamcleanup=true gitamcleanup=true
for pull in "${PULLS[@]}"; do for pull in "${PULLS[@]}"; do
openim::log::status "Downloading patch to /tmp/${pull}.patch (in case you need to do this again)" openim::log::status "Downloading patch to /tmp/${pull}.patch (in case you need to do this again)"
curl -o "/tmp/${pull}.patch" -sSL "https://github.com/${MAIN_REPO_ORG}/${MAIN_REPO_NAME}/pull/${pull}.patch" curl -o "/tmp/${pull}.patch" -sSL "https://github.com/${MAIN_REPO_ORG}/${MAIN_REPO_NAME}/pull/${pull}.patch"
echo echo
openim::log::status "About to attempt cherry pick of PR. To reattempt:" openim::log::status "About to attempt cherry pick of PR. To reattempt:"
echo " $ git am -3 /tmp/${pull}.patch" echo " $ git am -3 /tmp/${pull}.patch"
echo echo
git am -3 "/tmp/${pull}.patch" || { git am -3 "/tmp/${pull}.patch" || {
conflicts=false conflicts=false
while unmerged=$(git status --porcelain | grep ^U) && [[ -n ${unmerged} ]] \ while unmerged=$(git status --porcelain | grep ^U) && [[ -n ${unmerged} ]] \
|| [[ -e "${REBASEMAGIC}" ]]; do || [[ -e "${REBASEMAGIC}" ]]; do
conflicts=true # <-- We should have detected conflicts once conflicts=true # <-- We should have detected conflicts once
echo echo
openim::log::status "Conflicts detected:" openim::log::status "Conflicts detected:"
echo echo
(git status --porcelain | grep ^U) || echo "!!! None. Did you git am --continue?" (git status --porcelain | grep ^U) || echo "!!! None. Did you git am --continue?"
echo echo
openim::log::status "Please resolve the conflicts in another window (and remember to 'git add / git am --continue')" openim::log::status "Please resolve the conflicts in another window (and remember to 'git add / git am --continue')"
read -p "+++ Proceed (anything other than 'y' aborts the cherry-pick)? [y/n] " -r read -p "+++ Proceed (anything other than 'y' aborts the cherry-pick)? [y/n] " -r
echo echo
if ! [[ "${REPLY}" =~ ^[yY]$ ]]; then if ! [[ "${REPLY}" =~ ^[yY]$ ]]; then
echo "Aborting." >&2 echo "Aborting." >&2
exit 1
fi
done
if [[ "${conflicts}" != "true" ]]; then
echo "!!! git am failed, likely because of an in-progress 'git am' or 'git rebase'"
exit 1 exit 1
fi fi
} done
if [[ "${conflicts}" != "true" ]]; then
echo "!!! git am failed, likely because of an in-progress 'git am' or 'git rebase'"
exit 1
fi
}
# set the subject # set the subject
subject=$(grep -m 1 "^Subject" "/tmp/${pull}.patch" | sed -e 's/Subject: \[PATCH//g' | sed 's/.*] //') subject=$(grep -m 1 "^Subject" "/tmp/${pull}.patch" | sed -e 's/Subject: \[PATCH//g' | sed 's/.*] //')
SUBJECTS+=("#${pull}: ${subject}") SUBJECTS+=("#${pull}: ${subject}")
# remove the patch file from /tmp # remove the patch file from /tmp
rm -f "/tmp/${pull}.patch" rm -f "/tmp/${pull}.patch"
done done
gitamcleanup=false gitamcleanup=false
# Re-generate docs (if needed) # Re-generate docs (if needed)
if [[ -n "${REGENERATE_DOCS}" ]]; then if [[ -n "${REGENERATE_DOCS}" ]]; then
echo
echo "Regenerating docs..."
if ! scripts/generate-docs.sh; then
echo echo
echo "Regenerating docs..." echo "scripts/gendoc.sh FAILED to complete."
if ! scripts/generate-docs.sh; then exit 1
echo fi
echo "scripts/gendoc.sh FAILED to complete."
exit 1
fi
fi fi
if [[ -n "${DRY_RUN}" ]]; then if [[ -n "${DRY_RUN}" ]]; then
openim::log::error "!!! Skipping git push and PR creation because you set DRY_RUN." openim::log::error "!!! Skipping git push and PR creation because you set DRY_RUN."
echo "To return to the branch you were in when you invoked this script:" echo "To return to the branch you were in when you invoked this script:"
echo echo
echo " git checkout ${STARTINGBRANCH}" echo " git checkout ${STARTINGBRANCH}"
echo echo
echo "To delete this branch:" echo "To delete this branch:"
echo echo
echo " git branch -D ${NEWBRANCHUNIQ}" echo " git branch -D ${NEWBRANCHUNIQ}"
exit 0 exit 0
fi fi
if git remote -v | grep ^"${FORK_REMOTE}" | grep "${MAIN_REPO_ORG}/${MAIN_REPO_NAME}.git"; then if git remote -v | grep ^"${FORK_REMOTE}" | grep "${MAIN_REPO_ORG}/${MAIN_REPO_NAME}.git"; then
echo "!!! You have ${FORK_REMOTE} configured as your ${MAIN_REPO_ORG}/${MAIN_REPO_NAME}.git" echo "!!! You have ${FORK_REMOTE} configured as your ${MAIN_REPO_ORG}/${MAIN_REPO_NAME}.git"
echo "This isn't normal. Leaving you with push instructions:" echo "This isn't normal. Leaving you with push instructions:"
echo echo
openim::log::status "First manually push the branch this script created:" openim::log::status "First manually push the branch this script created:"
echo echo
echo " git push REMOTE ${NEWBRANCHUNIQ}:${NEWBRANCH}" echo " git push REMOTE ${NEWBRANCHUNIQ}:${NEWBRANCH}"
echo echo
echo "where REMOTE is your personal fork (maybe ${UPSTREAM_REMOTE}? Consider swapping those.)." echo "where REMOTE is your personal fork (maybe ${UPSTREAM_REMOTE}? Consider swapping those.)."
echo "OR consider setting UPSTREAM_REMOTE and FORK_REMOTE to different values." echo "OR consider setting UPSTREAM_REMOTE and FORK_REMOTE to different values."
echo echo
make-a-pr make-a-pr
cleanbranch="" cleanbranch=""
exit 0 exit 0
fi fi
echo echo
@ -248,8 +248,8 @@ echo " git push ${FORK_REMOTE} ${NEWBRANCHUNIQ}:${NEWBRANCH}"
echo echo
read -p "+++ Proceed (anything other than 'y' aborts the cherry-pick)? [y/n] " -r read -p "+++ Proceed (anything other than 'y' aborts the cherry-pick)? [y/n] " -r
if ! [[ "${REPLY}" =~ ^[yY]$ ]]; then if ! [[ "${REPLY}" =~ ^[yY]$ ]]; then
echo "Aborting." >&2 echo "Aborting." >&2
exit 1 exit 1
fi fi
git push "${FORK_REMOTE}" -f "${NEWBRANCHUNIQ}:${NEWBRANCH}" git push "${FORK_REMOTE}" -f "${NEWBRANCHUNIQ}:${NEWBRANCH}"

@ -87,28 +87,28 @@ readonly OPENIM_CONTAINER_RSYNC_PORT=8730
# #
# $1 - server architecture # $1 - server architecture
openim::build::get_docker_wrapped_binaries() { openim::build::get_docker_wrapped_binaries() {
local arch=$1 local arch=$1
local debian_base_version=v2.1.0 local debian_base_version=v2.1.0
local debian_iptables_version=v12.1.0 local debian_iptables_version=v12.1.0
### If you change any of these lists, please also update DOCKERIZED_BINARIES ### If you change any of these lists, please also update DOCKERIZED_BINARIES
### in build/BUILD. And openim::golang::server_image_targets ### in build/BUILD. And openim::golang::server_image_targets
local targets=( local targets=(
"openim-api,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-api,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-cmdutils,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-cmdutils,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-crontask,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-crontask,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-msggateway,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-msggateway,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-msgtransfer,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-msgtransfer,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-push,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-push,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-rpc-auth,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-rpc-auth,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-rpc-conversation,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-rpc-conversation,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-rpc-friend,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-rpc-friend,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-rpc-group,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-rpc-group,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-rpc-msg,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-rpc-msg,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-rpc-third,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-rpc-third,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
"openim-rpc-user,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" "openim-rpc-user,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}"
) )
echo "${targets[@]}" echo "${targets[@]}"
} }
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -133,170 +133,170 @@ openim::build::get_docker_wrapped_binaries() {
# DOCKER_MOUNT_ARGS # DOCKER_MOUNT_ARGS
# LOCAL_OUTPUT_BUILD_CONTEXT # LOCAL_OUTPUT_BUILD_CONTEXT
function openim::build::verify_prereqs() { function openim::build::verify_prereqs() {
local -r require_docker=${1:-true} local -r require_docker=${1:-true}
openim::log::status "Verifying Prerequisites...." openim::log::status "Verifying Prerequisites...."
openim::build::ensure_tar || return 1 openim::build::ensure_tar || return 1
openim::build::ensure_rsync || return 1 openim::build::ensure_rsync || return 1
if ${require_docker}; then if ${require_docker}; then
openim::build::ensure_docker_in_path || return 1 openim::build::ensure_docker_in_path || return 1
openim::util::ensure_docker_daemon_connectivity || return 1 openim::util::ensure_docker_daemon_connectivity || return 1
if (( OPENIM_VERBOSE > 6 )); then if (( OPENIM_VERBOSE > 6 )); then
openim::log::status "Docker Version:" openim::log::status "Docker Version:"
"${DOCKER[@]}" version | openim::log::info_from_stdin "${DOCKER[@]}" version | openim::log::info_from_stdin
fi
fi fi
fi
OPENIM_GIT_BRANCH=$(git symbolic-ref --short -q HEAD 2>/dev/null || true)
OPENIM_ROOT_HASH=$(openim::build::short_hash "${HOSTNAME:-}:"${OPENIM_ROOT}":${OPENIM_GIT_BRANCH}") OPENIM_GIT_BRANCH=$(git symbolic-ref --short -q HEAD 2>/dev/null || true)
OPENIM_BUILD_IMAGE_TAG_BASE="build-${OPENIM_ROOT_HASH}" OPENIM_ROOT_HASH=$(openim::build::short_hash "${HOSTNAME:-}:${OPENIM_ROOT}:${OPENIM_GIT_BRANCH}")
#OPENIM_BUILD_IMAGE_TAG="${OPENIM_BUILD_IMAGE_TAG_BASE}-${OPENIM_BUILD_IMAGE_VERSION}" OPENIM_BUILD_IMAGE_TAG_BASE="build-${OPENIM_ROOT_HASH}"
#OPENIM_BUILD_IMAGE="${OPENIM_BUILD_IMAGE_REPO}:${OPENIM_BUILD_IMAGE_TAG}" #OPENIM_BUILD_IMAGE_TAG="${OPENIM_BUILD_IMAGE_TAG_BASE}-${OPENIM_BUILD_IMAGE_VERSION}"
OPENIM_BUILD_CONTAINER_NAME_BASE="openim-build-${OPENIM_ROOT_HASH}" #OPENIM_BUILD_IMAGE="${OPENIM_BUILD_IMAGE_REPO}:${OPENIM_BUILD_IMAGE_TAG}"
#OPENIM_BUILD_CONTAINER_NAME="${OPENIM_BUILD_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}" OPENIM_BUILD_CONTAINER_NAME_BASE="openim-build-${OPENIM_ROOT_HASH}"
OPENIM_RSYNC_CONTAINER_NAME_BASE="openim-rsync-${OPENIM_ROOT_HASH}" #OPENIM_BUILD_CONTAINER_NAME="${OPENIM_BUILD_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}"
#OPENIM_RSYNC_CONTAINER_NAME="${OPENIM_RSYNC_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}" OPENIM_RSYNC_CONTAINER_NAME_BASE="openim-rsync-${OPENIM_ROOT_HASH}"
OPENIM_DATA_CONTAINER_NAME_BASE="openim-build-data-${OPENIM_ROOT_HASH}" #OPENIM_RSYNC_CONTAINER_NAME="${OPENIM_RSYNC_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}"
#OPENIM_DATA_CONTAINER_NAME="${OPENIM_DATA_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}" OPENIM_DATA_CONTAINER_NAME_BASE="openim-build-data-${OPENIM_ROOT_HASH}"
#DOCKER_MOUNT_ARGS=(--volumes-from "${OPENIM_DATA_CONTAINER_NAME}") #OPENIM_DATA_CONTAINER_NAME="${OPENIM_DATA_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}"
#LOCAL_OUTPUT_BUILD_CONTEXT="${LOCAL_OUTPUT_IMAGE_STAGING}/${OPENIM_BUILD_IMAGE}" #DOCKER_MOUNT_ARGS=(--volumes-from "${OPENIM_DATA_CONTAINER_NAME}")
#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::get_version_vars
#openim::version::save_version_vars "${OPENIM_ROOT}/.dockerized-openim-version-defs"
} }
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Utility functions # Utility functions
function openim::build::docker_available_on_osx() { function openim::build::docker_available_on_osx() {
if [[ -z "${DOCKER_HOST}" ]]; then if [[ -z "${DOCKER_HOST}" ]]; then
if [[ -S "/var/run/docker.sock" ]]; then if [[ -S "/var/run/docker.sock" ]]; then
openim::log::status "Using Docker for MacOS" openim::log::status "Using Docker for MacOS"
return 0 return 0
fi fi
openim::log::status "No docker host is set. Checking options for setting one..." openim::log::status "No docker host is set. Checking options for setting one..."
if [[ -z "$(which docker-machine)" ]]; then if [[ -z "$(which docker-machine)" ]]; then
openim::log::status "It looks like you're running Mac OS X, yet neither Docker for Mac nor docker-machine can be found." openim::log::status "It looks like you're running Mac OS X, yet neither Docker for Mac nor docker-machine can be found."
openim::log::status "See: https://docs.docker.com/engine/installation/mac/ for installation instructions." openim::log::status "See: https://docs.docker.com/engine/installation/mac/ for installation instructions."
return 1 return 1
elif [[ -n "$(which docker-machine)" ]]; then elif [[ -n "$(which docker-machine)" ]]; then
openim::build::prepare_docker_machine openim::build::prepare_docker_machine
fi
fi fi
fi
} }
function openim::build::prepare_docker_machine() { function openim::build::prepare_docker_machine() {
openim::log::status "docker-machine was found." openim::log::status "docker-machine was found."
local available_memory_bytes local available_memory_bytes
available_memory_bytes=$(sysctl -n hw.memsize 2>/dev/null) available_memory_bytes=$(sysctl -n hw.memsize 2>/dev/null)
local bytes_in_mb=1048576 local bytes_in_mb=1048576
# Give virtualbox 1/2 the system memory. Its necessary to divide by 2, instead # Give virtualbox 1/2 the system memory. Its necessary to divide by 2, instead
# of multiple by .5, because bash can only multiply by ints. # of multiple by .5, because bash can only multiply by ints.
local memory_divisor=2 local memory_divisor=2
local virtualbox_memory_mb=$(( available_memory_bytes / (bytes_in_mb * memory_divisor) )) local virtualbox_memory_mb=$(( available_memory_bytes / (bytes_in_mb * memory_divisor) ))
docker-machine inspect "${DOCKER_MACHINE_NAME}" &> /dev/null || { docker-machine inspect "${DOCKER_MACHINE_NAME}" &> /dev/null || {
openim::log::status "Creating a machine to build OPENIM" openim::log::status "Creating a machine to build OPENIM"
docker-machine create --driver "${DOCKER_MACHINE_DRIVER}" \ docker-machine create --driver "${DOCKER_MACHINE_DRIVER}" \
--virtualbox-memory "${virtualbox_memory_mb}" \ --virtualbox-memory "${virtualbox_memory_mb}" \
--engine-env HTTP_PROXY="${OPENIMRNETES_HTTP_PROXY:-}" \ --engine-env HTTP_PROXY="${OPENIMRNETES_HTTP_PROXY:-}" \
--engine-env HTTPS_PROXY="${OPENIMRNETES_HTTPS_PROXY:-}" \ --engine-env HTTPS_PROXY="${OPENIMRNETES_HTTPS_PROXY:-}" \
--engine-env NO_PROXY="${OPENIMRNETES_NO_PROXY:-127.0.0.1}" \ --engine-env NO_PROXY="${OPENIMRNETES_NO_PROXY:-127.0.0.1}" \
"${DOCKER_MACHINE_NAME}" > /dev/null || { "${DOCKER_MACHINE_NAME}" > /dev/null || {
openim::log::error "Something went wrong creating a machine." openim::log::error "Something went wrong creating a machine."
openim::log::error "Try the following: " openim::log::error "Try the following: "
openim::log::error "docker-machine create -d ${DOCKER_MACHINE_DRIVER} --virtualbox-memory ${virtualbox_memory_mb} ${DOCKER_MACHINE_NAME}" openim::log::error "docker-machine create -d ${DOCKER_MACHINE_DRIVER} --virtualbox-memory ${virtualbox_memory_mb} ${DOCKER_MACHINE_NAME}"
return 1 return 1
}
} }
docker-machine start "${DOCKER_MACHINE_NAME}" &> /dev/null }
# it takes `docker-machine env` a few seconds to work if the machine was just started docker-machine start "${DOCKER_MACHINE_NAME}" &> /dev/null
local docker_machine_out # it takes `docker-machine env` a few seconds to work if the machine was just started
while ! docker_machine_out=$(docker-machine env "${DOCKER_MACHINE_NAME}" 2>&1); do local docker_machine_out
if [[ ${docker_machine_out} =~ "Error checking TLS connection" ]]; then while ! docker_machine_out=$(docker-machine env "${DOCKER_MACHINE_NAME}" 2>&1); do
echo "${docker_machine_out}" if [[ ${docker_machine_out} =~ "Error checking TLS connection" ]]; then
docker-machine regenerate-certs "${DOCKER_MACHINE_NAME}" echo "${docker_machine_out}"
else docker-machine regenerate-certs "${DOCKER_MACHINE_NAME}"
sleep 1 else
fi sleep 1
done fi
eval "$(docker-machine env "${DOCKER_MACHINE_NAME}")" done
openim::log::status "A Docker host using docker-machine named '${DOCKER_MACHINE_NAME}' is ready to go!" eval "$(docker-machine env "${DOCKER_MACHINE_NAME}")"
return 0 openim::log::status "A Docker host using docker-machine named '${DOCKER_MACHINE_NAME}' is ready to go!"
return 0
} }
function openim::build::is_gnu_sed() { function openim::build::is_gnu_sed() {
[[ $(sed --version 2>&1) == *GNU* ]] [[ $(sed --version 2>&1) == *GNU* ]]
} }
function openim::build::ensure_rsync() { function openim::build::ensure_rsync() {
if [[ -z "$(which rsync)" ]]; then if [[ -z "$(which rsync)" ]]; then
openim::log::error "Can't find 'rsync' in PATH, please fix and retry." openim::log::error "Can't find 'rsync' in PATH, please fix and retry."
return 1 return 1
fi fi
} }
function openim::build::update_dockerfile() { function openim::build::update_dockerfile() {
if openim::build::is_gnu_sed; then if openim::build::is_gnu_sed; then
sed_opts=(-i) sed_opts=(-i)
else else
sed_opts=(-i '') sed_opts=(-i '')
fi fi
sed "${sed_opts[@]}" "s/OPENIM_BUILD_IMAGE_CROSS_TAG/${OPENIM_BUILD_IMAGE_CROSS_TAG}/" "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile" sed "${sed_opts[@]}" "s/OPENIM_BUILD_IMAGE_CROSS_TAG/${OPENIM_BUILD_IMAGE_CROSS_TAG}/" "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
} }
function openim::build::set_proxy() { function openim::build::set_proxy() {
if [[ -n "${OPENIMRNETES_HTTPS_PROXY:-}" ]]; then if [[ -n "${OPENIMRNETES_HTTPS_PROXY:-}" ]]; then
echo "ENV https_proxy $OPENIMRNETES_HTTPS_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile" echo "ENV https_proxy $OPENIMRNETES_HTTPS_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
fi fi
if [[ -n "${OPENIMRNETES_HTTP_PROXY:-}" ]]; then if [[ -n "${OPENIMRNETES_HTTP_PROXY:-}" ]]; then
echo "ENV http_proxy $OPENIMRNETES_HTTP_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile" echo "ENV http_proxy $OPENIMRNETES_HTTP_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
fi fi
if [[ -n "${OPENIMRNETES_NO_PROXY:-}" ]]; then if [[ -n "${OPENIMRNETES_NO_PROXY:-}" ]]; then
echo "ENV no_proxy $OPENIMRNETES_NO_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile" echo "ENV no_proxy $OPENIMRNETES_NO_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
fi fi
} }
function openim::build::ensure_docker_in_path() { function openim::build::ensure_docker_in_path() {
if [[ -z "$(which docker)" ]]; then if [[ -z "$(which docker)" ]]; then
openim::log::error "Can't find 'docker' in PATH, please fix and retry." openim::log::error "Can't find 'docker' in PATH, please fix and retry."
openim::log::error "See https://docs.docker.com/installation/#installation for installation instructions." openim::log::error "See https://docs.docker.com/installation/#installation for installation instructions."
return 1 return 1
fi fi
} }
function openim::build::ensure_tar() { function openim::build::ensure_tar() {
if [[ -n "${TAR:-}" ]]; then if [[ -n "${TAR:-}" ]]; then
return return
fi fi
# Find gnu tar if it is available, bomb out if not. # Find gnu tar if it is available, bomb out if not.
TAR=tar TAR=tar
if which gtar &>/dev/null; then if which gtar &>/dev/null; then
TAR=gtar TAR=gtar
else else
if which gnutar &>/dev/null; then if which gnutar &>/dev/null; then
TAR=gnutar TAR=gnutar
fi
fi
if ! "${TAR}" --version | grep -q GNU; then
echo " !!! Cannot find GNU tar. Build on Linux or install GNU tar"
echo " on Mac OS X (brew install gnu-tar)."
return 1
fi fi
fi
if ! "${TAR}" --version | grep -q GNU; then
echo " !!! Cannot find GNU tar. Build on Linux or install GNU tar"
echo " on Mac OS X (brew install gnu-tar)."
return 1
fi
} }
function openim::build::has_docker() { function openim::build::has_docker() {
which docker &> /dev/null which docker &> /dev/null
} }
function openim::build::has_ip() { function openim::build::has_ip() {
which ip &> /dev/null && ip -Version | grep 'iproute2' &> /dev/null which ip &> /dev/null && ip -Version | grep 'iproute2' &> /dev/null
} }
# Detect if a specific image exists # Detect if a specific image exists
@ -304,12 +304,12 @@ function openim::build::has_ip() {
# $1 - image repo name # $1 - image repo name
# $2 - image tag # $2 - image tag
function openim::build::docker_image_exists() { function openim::build::docker_image_exists() {
[[ -n $1 && -n $2 ]] || { [[ -n $1 && -n $2 ]] || {
openim::log::error "Internal error. Image not specified in docker_image_exists." openim::log::error "Internal error. Image not specified in docker_image_exists."
exit 2 exit 2
} }
[[ $("${DOCKER[@]}" images -q "${1}:${2}") ]] [[ $("${DOCKER[@]}" images -q "${1}:${2}") ]]
} }
# Delete all images that match a tag prefix except for the "current" version # Delete all images that match a tag prefix except for the "current" version
@ -318,21 +318,21 @@ function openim::build::docker_image_exists() {
# $2: The tag base. We consider any image that matches $2* # $2: The tag base. We consider any image that matches $2*
# $3: The current image not to delete if provided # $3: The current image not to delete if provided
function openim::build::docker_delete_old_images() { function openim::build::docker_delete_old_images() {
# In Docker 1.12, we can replace this with # In Docker 1.12, we can replace this with
# docker images "$1" --format "{{.Tag}}" # docker images "$1" --format "{{.Tag}}"
for tag in $("${DOCKER[@]}" images "${1}" | tail -n +2 | awk '{print $2}') ; do for tag in $("${DOCKER[@]}" images "${1}" | tail -n +2 | awk '{print $2}') ; do
if [[ "${tag}" != "${2}"* ]] ; then if [[ "${tag}" != "${2}"* ]] ; then
V=3 openim::log::status "Keeping image ${1}:${tag}" V=3 openim::log::status "Keeping image ${1}:${tag}"
continue continue
fi fi
if [[ -z "${3:-}" || "${tag}" != "${3}" ]] ; then if [[ -z "${3:-}" || "${tag}" != "${3}" ]] ; then
V=2 openim::log::status "Deleting image ${1}:${tag}" V=2 openim::log::status "Deleting image ${1}:${tag}"
"${DOCKER[@]}" rmi "${1}:${tag}" >/dev/null "${DOCKER[@]}" rmi "${1}:${tag}" >/dev/null
else else
V=3 openim::log::status "Keeping image ${1}:${tag}" V=3 openim::log::status "Keeping image ${1}:${tag}"
fi fi
done done
} }
# Stop and delete all containers that match a pattern # Stop and delete all containers that match a pattern
@ -340,36 +340,36 @@ function openim::build::docker_delete_old_images() {
# $1: The base container prefix # $1: The base container prefix
# $2: The current container to keep, if provided # $2: The current container to keep, if provided
function openim::build::docker_delete_old_containers() { function openim::build::docker_delete_old_containers() {
# In Docker 1.12 we can replace this line with # In Docker 1.12 we can replace this line with
# docker ps -a --format="{{.Names}}" # docker ps -a --format="{{.Names}}"
for container in $("${DOCKER[@]}" ps -a | tail -n +2 | awk '{print $NF}') ; do for container in $("${DOCKER[@]}" ps -a | tail -n +2 | awk '{print $NF}') ; do
if [[ "${container}" != "${1}"* ]] ; then if [[ "${container}" != "${1}"* ]] ; then
V=3 openim::log::status "Keeping container ${container}" V=3 openim::log::status "Keeping container ${container}"
continue continue
fi fi
if [[ -z "${2:-}" || "${container}" != "${2}" ]] ; then if [[ -z "${2:-}" || "${container}" != "${2}" ]] ; then
V=2 openim::log::status "Deleting container ${container}" V=2 openim::log::status "Deleting container ${container}"
openim::build::destroy_container "${container}" openim::build::destroy_container "${container}"
else else
V=3 openim::log::status "Keeping container ${container}" V=3 openim::log::status "Keeping container ${container}"
fi fi
done done
} }
# Takes $1 and computes a short has for it. Useful for unique tag generation # Takes $1 and computes a short has for it. Useful for unique tag generation
function openim::build::short_hash() { function openim::build::short_hash() {
[[ $# -eq 1 ]] || { [[ $# -eq 1 ]] || {
openim::log::error "Internal error. No data based to short_hash." openim::log::error "Internal error. No data based to short_hash."
exit 2 exit 2
} }
local short_hash local short_hash
if which md5 >/dev/null 2>&1; then if which md5 >/dev/null 2>&1; then
short_hash=$(md5 -q -s "$1") short_hash=$(md5 -q -s "$1")
else else
short_hash=$(echo -n "$1" | md5sum) short_hash=$(echo -n "$1" | md5sum)
fi fi
echo "${short_hash:0:10}" echo "${short_hash:0:10}"
} }
# Pedantically kill, wait-on and remove a container. The -f -v options # Pedantically kill, wait-on and remove a container. The -f -v options
@ -377,15 +377,15 @@ function openim::build::short_hash() {
# container, wait to ensure it's stopped, then try the remove. This is # container, wait to ensure it's stopped, then try the remove. This is
# a workaround for bug https://github.com/docker/docker/issues/3968. # a workaround for bug https://github.com/docker/docker/issues/3968.
function openim::build::destroy_container() { function openim::build::destroy_container() {
"${DOCKER[@]}" kill "$1" >/dev/null 2>&1 || true "${DOCKER[@]}" kill "$1" >/dev/null 2>&1 || true
if [[ $("${DOCKER[@]}" version --format '{{.Server.Version}}') = 17.06.0* ]]; then if [[ $("${DOCKER[@]}" version --format '{{.Server.Version}}') = 17.06.0* ]]; then
# Workaround https://github.com/moby/moby/issues/33948. # Workaround https://github.com/moby/moby/issues/33948.
# TODO: remove when 17.06.0 is not relevant anymore # TODO: remove when 17.06.0 is not relevant anymore
DOCKER_API_VERSION=v1.29 "${DOCKER[@]}" wait "$1" >/dev/null 2>&1 || true DOCKER_API_VERSION=v1.29 "${DOCKER[@]}" wait "$1" >/dev/null 2>&1 || true
else else
"${DOCKER[@]}" wait "$1" >/dev/null 2>&1 || true "${DOCKER[@]}" wait "$1" >/dev/null 2>&1 || true
fi fi
"${DOCKER[@]}" rm -f -v "$1" >/dev/null 2>&1 || true "${DOCKER[@]}" rm -f -v "$1" >/dev/null 2>&1 || true
} }
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -393,47 +393,47 @@ function openim::build::destroy_container() {
function openim::build::clean() { function openim::build::clean() {
if openim::build::has_docker ; then if openim::build::has_docker ; then
openim::build::docker_delete_old_containers "${OPENIM_BUILD_CONTAINER_NAME_BASE}" openim::build::docker_delete_old_containers "${OPENIM_BUILD_CONTAINER_NAME_BASE}"
openim::build::docker_delete_old_containers "${OPENIM_RSYNC_CONTAINER_NAME_BASE}" openim::build::docker_delete_old_containers "${OPENIM_RSYNC_CONTAINER_NAME_BASE}"
openim::build::docker_delete_old_containers "${OPENIM_DATA_CONTAINER_NAME_BASE}" openim::build::docker_delete_old_containers "${OPENIM_DATA_CONTAINER_NAME_BASE}"
openim::build::docker_delete_old_images "${OPENIM_BUILD_IMAGE_REPO}" "${OPENIM_BUILD_IMAGE_TAG_BASE}" openim::build::docker_delete_old_images "${OPENIM_BUILD_IMAGE_REPO}" "${OPENIM_BUILD_IMAGE_TAG_BASE}"
V=2 openim::log::status "Cleaning all untagged docker images" V=2 openim::log::status "Cleaning all untagged docker images"
"${DOCKER[@]}" rmi "$("${DOCKER[@]}" images -q --filter 'dangling=true')" 2> /dev/null || true "${DOCKER[@]}" rmi "$("${DOCKER[@]}" images -q --filter 'dangling=true')" 2> /dev/null || true
fi fi
if [[ -d "${LOCAL_OUTPUT_ROOT}" ]]; then if [[ -d "${LOCAL_OUTPUT_ROOT}" ]]; then
openim::log::status "Removing _output directory" openim::log::status "Removing _output directory"
rm -rf "${LOCAL_OUTPUT_ROOT}" rm -rf "${LOCAL_OUTPUT_ROOT}"
fi fi
} }
# Set up the context directory for the openim-build image and build it. # Set up the context directory for the openim-build image and build it.
function openim::build::build_image() { function openim::build::build_image() {
mkdir -p "${LOCAL_OUTPUT_BUILD_CONTEXT}" mkdir -p "${LOCAL_OUTPUT_BUILD_CONTEXT}"
# Make sure the context directory owned by the right user for syncing sources to container. # Make sure the context directory owned by the right user for syncing sources to container.
chown -R "${USER_ID}":"${GROUP_ID}" "${LOCAL_OUTPUT_BUILD_CONTEXT}" chown -R "${USER_ID}":"${GROUP_ID}" "${LOCAL_OUTPUT_BUILD_CONTEXT}"
cp /etc/localtime "${LOCAL_OUTPUT_BUILD_CONTEXT}/" 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/Dockerfile" "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
cp "${OPENIM_ROOT}/build/build-image/rsyncd.sh" "${LOCAL_OUTPUT_BUILD_CONTEXT}/" 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" 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" chmod go= "${LOCAL_OUTPUT_BUILD_CONTEXT}/rsyncd.password"
openim::build::update_dockerfile openim::build::update_dockerfile
openim::build::set_proxy openim::build::set_proxy
openim::build::docker_build "${OPENIM_BUILD_IMAGE}" "${LOCAL_OUTPUT_BUILD_CONTEXT}" 'false' openim::build::docker_build "${OPENIM_BUILD_IMAGE}" "${LOCAL_OUTPUT_BUILD_CONTEXT}" 'false'
# Clean up old versions of everything # Clean up old versions of everything
openim::build::docker_delete_old_containers "${OPENIM_BUILD_CONTAINER_NAME_BASE}" "${OPENIM_BUILD_CONTAINER_NAME}" openim::build::docker_delete_old_containers "${OPENIM_BUILD_CONTAINER_NAME_BASE}" "${OPENIM_BUILD_CONTAINER_NAME}"
openim::build::docker_delete_old_containers "${OPENIM_RSYNC_CONTAINER_NAME_BASE}" "${OPENIM_RSYNC_CONTAINER_NAME}" openim::build::docker_delete_old_containers "${OPENIM_RSYNC_CONTAINER_NAME_BASE}" "${OPENIM_RSYNC_CONTAINER_NAME}"
openim::build::docker_delete_old_containers "${OPENIM_DATA_CONTAINER_NAME_BASE}" "${OPENIM_DATA_CONTAINER_NAME}" openim::build::docker_delete_old_containers "${OPENIM_DATA_CONTAINER_NAME_BASE}" "${OPENIM_DATA_CONTAINER_NAME}"
openim::build::docker_delete_old_images "${OPENIM_BUILD_IMAGE_REPO}" "${OPENIM_BUILD_IMAGE_TAG_BASE}" "${OPENIM_BUILD_IMAGE_TAG}" openim::build::docker_delete_old_images "${OPENIM_BUILD_IMAGE_REPO}" "${OPENIM_BUILD_IMAGE_TAG_BASE}" "${OPENIM_BUILD_IMAGE_TAG}"
openim::build::ensure_data_container openim::build::ensure_data_container
openim::build::sync_to_container openim::build::sync_to_container
} }
# Build a docker image from a Dockerfile. # Build a docker image from a Dockerfile.
@ -441,14 +441,14 @@ function openim::build::build_image() {
# $2 is the location of the "context" directory, with the Dockerfile at the root. # $2 is the location of the "context" directory, with the Dockerfile at the root.
# $3 is the value to set the --pull flag for docker build; true by default # $3 is the value to set the --pull flag for docker build; true by default
function openim::build::docker_build() { function openim::build::docker_build() {
local -r image=$1 local -r image=$1
local -r context_dir=$2 local -r context_dir=$2
local -r pull="${3:-true}" local -r pull="${3:-true}"
local -ra build_cmd=("${DOCKER[@]}" build -t "${image}" "--pull=${pull}" "${context_dir}") local -ra build_cmd=("${DOCKER[@]}" build -t "${image}" "--pull=${pull}" "${context_dir}")
openim::log::status "Building Docker image ${image}" openim::log::status "Building Docker image ${image}"
local docker_output local docker_output
docker_output=$("${build_cmd[@]}" 2>&1) || { docker_output=$("${build_cmd[@]}" 2>&1) || {
cat <<EOF >&2 cat <<EOF >&2
+++ Docker build command failed for ${image} +++ Docker build command failed for ${image}
@ -459,61 +459,61 @@ To retry manually, run:
${build_cmd[*]} ${build_cmd[*]}
EOF EOF
return 1 return 1
} }
} }
function openim::build::ensure_data_container() { function openim::build::ensure_data_container() {
# If the data container exists AND exited successfully, we can use it. # If the data container exists AND exited successfully, we can use it.
# Otherwise nuke it and start over. # Otherwise nuke it and start over.
local ret=0 local ret=0
local code=0 local code=0
code=$(docker inspect \ code=$(docker inspect \
-f '{{.State.ExitCode}}' \ -f '{{.State.ExitCode}}' \
"${OPENIM_DATA_CONTAINER_NAME}" 2>/dev/null) || ret=$? "${OPENIM_DATA_CONTAINER_NAME}" 2>/dev/null) || ret=$?
if [[ "${ret}" == 0 && "${code}" != 0 ]]; then if [[ "${ret}" == 0 && "${code}" != 0 ]]; then
openim::build::destroy_container "${OPENIM_DATA_CONTAINER_NAME}" openim::build::destroy_container "${OPENIM_DATA_CONTAINER_NAME}"
ret=1 ret=1
fi fi
if [[ "${ret}" != 0 ]]; then if [[ "${ret}" != 0 ]]; then
openim::log::status "Creating data container ${OPENIM_DATA_CONTAINER_NAME}" openim::log::status "Creating data container ${OPENIM_DATA_CONTAINER_NAME}"
# We have to ensure the directory exists, or else the docker run will # We have to ensure the directory exists, or else the docker run will
# create it as root. # create it as root.
mkdir -p "${LOCAL_OUTPUT_GOPATH}" mkdir -p "${LOCAL_OUTPUT_GOPATH}"
# We want this to run as root to be able to chown, so non-root users can # We want this to run as root to be able to chown, so non-root users can
# later use the result as a data container. This run both creates the data # later use the result as a data container. This run both creates the data
# container and chowns the GOPATH. # container and chowns the GOPATH.
# #
# The data container creates volumes for all of the directories that store # The data container creates volumes for all of the directories that store
# intermediates for the Go build. This enables incremental builds across # intermediates for the Go build. This enables incremental builds across
# Docker sessions. The *_cgo paths are re-compiled versions of the go std # Docker sessions. The *_cgo paths are re-compiled versions of the go std
# libraries for true static building. # libraries for true static building.
local -ra docker_cmd=( local -ra docker_cmd=(
"${DOCKER[@]}" run "${DOCKER[@]}" run
--volume "${REMOTE_ROOT}" # white-out the whole output dir --volume "${REMOTE_ROOT}" # white-out the whole output dir
--volume /usr/local/go/pkg/linux_386_cgo --volume /usr/local/go/pkg/linux_386_cgo
--volume /usr/local/go/pkg/linux_amd64_cgo --volume /usr/local/go/pkg/linux_amd64_cgo
--volume /usr/local/go/pkg/linux_arm_cgo --volume /usr/local/go/pkg/linux_arm_cgo
--volume /usr/local/go/pkg/linux_arm64_cgo --volume /usr/local/go/pkg/linux_arm64_cgo
--volume /usr/local/go/pkg/linux_ppc64le_cgo --volume /usr/local/go/pkg/linux_ppc64le_cgo
--volume /usr/local/go/pkg/darwin_amd64_cgo --volume /usr/local/go/pkg/darwin_amd64_cgo
--volume /usr/local/go/pkg/darwin_386_cgo --volume /usr/local/go/pkg/darwin_386_cgo
--volume /usr/local/go/pkg/windows_amd64_cgo --volume /usr/local/go/pkg/windows_amd64_cgo
--volume /usr/local/go/pkg/windows_386_cgo --volume /usr/local/go/pkg/windows_386_cgo
--name "${OPENIM_DATA_CONTAINER_NAME}" --name "${OPENIM_DATA_CONTAINER_NAME}"
--hostname "${HOSTNAME}" --hostname "${HOSTNAME}"
"${OPENIM_BUILD_IMAGE}" "${OPENIM_BUILD_IMAGE}"
chown -R "${USER_ID}":"${GROUP_ID}" chown -R "${USER_ID}":"${GROUP_ID}"
"${REMOTE_ROOT}" "${REMOTE_ROOT}"
/usr/local/go/pkg/ /usr/local/go/pkg/
) )
"${docker_cmd[@]}" "${docker_cmd[@]}"
fi fi
} }
# Build all openim commands. # Build all openim commands.
function openim::build::build_command() { function openim::build::build_command() {
openim::log::status "Running build command..." openim::log::status "Running build command..."
make -C "${OPENIM_ROOT}" multiarch make -C "${OPENIM_ROOT}" multiarch
} }

@ -19,11 +19,11 @@
echo "mode: atomic" > coverage.txt echo "mode: atomic" > coverage.txt
for d in $(find ./* -maxdepth 10 -type d); do for d in $(find ./* -maxdepth 10 -type d); do
if ls $d/*.go &> /dev/null; then if ls $d/*.go &> /dev/null; then
go test -coverprofile=profile.out -covermode=atomic $d go test -coverprofile=profile.out -covermode=atomic $d
if [ -f profile.out ]; then if [ -f profile.out ]; then
cat profile.out | grep -v "mode: " >> /tmp/coverage.txt cat profile.out | grep -v "mode: " >> /tmp/coverage.txt
rm profile.out rm profile.out
fi
fi fi
fi
done done

@ -15,16 +15,16 @@
if ! command -v pv &> /dev/null if ! command -v pv &> /dev/null
then then
echo "pv not found, installing..." echo "pv not found, installing..."
if [ -e /etc/debian_version ]; then if [ -e /etc/debian_version ]; then
sudo apt-get update sudo apt-get update
sudo apt-get install -y pv sudo apt-get install -y pv
elif [ -e /etc/redhat-release ]; then elif [ -e /etc/redhat-release ]; then
sudo yum install -y pv sudo yum install -y pv
else else
echo "Unsupported OS, please install pv manually." echo "Unsupported OS, please install pv manually."
exit 1 exit 1
fi fi
fi fi
readonly t_reset=$(tput sgr0) readonly t_reset=$(tput sgr0)
@ -42,8 +42,8 @@ openim::util::ensure-bash-version
trap 'openim::util::onCtrlC' INT trap 'openim::util::onCtrlC' INT
function openim::util::onCtrlC() { function openim::util::onCtrlC() {
echo -e "\n${t_reset}Ctrl+C Press it. It's exiting openim make init..." echo -e "\n${t_reset}Ctrl+C Press it. It's exiting openim make init..."
exit 0 exit 0
} }
openim::util::desc "========> Welcome to the OpenIM Demo" openim::util::desc "========> Welcome to the OpenIM Demo"

@ -22,61 +22,61 @@ cd "$OPENIM_ROOT"
openim::util::check_docker_and_compose_versions openim::util::check_docker_and_compose_versions
progress() { progress() {
local _main_pid="$1" local _main_pid="$1"
local _length=20 local _length=20
local _ratio=1 local _ratio=1
local _colors=("31" "32" "33" "34" "35" "36" "37") local _colors=("31" "32" "33" "34" "35" "36" "37")
local _wave=("▁" "▂" "▃" "▄" "▅" "▆" "▇" "█" "▇" "▆" "▅" "▄" "▃" "▂") local _wave=("▁" "▂" "▃" "▄" "▅" "▆" "▇" "█" "▇" "▆" "▅" "▄" "▃" "▂")
while pgrep -P "$_main_pid" &> /dev/null; do while pgrep -P "$_main_pid" &> /dev/null; do
local _mark='>' local _mark='>'
local _progress_bar= local _progress_bar=
for ((i = 1; i <= _length; i++)); do for ((i = 1; i <= _length; i++)); do
if ((i > _ratio)); then if ((i > _ratio)); then
_mark='-' _mark='-'
fi fi
_progress_bar="${_progress_bar}${_mark}" _progress_bar="${_progress_bar}${_mark}"
done
local _color_idx=$((_ratio % ${#_colors[@]}))
local _color_prefix="\033[${_colors[_color_idx]}m"
local _reset_suffix="\033[0m"
local _wave_idx=$((_ratio % ${#_wave[@]}))
local _wave_progress=${_wave[_wave_idx]}
printf "Progress: ${_color_prefix}${_progress_bar}${_reset_suffix} ${_wave_progress} Countdown: %2ds \r" "$_countdown"
((_ratio++))
((_ratio > _length)) && _ratio=1
sleep 0.1
done done
local _color_idx=$((_ratio % ${#_colors[@]}))
local _color_prefix="\033[${_colors[_color_idx]}m"
local _reset_suffix="\033[0m"
local _wave_idx=$((_ratio % ${#_wave[@]}))
local _wave_progress=${_wave[_wave_idx]}
printf "Progress: ${_color_prefix}${_progress_bar}${_reset_suffix} ${_wave_progress} Countdown: %2ds \r" "$_countdown"
((_ratio++))
((_ratio > _length)) && _ratio=1
sleep 0.1
done
} }
countdown() { countdown() {
local _duration="$1" local _duration="$1"
for ((i = _duration; i >= 1; i--)); do for ((i = _duration; i >= 1; i--)); do
printf "\rCountdown: %2ds \r" "$i" printf "\rCountdown: %2ds \r" "$i"
sleep 1 sleep 1
done done
printf "\rCountdown: %2ds \r" "$_duration" printf "\rCountdown: %2ds \r" "$_duration"
} }
do_sth() { do_sth() {
echo "++++++++++++++++++++++++" echo "++++++++++++++++++++++++"
progress $$ & progress $$ &
local _progress_pid=$! local _progress_pid=$!
local _countdown=30 local _countdown=30
countdown "$_countdown" & countdown "$_countdown" &
local _countdown_pid=$! local _countdown_pid=$!
sleep 30 sleep 30
kill "$_progress_pid" "$_countdown_pid" kill "$_progress_pid" "$_countdown_pid"
"${SCRIPTS_ROOT}/check-all.sh" "${SCRIPTS_ROOT}/check-all.sh"
echo -e "${PURPLE_PREFIX}=========> Check docker-compose status ${COLOR_SUFFIX} \n" echo -e "${PURPLE_PREFIX}=========> Check docker-compose status ${COLOR_SUFFIX} \n"
} }
set -e set -e

@ -18,9 +18,9 @@ OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
version="${VERSION}" version="${VERSION}"
if [ "${version}" == "" ];then if [ "${version}" == "" ];then
version=v`${OPENIM_ROOT}/_output/tools/gsemver bump` version=v$(${OPENIM_ROOT}/_output/tools/gsemver bump)
fi fi
if [ -z "`git tag -l ${version}`" ];then if [ -z "$(git tag -l ${version})" ];then
git tag -a -m "release version ${version}" ${version} git tag -a -m "release version ${version}" ${version}
fi fi

@ -67,7 +67,7 @@ echo -e "=== any\nRepresents an untyped JSON map - see the description of the fi
asciidoctor definitions.adoc asciidoctor definitions.adoc
asciidoctor paths.adoc asciidoctor paths.adoc
cp ${OPENIM_OUTPUT_TMP}/definitions.html ${OPENIM_OUTPUT_TMP}/_output/ cp "$OPENIM_OUTPUT_TMP/definitions.html" "$OPENIM_OUTPUT_TMP/_output/"
cp ${OPENIM_OUTPUT_TMP}/paths.html ${OPENIM_OUTPUT_TMP}/_output/operations.html cp "$OPENIM_OUTPUT_TMP/paths.html" "$OPENIM_OUTPUT_TMP/_output/operations.html"
success "SUCCESS" success "SUCCESS"

@ -25,12 +25,12 @@ OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
source "${OPENIM_ROOT}/scripts/lib/init.sh" source "${OPENIM_ROOT}/scripts/lib/init.sh"
if [ $# -ne 2 ];then if [ $# -ne 2 ];then
openim::log::error "Usage: scripts/genconfig.sh scripts/environment.sh configs/openim-api.yaml" openim::log::error "Usage: scripts/genconfig.sh scripts/environment.sh configs/config.yaml"
exit 1 exit 1
fi fi
if [ -z "${OPENIM_IP}" ]; then if [ -z "${OPENIM_IP}" ]; then
openim::util::require-dig openim::util::require-dig
fi fi
source "${env_file}" source "${env_file}"
@ -40,15 +40,15 @@ declare -A envs
set +u set +u
for env in $(sed -n 's/^[^#].*${\(.*\)}.*/\1/p' ${template_file}) for env in $(sed -n 's/^[^#].*${\(.*\)}.*/\1/p' ${template_file})
do do
if [ -z "$(eval echo \$${env})" ];then if [ -z "$(eval echo \$${env})" ];then
openim::log::error "environment variable '${env}' not set" openim::log::error "environment variable '${env}' not set"
missing=true missing=true
fi fi
done done
if [ "${missing}" ];then if [ "${missing}" ];then
openim::log::error 'You may run `source scripts/environment.sh` to set these environment' openim::log::error "You may run 'source scripts/environment.sh' to set these environment"
exit 1 exit 1
fi fi
eval "cat << EOF eval "cat << EOF

@ -14,43 +14,43 @@
# limitations under the License. # limitations under the License.
DEFAULT_DIRS=( DEFAULT_DIRS=(
"pkg" "pkg"
"internal/pkg" "internal/pkg"
) )
BASE_URL="github.com/openimsdk/open-im-server" BASE_URL="github.com/openimsdk/open-im-server"
usage() { usage() {
echo "Usage: $0 [OPTIONS]" echo "Usage: $0 [OPTIONS]"
echo echo
echo "This script iterates over directories and generates doc.go if necessary." echo "This script iterates over directories and generates doc.go if necessary."
echo "By default, it processes 'pkg' and 'internal/pkg' directories." echo "By default, it processes 'pkg' and 'internal/pkg' directories."
echo echo
echo "Options:" echo "Options:"
echo " -d DIRS, --dirs DIRS Specify the directories to be processed, separated by commas. E.g., 'pkg,internal/pkg'." echo " -d DIRS, --dirs DIRS Specify the directories to be processed, separated by commas. E.g., 'pkg,internal/pkg'."
echo " -u URL, --url URL Set the base URL for the import path. Default is '$BASE_URL'." echo " -u URL, --url URL Set the base URL for the import path. Default is '$BASE_URL'."
echo " -h, --help Show this help message." echo " -h, --help Show this help message."
echo echo
} }
process_dir() { process_dir() {
local dir=$1 local dir=$1
local base_url=$2 local base_url=$2
for d in $(find $dir -type d); do for d in $(find $dir -type d); do
if [ ! -f $d/doc.go ]; then if [ ! -f $d/doc.go ]; then
if ls $d/*.go > /dev/null 2>&1; then if ls $d/*.go > /dev/null 2>&1; then
echo $d/doc.go echo $d/doc.go
echo "package $(basename $d) // import \"$base_url/$d\"" > $d/doc.go echo "package $(basename $d) // import \"$base_url/$d\"" > $d/doc.go
fi fi
fi fi
done done
} }
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
key="$1" key="$1"
case $key in case $key in
-d|--dirs) -d|--dirs)
IFS=',' read -ra DIRS <<< "$2" IFS=',' read -ra DIRS <<< "$2"
shift # shift past argument shift # shift past argument
shift # shift past value shift # shift past value

@ -34,15 +34,15 @@ RED="\e[31m"
ENDCOLOR="\e[0m" ENDCOLOR="\e[0m"
printMessage() { printMessage() {
printf "${YELLOW}OpenIM : $1${ENDCOLOR}\n" printf "${YELLOW}OpenIM : $1${ENDCOLOR}\n"
} }
printSuccess() { printSuccess() {
printf "${GREEN}OpenIM : $1${ENDCOLOR}\n" printf "${GREEN}OpenIM : $1${ENDCOLOR}\n"
} }
printError() { printError() {
printf "${RED}OpenIM : $1${ENDCOLOR}\n" printf "${RED}OpenIM : $1${ENDCOLOR}\n"
} }
printMessage "Running the OpenIM commit-msg hook." printMessage "Running the OpenIM commit-msg hook."
@ -50,9 +50,9 @@ printMessage "Running the OpenIM commit-msg hook."
# This example catches duplicate Signed-off-by lines. # This example catches duplicate Signed-off-by lines.
test "" = "$(grep '^Signed-off-by: ' "$1" | test "" = "$(grep '^Signed-off-by: ' "$1" |
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
echo >&2 Duplicate Signed-off-by lines. echo >&2 Duplicate Signed-off-by lines.
exit 1 exit 1
} }
# TODO: go-gitlint dir set # TODO: go-gitlint dir set
@ -60,21 +60,21 @@ OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/../..
GITLINT_DIR="$OPENIM_ROOT/_output/tools/go-gitlint" GITLINT_DIR="$OPENIM_ROOT/_output/tools/go-gitlint"
$GITLINT_DIR \ $GITLINT_DIR \
--msg-file=$1 \ --msg-file=$1 \
--subject-regex="^(build|chore|ci|docs|feat|feature|fix|perf|refactor|revert|style|bot|test)(.*)?:\s?.*" \ --subject-regex="^(build|chore|ci|docs|feat|feature|fix|perf|refactor|revert|style|bot|test)(.*)?:\s?.*" \
--subject-maxlen=150 \ --subject-maxlen=150 \
--subject-minlen=10 \ --subject-minlen=10 \
--body-regex=".*" \ --body-regex=".*" \
--max-parents=1 --max-parents=1
if [ $? -ne 0 ] if [ $? -ne 0 ]
then then
if ! command -v $GITLINT_DIR &>/dev/null; then if ! command -v $GITLINT_DIR &>/dev/null; then
printError "$GITLINT_DIR not found. Please run 'make tools' OR 'make tools.verify.go-gitlint' make verto install it." printError "$GITLINT_DIR not found. Please run 'make tools' OR 'make tools.verify.go-gitlint' make verto install it."
fi fi
printError "Please fix your commit message to match kubecub coding standards" printError "Please fix your commit message to match kubecub coding standards"
printError "https://gist.github.com/cubxxw/126b72104ac0b0ca484c9db09c3e5694#file-githook-md" printError "https://gist.github.com/cubxxw/126b72104ac0b0ca484c9db09c3e5694#file-githook-md"
exit 1 exit 1
fi fi
### Add Sign-off-by line to the end of the commit message ### Add Sign-off-by line to the end of the commit message
@ -88,5 +88,5 @@ SIGNED_OFF_BY_EXISTS=$?
# Add "Signed-off-by" line if it doesn't exist # Add "Signed-off-by" line if it doesn't exist
if [ $SIGNED_OFF_BY_EXISTS -ne 0 ]; then if [ $SIGNED_OFF_BY_EXISTS -ne 0 ]; then
echo -e "\nSigned-off-by: $NAME <$EMAIL>" >> "$1" echo -e "\nSigned-off-by: $NAME <$EMAIL>" >> "$1"
fi fi

@ -34,15 +34,15 @@ RED="\e[31m"
ENDCOLOR="\e[0m" ENDCOLOR="\e[0m"
printMessage() { printMessage() {
printf "${YELLOW}openim : $1${ENDCOLOR}\n" printf "${YELLOW}openim : $1${ENDCOLOR}\n"
} }
printSuccess() { printSuccess() {
printf "${GREEN}openim : $1${ENDCOLOR}\n" printf "${GREEN}openim : $1${ENDCOLOR}\n"
} }
printError() { printError() {
printf "${RED}openim : $1${ENDCOLOR}\n" printf "${RED}openim : $1${ENDCOLOR}\n"
} }
printMessage "Running local openim pre-commit hook." printMessage "Running local openim pre-commit hook."
@ -55,8 +55,8 @@ limit=${GIT_FILE_SIZE_LIMIT:-2000000} # Default 2MB
limitInMB=$(( $limit / 1000000 )) limitInMB=$(( $limit / 1000000 ))
function file_too_large(){ function file_too_large(){
filename=$0 filename=$0
filesize=$(( $1 / 2**20 )) filesize=$(( $1 / 2**20 ))
cat <<HEREDOC cat <<HEREDOC
@ -65,7 +65,7 @@ function file_too_large(){
Commit aborted Commit aborted
HEREDOC HEREDOC
git status git status
} }
@ -77,9 +77,9 @@ empty_tree=$( git hash-object -t tree /dev/null )
if git rev-parse --verify HEAD > /dev/null 2>&1 if git rev-parse --verify HEAD > /dev/null 2>&1
then then
against=HEAD against=HEAD
else else
against="$empty_tree" against="$empty_tree"
fi fi
# Set split so that for loop below can handle spaces in file names by splitting on line breaks # Set split so that for loop below can handle spaces in file names by splitting on line breaks

@ -25,20 +25,20 @@ local_branch="$(git rev-parse --abbrev-ref HEAD)"
valid_branch_regex="^(main|master|develop|release(-[a-zA-Z0-9._-]+)?)$|(feature|feat|openim|hotfix|test|bug|ci|cicd|style|)\/[a-z0-9._-]+$|^HEAD$" valid_branch_regex="^(main|master|develop|release(-[a-zA-Z0-9._-]+)?)$|(feature|feat|openim|hotfix|test|bug|ci|cicd|style|)\/[a-z0-9._-]+$|^HEAD$"
printMessage() { printMessage() {
printf "${YELLOW}OpenIM : $1${ENDCOLOR}\n" printf "${YELLOW}OpenIM : $1${ENDCOLOR}\n"
} }
printSuccess() { printSuccess() {
printf "${GREEN}OpenIM : $1${ENDCOLOR}\n" printf "${GREEN}OpenIM : $1${ENDCOLOR}\n"
} }
printError() { printError() {
printf "${RED}OpenIM : $1${ENDCOLOR}\n" printf "${RED}OpenIM : $1${ENDCOLOR}\n"
} }
printMessage "Running local OpenIM pre-push hook." printMessage "Running local OpenIM pre-push hook."
if [[ `git status --porcelain` ]]; then if [[ $(git status --porcelain) ]]; then
printError "This scripts needs to run against committed code only. Please commit or stash you changes." printError "This scripts needs to run against committed code only. Please commit or stash you changes."
exit 1 exit 1
fi fi

@ -31,7 +31,7 @@ readonly ENV_FILE=${ENV_FILE:-"${OPENIM_ROOT}/scripts/install/environment.sh"}
# Templates for configuration files # Templates for configuration files
declare -A TEMPLATES=( declare -A TEMPLATES=(
["${OPENIM_ROOT}/deployments/templates/env-template.yaml"]="${OPENIM_ROOT}/.env" ["${OPENIM_ROOT}/deployments/templates/env-template.yaml"]="${OPENIM_ROOT}/.env"
["${OPENIM_ROOT}/deployments/templates/openim.yaml"]="${OPENIM_ROOT}/config/config.yaml" ["${OPENIM_ROOT}/deployments/templates/config.yaml"]="${OPENIM_ROOT}/config/config.yaml"
["${OPENIM_ROOT}/deployments/templates/prometheus.yml"]="${OPENIM_ROOT}/config/prometheus.yml" ["${OPENIM_ROOT}/deployments/templates/prometheus.yml"]="${OPENIM_ROOT}/config/prometheus.yml"
["${OPENIM_ROOT}/deployments/templates/alertmanager.yml"]="${OPENIM_ROOT}/config/alertmanager.yml" ["${OPENIM_ROOT}/deployments/templates/alertmanager.yml"]="${OPENIM_ROOT}/config/alertmanager.yml"
) )
@ -39,7 +39,7 @@ declare -A TEMPLATES=(
# Templates for example files # Templates for example files
declare -A EXAMPLES=( declare -A EXAMPLES=(
["${OPENIM_ROOT}/deployments/templates/env-template.yaml"]="${OPENIM_ROOT}/config/templates/env.template" ["${OPENIM_ROOT}/deployments/templates/env-template.yaml"]="${OPENIM_ROOT}/config/templates/env.template"
["${OPENIM_ROOT}/deployments/templates/openim.yaml"]="${OPENIM_ROOT}/config/templates/config.yaml.template" ["${OPENIM_ROOT}/deployments/templates/config.yaml"]="${OPENIM_ROOT}/config/templates/config.yaml.template"
["${OPENIM_ROOT}/deployments/templates/prometheus.yml"]="${OPENIM_ROOT}/config/templates/prometheus.yml.template" ["${OPENIM_ROOT}/deployments/templates/prometheus.yml"]="${OPENIM_ROOT}/config/templates/prometheus.yml.template"
["${OPENIM_ROOT}/deployments/templates/alertmanager.yml"]="${OPENIM_ROOT}/config/templates/alertmanager.yml.template" ["${OPENIM_ROOT}/deployments/templates/alertmanager.yml"]="${OPENIM_ROOT}/config/templates/alertmanager.yml.template"
) )
@ -95,8 +95,12 @@ generate_config_files() {
# Function to generate example files # Function to generate example files
generate_example_files() { generate_example_files() {
env_cmd="env -i" env_cmd="env -i"
env_vars["OPENIM_IP"]="127.0.0.1"
env_vars["LOG_STORAGE_LOCATION"]="../../"
for var in "${!env_vars[@]}"; do for var in "${!env_vars[@]}"; do
env_cmd+=" $var='${env_vars[$var]}'" env_cmd+=" $var='${env_vars[$var]}'"
done done
# Processing EXAMPLES array # Processing EXAMPLES array
@ -110,7 +114,6 @@ generate_example_files() {
local example_file="${COPY_EXAMPLES[$template]}" local example_file="${COPY_EXAMPLES[$template]}"
process_file "$template" "$example_file" false process_file "$template" "$example_file" false
done done
} }
# Function to process a single file, either by generating or copying # Function to process a single file, either by generating or copying
@ -122,7 +125,7 @@ process_file() {
if [[ -f "${output_file}" ]]; then if [[ -f "${output_file}" ]]; then
if [[ "${FORCE_OVERWRITE}" == true ]]; then if [[ "${FORCE_OVERWRITE}" == true ]]; then
openim::log::info "Force overwriting ${output_file}." openim::log::info "Force overwriting ${output_file}."
elif [[ "${SKIP_EXISTING}" == true ]]; then elif [[ "${SKIP_EXISTING}" == true ]]; then
openim::log::info "Skipping generation of ${output_file} as it already exists." openim::log::info "Skipping generation of ${output_file} as it already exists."
return return
else else
@ -147,15 +150,15 @@ process_file() {
exit 1 exit 1
fi fi
if [[ -n "${env_cmd}" ]]; then if [[ -n "${env_cmd}" ]]; then
eval "$env_cmd ${OPENIM_ROOT}/scripts/genconfig.sh '${ENV_FILE}' '${template}' > '${output_file}'" || { eval "$env_cmd ${OPENIM_ROOT}/scripts/genconfig.sh '${ENV_FILE}' '${template}' > '${output_file}'" || {
openim::log::error "Error processing template file ${template}" openim::log::error "Error processing template file ${template}"
exit 1 exit 1
} }
else else
"${OPENIM_ROOT}/scripts/genconfig.sh" "${ENV_FILE}" "${template}" > "${output_file}" || { "${OPENIM_ROOT}/scripts/genconfig.sh" "${ENV_FILE}" "${template}" > "${output_file}" || {
openim::log::error "Error processing template file ${template}" openim::log::error "Error processing template file ${template}"
exit 1 exit 1
} }
fi fi
else else
openim::log::info "📋 Copying ${template} to ${output_file}..." openim::log::info "📋 Copying ${template} to ${output_file}..."
@ -181,7 +184,6 @@ clean_config_files() {
# Function to clean example files # Function to clean example files
clean_example_files() { clean_example_files() {
# 合并 EXAMPLES 和 COPY_EXAMPLES 数组
local all_examples=("${EXAMPLES[@]}" "${COPY_EXAMPLES[@]}") local all_examples=("${EXAMPLES[@]}" "${COPY_EXAMPLES[@]}")
for example_file in "${all_examples[@]}"; do for example_file in "${all_examples[@]}"; do
@ -197,32 +199,32 @@ while [[ $# -gt 0 ]]; do
-h|--help) -h|--help)
show_help show_help
exit 0 exit 0
;; ;;
--force) --force)
FORCE_OVERWRITE=true FORCE_OVERWRITE=true
shift shift
;; ;;
--skip) --skip)
SKIP_EXISTING=true SKIP_EXISTING=true
shift shift
;; ;;
--examples) --examples)
GENERATE_EXAMPLES=true GENERATE_EXAMPLES=true
shift shift
;; ;;
--clean-config) --clean-config)
CLEAN_CONFIG=true CLEAN_CONFIG=true
shift shift
;; ;;
--clean-examples) --clean-examples)
CLEAN_EXAMPLES=true CLEAN_EXAMPLES=true
shift shift
;; ;;
*) *)
echo "Unknown option: $1" echo "Unknown option: $1"
show_help show_help
exit 1 exit 1
;; ;;
esac esac
done done

@ -25,9 +25,9 @@ source "${OPENIM_ROOT}/scripts/install/common.sh"
openim::log::info "\n# Begin Install OpenIM Config" openim::log::info "\n# Begin Install OpenIM Config"
for file in "${OPENIM_SERVER_TARGETS[@]}"; do for file in "${OPENIM_SERVER_TARGETS[@]}"; do
VARNAME="$(echo $file | tr '[:lower:]' '[:upper:]' | tr '.' '_' | tr '-' '_')" VARNAME="$(echo $file | tr '[:lower:]' '[:upper:]' | tr '.' '_' | tr '-' '_')"
VARVALUE="$OPENIM_OUTPUT_HOSTBIN/$file" VARVALUE="$OPENIM_OUTPUT_HOSTBIN/$file"
# /etc/profile.d/openim-env.sh # /etc/profile.d/openim-env.sh
echo "export $VARNAME=$VARVALUE" > /etc/profile.d/openim-env.sh echo "export $VARNAME=$VARVALUE" > /etc/profile.d/openim-env.sh
source /etc/profile.d/openim-env.sh source /etc/profile.d/openim-env.sh
done done

@ -39,62 +39,62 @@ OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
HOOKS_DIR="${OPENIM_ROOT}/.git/hooks" HOOKS_DIR="${OPENIM_ROOT}/.git/hooks"
help_info() { help_info() {
echo "Usage: $0 [options]" echo "Usage: $0 [options]"
echo echo
echo "This script helps to manage git hooks." echo "This script helps to manage git hooks."
echo echo
echo "Options:" echo "Options:"
echo " -h, --help Show this help message and exit." echo " -h, --help Show this help message and exit."
echo " -d, --delete Delete the hooks that have been added." echo " -d, --delete Delete the hooks that have been added."
echo " By default, it will prompt to enable git hooks." echo " By default, it will prompt to enable git hooks."
} }
delete_hooks() { delete_hooks() {
for file in ${OPENIM_ROOT}/scripts/githooks/*.sh; do for file in "${OPENIM_ROOT}"/scripts/githooks/*.sh; do
hook_name=$(basename "$file" .sh) # This removes the .sh extension hook_name=$(basename "$file" .sh) # This removes the .sh extension
rm -f "$HOOKS_DIR/$hook_name" rm -f "$HOOKS_DIR/$hook_name"
done done
echo "Git hooks have been deleted." echo "Git hooks have been deleted."
} }
enable_hooks() { enable_hooks() {
echo "Would you like to:" echo "Would you like to:"
echo "1) Enable git hooks mode" echo "1) Enable git hooks mode"
echo "2) Delete existing git hooks" echo "2) Delete existing git hooks"
echo "Please select a number (or any other key to exit):" echo "Please select a number (or any other key to exit):"
read -r choice read -r choice
case "$choice" in case "$choice" in
1) 1)
for file in ${OPENIM_ROOT}/scripts/githooks/*.sh; do for file in ${OPENIM_ROOT}/scripts/githooks/*.sh; do
hook_name=$(basename "$file" .sh) # This removes the .sh extension hook_name=$(basename "$file" .sh) # This removes the .sh extension
cp -f "$file" "$HOOKS_DIR/$hook_name" cp -f "$file" "$HOOKS_DIR/$hook_name"
done done
chmod +x $HOOKS_DIR/* chmod +x $HOOKS_DIR/*
echo "Git hooks mode has been enabled." echo "Git hooks mode has been enabled."
echo "With git hooks enabled, every time you perform a git action (e.g. git commit), the corresponding hooks script will be triggered automatically." echo "With git hooks enabled, every time you perform a git action (e.g. git commit), the corresponding hooks script will be triggered automatically."
echo "This means that if the size of the file you're committing exceeds the set limit (e.g. 42MB), the commit will be rejected." echo "This means that if the size of the file you're committing exceeds the set limit (e.g. 42MB), the commit will be rejected."
;; ;;
2) 2)
delete_hooks delete_hooks
;; ;;
*) *)
echo "Exiting without making changes." echo "Exiting without making changes."
;; ;;
esac esac
} }
case "$1" in case "$1" in
-h|--help) -h|--help)
help_info help_info
;; ;;
-d|--delete) -d|--delete)
delete_hooks delete_hooks
;; ;;
*) *)
enable_hooks enable_hooks
;; ;;
esac esac

@ -49,10 +49,10 @@ DOCKER_COMPOSE_COMMAND=
# Check if docker-compose command is available # Check if docker-compose command is available
openim::util::check_docker_and_compose_versions 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" openim::log::info "docker compose command is available"
DOCKER_COMPOSE_COMMAND="docker compose" DOCKER_COMPOSE_COMMAND="docker compose"
else else
DOCKER_COMPOSE_COMMAND="docker-compose" DOCKER_COMPOSE_COMMAND="docker-compose"
fi fi
export SERVER_IMAGE_VERSION export SERVER_IMAGE_VERSION
@ -67,12 +67,12 @@ ${DOCKER_COMPOSE_COMMAND} up -d
# Function to check container status # Function to check container status
check_containers() { check_containers() {
if ! ${DOCKER_COMPOSE_COMMAND} ps | grep -q 'Up'; then if ! ${DOCKER_COMPOSE_COMMAND} ps | grep -q 'Up'; then
echo "Error: One or more docker containers failed to start." echo "Error: One or more docker containers failed to start."
${DOCKER_COMPOSE_COMMAND} logs ${DOCKER_COMPOSE_COMMAND} logs
return 1 return 1
fi fi
return 0 return 0
} }
# Wait for a short period to allow containers to initialize # Wait for a short period to allow containers to initialize

@ -24,66 +24,66 @@ OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P)
# Start MongoDB service # Start MongoDB service
docker run -d \ docker run -d \
--name mongo \ --name mongo \
-p 37017:27017 \ -p 37017:27017 \
-v "${DATA_DIR}/components/mongodb/data/db:/data/db" \ -v "${DATA_DIR}/components/mongodb/data/db:/data/db" \
-v "${DATA_DIR}/components/mongodb/data/logs:/data/logs" \ -v "${DATA_DIR}/components/mongodb/data/logs:/data/logs" \
-v "${DATA_DIR}/components/mongodb/data/conf:/etc/mongo" \ -v "${DATA_DIR}/components/mongodb/data/conf:/etc/mongo" \
-v "./scripts/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro" \ -v "./scripts/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro" \
-e TZ=Asia/Shanghai \ -e TZ=Asia/Shanghai \
-e wiredTigerCacheSizeGB=1 \ -e wiredTigerCacheSizeGB=1 \
-e MONGO_INITDB_ROOT_USERNAME=${OPENIM_USER} \ -e MONGO_INITDB_ROOT_USERNAME=${OPENIM_USER} \
-e MONGO_INITDB_ROOT_PASSWORD=${PASSWORD} \ -e MONGO_INITDB_ROOT_PASSWORD=${PASSWORD} \
-e MONGO_INITDB_DATABASE=openIM \ -e MONGO_INITDB_DATABASE=openim_v3 \
-e MONGO_OPENIM_USERNAME=${OPENIM_USER} \ -e MONGO_OPENIM_USERNAME=${OPENIM_USER} \
-e MONGO_OPENIM_PASSWORD=${PASSWORD} \ -e MONGO_OPENIM_PASSWORD=${PASSWORD} \
--restart always \ --restart always \
mongo:6.0.2 --wiredTigerCacheSizeGB 1 --auth mongo:6.0.2 --wiredTigerCacheSizeGB 1 --auth
# Start Redis service # Start Redis service
docker run -d \ docker run -d \
--name redis \ --name redis \
-p 16379:6379 \ -p 16379:6379 \
-v "${DATA_DIR}/components/redis/data:/data" \ -v "${DATA_DIR}/components/redis/data:/data" \
-v "${DATA_DIR}/components/redis/config/redis.conf:/usr/local/redis/config/redis.conf" \ -v "${DATA_DIR}/components/redis/config/redis.conf:/usr/local/redis/config/redis.conf" \
-e TZ=Asia/Shanghai \ -e TZ=Asia/Shanghai \
--sysctl net.core.somaxconn=1024 \ --sysctl net.core.somaxconn=1024 \
--restart always \ --restart always \
redis:7.0.0 redis-server --requirepass ${PASSWORD} --appendonly yes redis:7.0.0 redis-server --requirepass ${PASSWORD} --appendonly yes
# Start Zookeeper service # Start Zookeeper service
docker run -d \ docker run -d \
--name zookeeper \ --name zookeeper \
-p 2181:2181 \ -p 2181:2181 \
-v "/etc/localtime:/etc/localtime" \ -v "/etc/localtime:/etc/localtime" \
-e TZ=Asia/Shanghai \ -e TZ=Asia/Shanghai \
--restart always \ --restart always \
wurstmeister/zookeeper wurstmeister/zookeeper
# Start Kafka service # Start Kafka service
docker run -d \ docker run -d \
--name kafka \ --name kafka \
-p 9092:9092 \ -p 9092:9092 \
-e TZ=Asia/Shanghai \ -e TZ=Asia/Shanghai \
-e KAFKA_BROKER_ID=0 \ -e KAFKA_BROKER_ID=0 \
-e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 \ -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 \
-e KAFKA_CREATE_TOPICS="latestMsgToRedis:8:1,msgToPush:8:1,offlineMsgToMongoMysql:8:1" \ -e KAFKA_CREATE_TOPICS="latestMsgToRedis:8:1,msgToPush:8:1,offlineMsgToMongoMysql:8:1" \
-e KAFKA_ADVERTISED_LISTENERS="INSIDE://127.0.0.1:9092,OUTSIDE://103.116.45.174:9092" \ -e KAFKA_ADVERTISED_LISTENERS="INSIDE://127.0.0.1:9092,OUTSIDE://103.116.45.174:9092" \
-e KAFKA_LISTENERS="INSIDE://:9092,OUTSIDE://:9093" \ -e KAFKA_LISTENERS="INSIDE://:9092,OUTSIDE://:9093" \
-e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP="INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT" \ -e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP="INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT" \
-e KAFKA_INTER_BROKER_LISTENER_NAME=INSIDE \ -e KAFKA_INTER_BROKER_LISTENER_NAME=INSIDE \
--restart always \ --restart always \
--link zookeeper \ --link zookeeper \
wurstmeister/kafka wurstmeister/kafka
# Start MinIO service # Start MinIO service
docker run -d \ docker run -d \
--name minio \ --name minio \
-p 10005:9000 \ -p 10005:9000 \
-p 9090:9090 \ -p 9090:9090 \
-v "/mnt/data:/data" \ -v "/mnt/data:/data" \
-v "/mnt/config:/root/.minio" \ -v "/mnt/config:/root/.minio" \
-e MINIO_ROOT_USER=${OPENIM_USER} \ -e MINIO_ROOT_USER=${OPENIM_USER} \
-e MINIO_ROOT_PASSWORD=${PASSWORD} \ -e MINIO_ROOT_PASSWORD=${PASSWORD} \
--restart always \ --restart always \
minio/minio server /data --console-address ':9090' minio/minio server /data --console-address ':9090'

@ -28,7 +28,7 @@ source "${OPENIM_ROOT}/scripts/lib/init.sh"
#TODO: Access to the OPENIM_IP networks outside, or you want to use the OPENIM_IP network #TODO: Access to the OPENIM_IP networks outside, or you want to use the OPENIM_IP network
# OPENIM_IP=127.0.0.1 # OPENIM_IP=127.0.0.1
if [ -z "${OPENIM_IP}" ]; then if [ -z "${OPENIM_IP}" ]; then
OPENIM_IP=$(openim::util::get_server_ip) OPENIM_IP=$(openim::util::get_server_ip)
fi fi
# config.gateway custom bridge modes # config.gateway custom bridge modes
@ -37,9 +37,9 @@ fi
# fi # fi
function def() { function def() {
local var_name="$1" local var_name="$1"
local default_value="${2:-}" local default_value="${2:-}"
eval "readonly $var_name=\"\${$var_name:-$(printf '%q' "$default_value")}\"" eval "readonly $var_name=\"\${$var_name:-$(printf '%q' "$default_value")}\""
} }
# OpenIM Docker Compose 数据存储的默认路径 # OpenIM Docker Compose 数据存储的默认路径
@ -52,7 +52,7 @@ def "OPENIM_USER" "root"
readonly PASSWORD=${PASSWORD:-'openIM123'} readonly PASSWORD=${PASSWORD:-'openIM123'}
# 设置统一的数据库名称,方便管理 # 设置统一的数据库名称,方便管理
def "DATABASE_NAME" "openIM_v3" def "DATABASE_NAME" "openim_v3"
# Linux系统 openim 用户 # Linux系统 openim 用户
def "LINUX_USERNAME" "openim" def "LINUX_USERNAME" "openim"
@ -89,8 +89,8 @@ SUBNET=$(echo $DOCKER_BRIDGE_SUBNET | cut -d '/' -f 2)
LAST_OCTET=$(echo $IP_PREFIX | cut -d '.' -f 4) LAST_OCTET=$(echo $IP_PREFIX | cut -d '.' -f 4)
generate_ip() { generate_ip() {
local NEW_IP="$(echo $IP_PREFIX | cut -d '.' -f 1-3).$((LAST_OCTET++))" local NEW_IP="$(echo $IP_PREFIX | cut -d '.' -f 1-3).$((LAST_OCTET++))"
echo $NEW_IP echo $NEW_IP
} }
LAST_OCTET=$((LAST_OCTET + 1)) LAST_OCTET=$((LAST_OCTET + 1))
DOCKER_BRIDGE_GATEWAY=$(generate_ip) DOCKER_BRIDGE_GATEWAY=$(generate_ip)

@ -40,79 +40,79 @@ DOWNLOAD_DIR="/tmp/openim-protoc"
INSTALL_DIR="/usr/local/bin" INSTALL_DIR="/usr/local/bin"
function help_message { function help_message {
echo "Usage: ./install-protobuf.sh [option]" echo "Usage: ./install-protobuf.sh [option]"
echo "Options:" echo "Options:"
echo "-i, --install Install the OpenIM Protoc tool." echo "-i, --install Install the OpenIM Protoc tool."
echo "-u, --uninstall Uninstall the OpenIM Protoc tool." echo "-u, --uninstall Uninstall the OpenIM Protoc tool."
echo "-r, --reinstall Reinstall the OpenIM Protoc tool." echo "-r, --reinstall Reinstall the OpenIM Protoc tool."
echo "-c, --check Check if the OpenIM Protoc tool is installed." echo "-c, --check Check if the OpenIM Protoc tool is installed."
echo "-h, --help Display this help message." echo "-h, --help Display this help message."
} }
function install_protobuf { function install_protobuf {
echo "Installing OpenIM Protoc tool..." echo "Installing OpenIM Protoc tool..."
# Create temporary directory and download the zip file # Create temporary directory and download the zip file
mkdir -p $DOWNLOAD_DIR mkdir -p $DOWNLOAD_DIR
wget $PROTOC_DOWNLOAD_URL -O $DOWNLOAD_DIR/linux.zip wget $PROTOC_DOWNLOAD_URL -O $DOWNLOAD_DIR/linux.zip
# Unzip the file # Unzip the file
unzip -o $DOWNLOAD_DIR/linux.zip -d $DOWNLOAD_DIR unzip -o $DOWNLOAD_DIR/linux.zip -d $DOWNLOAD_DIR
# Move binaries to the install directory and make them executable # Move binaries to the install directory and make them executable
sudo cp $DOWNLOAD_DIR/linux/protoc $INSTALL_DIR/ sudo cp $DOWNLOAD_DIR/linux/protoc $INSTALL_DIR/
sudo cp $DOWNLOAD_DIR/linux/protoc-gen-go $INSTALL_DIR/ sudo cp $DOWNLOAD_DIR/linux/protoc-gen-go $INSTALL_DIR/
sudo chmod +x $INSTALL_DIR/protoc sudo chmod +x $INSTALL_DIR/protoc
sudo chmod +x $INSTALL_DIR/protoc-gen-go sudo chmod +x $INSTALL_DIR/protoc-gen-go
# Clean up # Clean up
rm -rf $DOWNLOAD_DIR rm -rf $DOWNLOAD_DIR
echo "OpenIM Protoc tool installed successfully!" echo "OpenIM Protoc tool installed successfully!"
} }
function uninstall_protobuf { function uninstall_protobuf {
echo "Uninstalling OpenIM Protoc tool..." echo "Uninstalling OpenIM Protoc tool..."
# Removing binaries from the install directory # Removing binaries from the install directory
sudo rm -f $INSTALL_DIR/protoc sudo rm -f $INSTALL_DIR/protoc
sudo rm -f $INSTALL_DIR/protoc-gen-go sudo rm -f $INSTALL_DIR/protoc-gen-go
echo "OpenIM Protoc tool uninstalled successfully!" echo "OpenIM Protoc tool uninstalled successfully!"
} }
function reinstall_protobuf { function reinstall_protobuf {
echo "Reinstalling OpenIM Protoc tool..." echo "Reinstalling OpenIM Protoc tool..."
uninstall_protobuf uninstall_protobuf
install_protobuf install_protobuf
} }
function check_protobuf { function check_protobuf {
echo "Checking for OpenIM Protoc tool installation..." echo "Checking for OpenIM Protoc tool installation..."
which protoc > /dev/null 2>&1 which protoc > /dev/null 2>&1
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "OpenIM Protoc tool is installed." echo "OpenIM Protoc tool is installed."
else else
echo "OpenIM Protoc tool is not installed." echo "OpenIM Protoc tool is not installed."
fi fi
} }
while [ "$1" != "" ]; do while [ "$1" != "" ]; do
case $1 in case $1 in
-i | --install ) install_protobuf -i | --install ) install_protobuf
;; ;;
-u | --uninstall ) uninstall_protobuf -u | --uninstall ) uninstall_protobuf
;; ;;
-r | --reinstall ) reinstall_protobuf -r | --reinstall ) reinstall_protobuf
;; ;;
-c | --check ) check_protobuf -c | --check ) check_protobuf
;; ;;
-h | --help ) help_message -h | --help ) help_message
exit exit
;; ;;
* ) help_message * ) help_message
exit 1 exit 1
esac esac
shift shift
done done

@ -57,99 +57,99 @@ ${OPENIM_ROOT}/scripts/install/test.sh
# Detailed help function # Detailed help function
function openim::install::show_help() { function openim::install::show_help() {
echo "OpenIM Installer" echo "OpenIM Installer"
echo "Usage: $0 <command> [options]" echo "Usage: $0 <command> [options]"
echo "" echo ""
echo "Commands:" echo "Commands:"
echo " -i, --install Install all OpenIM components." echo " -i, --install Install all OpenIM components."
echo " -u, --uninstall Remove all OpenIM components." echo " -u, --uninstall Remove all OpenIM components."
echo " -s, --status Check the current status of OpenIM components." echo " -s, --status Check the current status of OpenIM components."
echo " -h, --help Show this help menu." echo " -h, --help Show this help menu."
echo "" echo ""
echo "Example: " echo "Example: "
echo " $0 -i Will install all OpenIM components." echo " $0 -i Will install all OpenIM components."
echo " $0 --install Same as above." echo " $0 --install Same as above."
} }
function openim::install::install_openim() { function openim::install::install_openim() {
openim::common::sudo "mkdir -p ${OPENIM_DATA_DIR} ${OPENIM_INSTALL_DIR} ${OPENIM_CONFIG_DIR} ${OPENIM_LOG_DIR}" openim::common::sudo "mkdir -p ${OPENIM_DATA_DIR} ${OPENIM_INSTALL_DIR} ${OPENIM_CONFIG_DIR} ${OPENIM_LOG_DIR}"
openim::log::info "check openim dependency" openim::log::info "check openim dependency"
openim::common::sudo "cp -r ${OPENIM_ROOT}/config/* ${OPENIM_CONFIG_DIR}/" openim::common::sudo "cp -r ${OPENIM_ROOT}/config/* ${OPENIM_CONFIG_DIR}/"
${OPENIM_ROOT}/scripts/genconfig.sh ${ENV_FILE} ${OPENIM_ROOT}/deployments/templates/openim.yaml > ${OPENIM_CONFIG_DIR}/config.yaml ${OPENIM_ROOT}/scripts/genconfig.sh ${ENV_FILE} ${OPENIM_ROOT}/deployments/templates/config.yaml > ${OPENIM_CONFIG_DIR}/config.yaml
${OPENIM_ROOT}/scripts/genconfig.sh ${ENV_FILE} ${OPENIM_ROOT}/deployments/templates/prometheus.yml > ${OPENIM_CONFIG_DIR}/prometheus.yml ${OPENIM_ROOT}/scripts/genconfig.sh ${ENV_FILE} ${OPENIM_ROOT}/deployments/templates/prometheus.yml > ${OPENIM_CONFIG_DIR}/prometheus.yml
openim::util::check_ports ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]} openim::util::check_ports ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]}
${OPENIM_ROOT}/scripts/install/openim-msggateway.sh openim::msggateway::install || return 1 ${OPENIM_ROOT}/scripts/install/openim-msggateway.sh openim::msggateway::install || return 1
${OPENIM_ROOT}/scripts/install/openim-msgtransfer.sh openim::msgtransfer::install || return 1 ${OPENIM_ROOT}/scripts/install/openim-msgtransfer.sh openim::msgtransfer::install || return 1
${OPENIM_ROOT}/scripts/install/openim-push.sh openim::push::install || return 1 ${OPENIM_ROOT}/scripts/install/openim-push.sh openim::push::install || return 1
${OPENIM_ROOT}/scripts/install/openim-crontask.sh openim::crontask::install || return 1 ${OPENIM_ROOT}/scripts/install/openim-crontask.sh openim::crontask::install || return 1
${OPENIM_ROOT}/scripts/install/openim-rpc.sh openim::rpc::install || return 1 ${OPENIM_ROOT}/scripts/install/openim-rpc.sh openim::rpc::install || return 1
${OPENIM_ROOT}/scripts/install/openim-api.sh openim::api::install || return 1 ${OPENIM_ROOT}/scripts/install/openim-api.sh openim::api::install || return 1
openim::common::sudo "cp -r ${OPENIM_ROOT}/deployments/templates/openim.target /etc/systemd/system/openim.target" openim::common::sudo "cp -r ${OPENIM_ROOT}/deployments/templates/openim.target /etc/systemd/system/openim.target"
openim::common::sudo "systemctl daemon-reload" openim::common::sudo "systemctl daemon-reload"
openim::common::sudo "systemctl restart openim.target" openim::common::sudo "systemctl restart openim.target"
openim::common::sudo "systemctl enable openim.target" openim::common::sudo "systemctl enable openim.target"
openim::log::success "openim install success" openim::log::success "openim install success"
} }
function openim::uninstall::uninstall_openim() { function openim::uninstall::uninstall_openim() {
openim::log::info "uninstall openim" openim::log::info "uninstall openim"
${OPENIM_ROOT}/scripts/install/openim-msggateway.sh openim::msggateway::uninstall || return 1 ${OPENIM_ROOT}/scripts/install/openim-msggateway.sh openim::msggateway::uninstall || return 1
${OPENIM_ROOT}/scripts/install/openim-msgtransfer.sh openim::msgtransfer::uninstall || return 1 ${OPENIM_ROOT}/scripts/install/openim-msgtransfer.sh openim::msgtransfer::uninstall || return 1
${OPENIM_ROOT}/scripts/install/openim-push.sh openim::push::uninstall || return 1 ${OPENIM_ROOT}/scripts/install/openim-push.sh openim::push::uninstall || return 1
${OPENIM_ROOT}/scripts/install/openim-crontask.sh openim::crontask::uninstall || return 1 ${OPENIM_ROOT}/scripts/install/openim-crontask.sh openim::crontask::uninstall || return 1
${OPENIM_ROOT}/scripts/install/openim-rpc.sh openim::rpc::uninstall || return 1 ${OPENIM_ROOT}/scripts/install/openim-rpc.sh openim::rpc::uninstall || return 1
${OPENIM_ROOT}/scripts/install/openim-api.sh openim::api::uninstall || return 1 ${OPENIM_ROOT}/scripts/install/openim-api.sh openim::api::uninstall || return 1
set +o errexit set +o errexit
openim::common::sudo "systemctl stop openim.target" openim::common::sudo "systemctl stop openim.target"
openim::common::sudo "systemctl disable openim.target" openim::common::sudo "systemctl disable openim.target"
openim::common::sudo "rm -f /etc/systemd/system/openim.target" openim::common::sudo "rm -f /etc/systemd/system/openim.target"
set -o errexit set -o errexit
openim::log::success "openim uninstall success" openim::log::success "openim uninstall success"
} }
function openim::install::status() { function openim::install::status() {
openim::log::info "check openim status" openim::log::info "check openim status"
${OPENIM_ROOT}/scripts/install/openim-msggateway.sh openim::msggateway::status || return 1 ${OPENIM_ROOT}/scripts/install/openim-msggateway.sh openim::msggateway::status || return 1
${OPENIM_ROOT}/scripts/install/openim-msgtransfer.sh openim::msgtransfer::status || return 1 ${OPENIM_ROOT}/scripts/install/openim-msgtransfer.sh openim::msgtransfer::status || return 1
${OPENIM_ROOT}/scripts/install/openim-push.sh openim::push::status || return 1 ${OPENIM_ROOT}/scripts/install/openim-push.sh openim::push::status || return 1
${OPENIM_ROOT}/scripts/install/openim-crontask.sh openim::crontask::status || return 1 ${OPENIM_ROOT}/scripts/install/openim-crontask.sh openim::crontask::status || return 1
${OPENIM_ROOT}/scripts/install/openim-rpc.sh openim::rpc::status || return 1 ${OPENIM_ROOT}/scripts/install/openim-rpc.sh openim::rpc::status || return 1
${OPENIM_ROOT}/scripts/install/openim-api.sh openim::api::status || return 1 ${OPENIM_ROOT}/scripts/install/openim-api.sh openim::api::status || return 1
openim::log::success "openim status success" openim::log::success "openim status success"
} }
# If no arguments are provided, show help # If no arguments are provided, show help
if [[ $# -eq 0 ]]; then if [[ $# -eq 0 ]]; then
openim::install::show_help openim::install::show_help
exit 0 exit 0
fi fi
# Argument parsing to call functions based on user input # Argument parsing to call functions based on user input
while (( "$#" )); do while (( "$#" )); do
case "$1" in case "$1" in
-i|--install) -i|--install)
openim::install::install_openim openim::install::install_openim
shift shift
;; ;;
-u|--uninstall) -u|--uninstall)
openim::uninstall::uninstall_openim openim::uninstall::uninstall_openim
shift shift
;; ;;
-s|--status) -s|--status)
openim::install::status openim::install::status
shift shift
;; ;;
-h|--help|*) -h|--help|*)
openim::install::show_help openim::install::show_help
exit 0 exit 0
;; ;;
esac esac
done done

@ -34,24 +34,24 @@ readonly OPENIM_API_SERVICE_TARGETS=(
readonly OPENIM_API_SERVICE_LISTARIES=("${OPENIM_API_SERVICE_TARGETS[@]##*/}") readonly OPENIM_API_SERVICE_LISTARIES=("${OPENIM_API_SERVICE_TARGETS[@]##*/}")
function openim::api::start() { function openim::api::start() {
echo "++ OPENIM_API_SERVICE_LISTARIES: ${OPENIM_API_SERVICE_LISTARIES[@]}" echo "++ OPENIM_API_SERVICE_LISTARIES: ${OPENIM_API_SERVICE_LISTARIES[@]}"
echo "++ OPENIM_API_PORT_LISTARIES: ${OPENIM_API_PORT_LISTARIES[@]}" echo "++ OPENIM_API_PORT_LISTARIES: ${OPENIM_API_PORT_LISTARIES[@]}"
echo "++ OpenIM API config path: ${OPENIM_API_CONFIG}" echo "++ OpenIM API config path: ${OPENIM_API_CONFIG}"
openim::log::info "Starting ${SERVER_NAME} ..." openim::log::info "Starting ${SERVER_NAME} ..."
printf "+------------------------+--------------+\n" printf "+------------------------+--------------+\n"
printf "| Service Name | Port |\n" printf "| Service Name | Port |\n"
printf "+------------------------+--------------+\n" printf "+------------------------+--------------+\n"
length=${#OPENIM_API_SERVICE_LISTARIES[@]} length=${#OPENIM_API_SERVICE_LISTARIES[@]}
for ((i=0; i<$length; i++)); do for ((i=0; i<$length; i++)); do
printf "| %-22s | %6s |\n" "${OPENIM_API_SERVICE_LISTARIES[$i]}" "${OPENIM_API_PORT_LISTARIES[$i]}" printf "| %-22s | %6s |\n" "${OPENIM_API_SERVICE_LISTARIES[$i]}" "${OPENIM_API_PORT_LISTARIES[$i]}"
printf "+------------------------+--------------+\n" printf "+------------------------+--------------+\n"
done done
# start all api services # start all api services
for ((i = 0; i < ${#OPENIM_API_SERVICE_LISTARIES[*]}; i++)); do for ((i = 0; i < ${#OPENIM_API_SERVICE_LISTARIES[*]}; i++)); do
openim::util::stop_services_on_ports ${OPENIM_API_PORT_LISTARIES[$i]} openim::util::stop_services_on_ports ${OPENIM_API_PORT_LISTARIES[$i]}
openim::log::info "OpenIM ${OPENIM_API_SERVICE_LISTARIES[$i]} config path: ${OPENIM_API_CONFIG}" openim::log::info "OpenIM ${OPENIM_API_SERVICE_LISTARIES[$i]} config path: ${OPENIM_API_CONFIG}"
@ -60,18 +60,18 @@ function openim::api::start() {
# TODO Only one port is supported. An error occurs on multiple ports # TODO Only one port is supported. An error occurs on multiple ports
if [ ${#OPENIM_API_SERVICE_PORTS[@]} -ne 1 ]; then if [ ${#OPENIM_API_SERVICE_PORTS[@]} -ne 1 ]; then
openim::log::error_exit "Set only one port for ${OPENIM_API_SERVICE_LISTARIES[$i]} service." openim::log::error_exit "Set only one port for ${OPENIM_API_SERVICE_LISTARIES[$i]} service."
fi fi
for ((j = 0; j < ${#OPENIM_API_SERVICE_PORTS[@]}; j++)); do for ((j = 0; j < ${#OPENIM_API_SERVICE_PORTS[@]}; j++)); do
openim::log::info "Starting ${OPENIM_API_SERVICE_LISTARIES[$i]} service, port: ${OPENIM_API_SERVICE_PORTS[j]}, binary root: ${OPENIM_OUTPUT_HOSTBIN}/${OPENIM_API_SERVICE_LISTARIES[$i]}" openim::log::info "Starting ${OPENIM_API_SERVICE_LISTARIES[$i]} service, port: ${OPENIM_API_SERVICE_PORTS[j]}, binary root: ${OPENIM_OUTPUT_HOSTBIN}/${OPENIM_API_SERVICE_LISTARIES[$i]}"
openim::api::start_service "${OPENIM_API_SERVICE_LISTARIES[$i]}" "${OPENIM_API_PORT_LISTARIES[j]}" openim::api::start_service "${OPENIM_API_SERVICE_LISTARIES[$i]}" "${OPENIM_API_PORT_LISTARIES[j]}"
sleep 2 sleep 2
done
done done
done
OPENIM_API_PORT_STRINGARIES=( $(openim::util::list-to-string ${OPENIM_API_PORT_LISTARIES[@]}) ) OPENIM_API_PORT_STRINGARIES=( $(openim::util::list-to-string ${OPENIM_API_PORT_LISTARIES[@]}) )
openim::util::check_ports ${OPENIM_API_PORT_STRINGARIES[@]} openim::util::check_ports ${OPENIM_API_PORT_STRINGARIES[@]}
} }
function openim::api::start_service() { function openim::api::start_service() {
@ -100,61 +100,61 @@ EOF
# install openim-api # install openim-api
function openim::api::install() { function openim::api::install() {
openim::log::info "Installing ${SERVER_NAME} ..." openim::log::info "Installing ${SERVER_NAME} ..."
pushd "${OPENIM_ROOT}" pushd "${OPENIM_ROOT}"
# 1. Build openim-api # 1. Build openim-api
make build BINS=${SERVER_NAME} make build BINS=${SERVER_NAME}
openim::common::sudo "cp -r ${OPENIM_OUTPUT_HOSTBIN}/${SERVER_NAME} ${OPENIM_INSTALL_DIR}/${SERVER_NAME}" openim::common::sudo "cp -r ${OPENIM_OUTPUT_HOSTBIN}/${SERVER_NAME} ${OPENIM_INSTALL_DIR}/${SERVER_NAME}"
openim::log::status "${SERVER_NAME} binary: ${OPENIM_INSTALL_DIR}/${SERVER_NAME}/${SERVER_NAME}" openim::log::status "${SERVER_NAME} binary: ${OPENIM_INSTALL_DIR}/${SERVER_NAME}/${SERVER_NAME}"
# 2. Generate and install the openim-api configuration file (config) # 2. Generate and install the openim-api configuration file (config)
openim::log::status "${SERVER_NAME} config file: ${OPENIM_CONFIG_DIR}/config.yaml" openim::log::status "${SERVER_NAME} config file: ${OPENIM_CONFIG_DIR}/config.yaml"
# 3. Create and install the ${SERVER_NAME} systemd unit file # 3. Create and install the ${SERVER_NAME} systemd unit file
echo ${LINUX_PASSWORD} | sudo -S bash -c \ echo ${LINUX_PASSWORD} | sudo -S bash -c \
"SERVER_NAME=${SERVER_NAME} ./scripts/genconfig.sh ${ENV_FILE} deployments/templates/openim.service > ${SYSTEM_FILE_PATH}" "SERVER_NAME=${SERVER_NAME} ./scripts/genconfig.sh ${ENV_FILE} deployments/templates/openim.service > ${SYSTEM_FILE_PATH}"
openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}" openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}"
# 4. Start the openim-api service # 4. Start the openim-api service
openim::common::sudo "systemctl daemon-reload" openim::common::sudo "systemctl daemon-reload"
openim::common::sudo "systemctl restart ${SERVER_NAME}" openim::common::sudo "systemctl restart ${SERVER_NAME}"
openim::common::sudo "systemctl enable ${SERVER_NAME}" openim::common::sudo "systemctl enable ${SERVER_NAME}"
openim::api::status || return 1 openim::api::status || return 1
openim::api::info openim::api::info
openim::log::info "install ${SERVER_NAME} successfully" openim::log::info "install ${SERVER_NAME} successfully"
popd popd
} }
# Unload # Unload
function openim::api::uninstall() { function openim::api::uninstall() {
openim::log::info "Uninstalling ${SERVER_NAME} ..." openim::log::info "Uninstalling ${SERVER_NAME} ..."
set +o errexit set +o errexit
openim::common::sudo "systemctl stop ${SERVER_NAME}" openim::common::sudo "systemctl stop ${SERVER_NAME}"
openim::common::sudo "systemctl disable ${SERVER_NAME}" openim::common::sudo "systemctl disable ${SERVER_NAME}"
openim::common::sudo "rm -f ${OPENIM_INSTALL_DIR}/${SERVER_NAME}" openim::common::sudo "rm -f ${OPENIM_INSTALL_DIR}/${SERVER_NAME}"
openim::common::sudo "rm -f ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" openim::common::sudo "rm -f ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml"
openim::common::sudo "rm -f /etc/systemd/system/${SERVER_NAME}.service" openim::common::sudo "rm -f /etc/systemd/system/${SERVER_NAME}.service"
set -o errexit set -o errexit
openim::log::info "uninstall ${SERVER_NAME} successfully" openim::log::info "uninstall ${SERVER_NAME} successfully"
} }
# Status Check # Status Check
function openim::api::status() { function openim::api::status() {
openim::log::info "Checking ${SERVER_NAME} status ..." openim::log::info "Checking ${SERVER_NAME} status ..."
# Check the running status of the ${SERVER_NAME}. If active (running) is displayed, the ${SERVER_NAME} is started successfully. # Check the running status of the ${SERVER_NAME}. If active (running) is displayed, the ${SERVER_NAME} is started successfully.
systemctl status ${SERVER_NAME}|grep -q 'active' || { systemctl status ${SERVER_NAME}|grep -q 'active' || {
openim::log::error "${SERVER_NAME} failed to start, maybe not installed properly" openim::log::error "${SERVER_NAME} failed to start, maybe not installed properly"
return 1 return 1
} }
openim::util::check_ports ${OPENIM_API_PORT_LISTARIES[@]} openim::util::check_ports ${OPENIM_API_PORT_LISTARIES[@]}
} }
if [[ "$*" =~ openim::api:: ]];then if [[ "$*" =~ openim::api:: ]];then
eval $* eval $*
fi fi

@ -44,14 +44,14 @@ OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P)
SERVER_NAME="openim-crontask" SERVER_NAME="openim-crontask"
function openim::crontask::start() { function openim::crontask::start() {
openim::log::info "Start OpenIM Cron, binary root: ${SERVER_NAME}" openim::log::info "Start OpenIM Cron, binary root: ${SERVER_NAME}"
openim::log::status "Start OpenIM Cron, path: ${OPENIM_CRONTASK_BINARY}" openim::log::status "Start OpenIM Cron, path: ${OPENIM_CRONTASK_BINARY}"
openim::util::stop_services_with_name ${OPENIM_CRONTASK_BINARY} openim::util::stop_services_with_name ${OPENIM_CRONTASK_BINARY}
openim::log::status "start cron_task process, path: ${OPENIM_CRONTASK_BINARY}" openim::log::status "start cron_task process, path: ${OPENIM_CRONTASK_BINARY}"
nohup ${OPENIM_CRONTASK_BINARY} -c ${OPENIM_PUSH_CONFIG} >> ${LOG_FILE} 2>&1 & nohup ${OPENIM_CRONTASK_BINARY} -c ${OPENIM_PUSH_CONFIG} >> ${LOG_FILE} 2>&1 &
openim::util::check_process_names ${SERVER_NAME} openim::util::check_process_names ${SERVER_NAME}
} }
###################################### Linux Systemd ###################################### ###################################### Linux Systemd ######################################
@ -79,7 +79,7 @@ function openim::crontask::install() {
# 3. Create and install the ${SERVER_NAME} systemd unit file # 3. Create and install the ${SERVER_NAME} systemd unit file
echo ${LINUX_PASSWORD} | sudo -S bash -c \ echo ${LINUX_PASSWORD} | sudo -S bash -c \
"SERVER_NAME=${SERVER_NAME} ./scripts/genconfig.sh ${ENV_FILE} deployments/templates/openim.service > ${SYSTEM_FILE_PATH}" "SERVER_NAME=${SERVER_NAME} ./scripts/genconfig.sh ${ENV_FILE} deployments/templates/openim.service > ${SYSTEM_FILE_PATH}"
openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}" openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}"
# 4. Start the openim-crontask service # 4. Start the openim-crontask service

@ -54,43 +54,43 @@ EOF
# Install the man pages for openim # Install the man pages for openim
function openim::man::install() { function openim::man::install() {
# Navigate to the openim root directory # Navigate to the openim root directory
pushd "${OPENIM_ROOT}" > /dev/null pushd "${OPENIM_ROOT}" > /dev/null
# Generate man pages for each component # 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/" openim::common::sudo "cp docs/man/man1/* /usr/share/man/man1/"
# Verify installation status # Verify installation status
if openim::man::status; then if openim::man::status; then
openim::log::info "Installed openim-server man page successfully" openim::log::info "Installed openim-server man page successfully"
openim::man::info openim::man::info
fi fi
# Return to the original directory # Return to the original directory
popd > /dev/null popd > /dev/null
} }
# Uninstall the man pages for openim # Uninstall the man pages for openim
function openim::man::uninstall() { function openim::man::uninstall() {
# Turn off exit-on-error temporarily to handle non-existing files gracefully # Turn off exit-on-error temporarily to handle non-existing files gracefully
set +o errexit set +o errexit
openim::common::sudo "rm -f /usr/share/man/man1/openim-*" openim::common::sudo "rm -f /usr/share/man/man1/openim-*"
set -o errexit set -o errexit
openim::log::info "Uninstalled openim man pages successfully" openim::log::info "Uninstalled openim man pages successfully"
} }
# Check the installation status of the man pages # Check the installation status of the man pages
function openim::man::status() { function openim::man::status() {
if ! ls /usr/share/man/man1/openim-* &> /dev/null; then if ! ls /usr/share/man/man1/openim-* &> /dev/null; then
openim::log::error "OpenIM man files not found. Perhaps they were not installed correctly." openim::log::error "OpenIM man files not found. Perhaps they were not installed correctly."
return 1 return 1
fi fi
return 0 return 0
} }
# Execute the appropriate function based on the given arguments # Execute the appropriate function based on the given arguments
if [[ "$*" =~ openim::man:: ]]; then if [[ "$*" =~ openim::man:: ]]; then
eval "$*" eval "$*"
fi fi

@ -26,13 +26,13 @@ openim::util::set_max_fd 200000
SERVER_NAME="openim-msggateway" SERVER_NAME="openim-msggateway"
function openim::msggateway::start() { function openim::msggateway::start() {
openim::log::info "Start OpenIM Msggateway, binary root: ${SERVER_NAME}" openim::log::info "Start OpenIM Msggateway, binary root: ${SERVER_NAME}"
openim::log::status "Start OpenIM Msggateway, path: ${OPENIM_MSGGATEWAY_BINARY}" openim::log::status "Start OpenIM Msggateway, path: ${OPENIM_MSGGATEWAY_BINARY}"
openim::util::stop_services_with_name ${OPENIM_MSGGATEWAY_BINARY} openim::util::stop_services_with_name ${OPENIM_MSGGATEWAY_BINARY}
# OpenIM message gateway service port # OpenIM message gateway service port
OPENIM_MESSAGE_GATEWAY_PORTS=$(openim::util::list-to-string ${OPENIM_MESSAGE_GATEWAY_PORT} ) OPENIM_MESSAGE_GATEWAY_PORTS=$(openim::util::list-to-string ${OPENIM_MESSAGE_GATEWAY_PORT} )
read -a OPENIM_MSGGATEWAY_PORTS_ARRAY <<< ${OPENIM_MESSAGE_GATEWAY_PORTS} read -a OPENIM_MSGGATEWAY_PORTS_ARRAY <<< ${OPENIM_MESSAGE_GATEWAY_PORTS}
openim::util::stop_services_on_ports ${OPENIM_MSGGATEWAY_PORTS_ARRAY[*]} openim::util::stop_services_on_ports ${OPENIM_MSGGATEWAY_PORTS_ARRAY[*]}
# OpenIM WS port # OpenIM WS port

@ -28,59 +28,59 @@ openim::util::set_max_fd 200000
SERVER_NAME="openim-msgtransfer" SERVER_NAME="openim-msgtransfer"
function openim::msgtransfer::start() { function openim::msgtransfer::start() {
openim::log::info "Start OpenIM Msggateway, binary root: ${SERVER_NAME}" openim::log::info "Start OpenIM Msggateway, binary root: ${SERVER_NAME}"
openim::log::status "Start OpenIM Msggateway, path: ${OPENIM_MSGTRANSFER_BINARY}" openim::log::status "Start OpenIM Msggateway, path: ${OPENIM_MSGTRANSFER_BINARY}"
openim::util::stop_services_with_name ${OPENIM_MSGTRANSFER_BINARY} openim::util::stop_services_with_name ${OPENIM_MSGTRANSFER_BINARY}
# Message Transfer Prometheus port list # Message Transfer Prometheus port list
MSG_TRANSFER_PROM_PORTS=(openim::util::list-to-string ${MSG_TRANSFER_PROM_PORT} ) MSG_TRANSFER_PROM_PORTS=(openim::util::list-to-string ${MSG_TRANSFER_PROM_PORT} )
openim::log::status "OpenIM Prometheus ports: ${MSG_TRANSFER_PROM_PORTS[*]}" openim::log::status "OpenIM Prometheus ports: ${MSG_TRANSFER_PROM_PORTS[*]}"
openim::log::status "OpenIM Msggateway config path: ${OPENIM_MSGTRANSFER_CONFIG}" openim::log::status "OpenIM Msggateway config path: ${OPENIM_MSGTRANSFER_CONFIG}"
openim::log::info "openim maggateway num: ${OPENIM_MSGGATEWAY_NUM}" openim::log::info "openim maggateway num: ${OPENIM_MSGGATEWAY_NUM}"
if [ "${OPENIM_MSGGATEWAY_NUM}" -lt 1 ]; then if [ "${OPENIM_MSGGATEWAY_NUM}" -lt 1 ]; then
opeim::log::error_exit "OPENIM_MSGGATEWAY_NUM must be greater than 0" opeim::log::error_exit "OPENIM_MSGGATEWAY_NUM must be greater than 0"
fi fi
if [ ${OPENIM_MSGGATEWAY_NUM} -ne $((${#MSG_TRANSFER_PROM_PORTS[@]} - 1)) ]; then if [ ${OPENIM_MSGGATEWAY_NUM} -ne $((${#MSG_TRANSFER_PROM_PORTS[@]} - 1)) ]; then
openim::log::error_exit "OPENIM_MSGGATEWAY_NUM must be equal to the number of MSG_TRANSFER_PROM_PORTS" openim::log::error_exit "OPENIM_MSGGATEWAY_NUM must be equal to the number of MSG_TRANSFER_PROM_PORTS"
fi fi
for (( i=0; i<$OPENIM_MSGGATEWAY_NUM; i++ )) do for (( i=0; i<$OPENIM_MSGGATEWAY_NUM; i++ )) do
openim::log::info "prometheus port: ${MSG_TRANSFER_PROM_PORTS[$i]}" openim::log::info "prometheus port: ${MSG_TRANSFER_PROM_PORTS[$i]}"
PROMETHEUS_PORT_OPTION="" PROMETHEUS_PORT_OPTION=""
if [[ -n "${OPENIM_PROMETHEUS_PORTS[$i]}" ]]; then if [[ -n "${OPENIM_PROMETHEUS_PORTS[$i]}" ]]; then
PROMETHEUS_PORT_OPTION="--prometheus_port ${OPENIM_PROMETHEUS_PORTS[$i]}" PROMETHEUS_PORT_OPTION="--prometheus_port ${OPENIM_PROMETHEUS_PORTS[$i]}"
fi fi
nohup ${OPENIM_MSGTRANSFER_BINARY} ${PROMETHEUS_PORT_OPTION} -c ${OPENIM_MSGTRANSFER_CONFIG} -n ${i}>> ${LOG_FILE} 2>&1 & nohup ${OPENIM_MSGTRANSFER_BINARY} ${PROMETHEUS_PORT_OPTION} -c ${OPENIM_MSGTRANSFER_CONFIG} -n ${i}>> ${LOG_FILE} 2>&1 &
done done
openim::util::check_process_names "${OPENIM_OUTPUT_HOSTBIN}/${SERVER_NAME}" openim::util::check_process_names "${OPENIM_OUTPUT_HOSTBIN}/${SERVER_NAME}"
} }
function openim::msgtransfer::check() { function openim::msgtransfer::check() {
PIDS=$(pgrep -f "${OPENIM_OUTPUT_HOSTBIN}/openim-msgtransfer") PIDS=$(pgrep -f "${OPENIM_OUTPUT_HOSTBIN}/openim-msgtransfer")
NUM_PROCESSES=$(echo "$PIDS" | wc -l) NUM_PROCESSES=$(echo "$PIDS" | wc -l)
if [ "$NUM_PROCESSES" -eq "$OPENIM_MSGGATEWAY_NUM" ]; then if [ "$NUM_PROCESSES" -eq "$OPENIM_MSGGATEWAY_NUM" ]; then
openim::log::info "Found $OPENIM_MSGGATEWAY_NUM processes named $OPENIM_OUTPUT_HOSTBIN" openim::log::info "Found $OPENIM_MSGGATEWAY_NUM processes named $OPENIM_OUTPUT_HOSTBIN"
for PID in $PIDS; do for PID in $PIDS; do
if [[ "$OSTYPE" == "linux-gnu"* ]]; then if [[ "$OSTYPE" == "linux-gnu"* ]]; then
ps -p $PID -o pid,cmd ps -p $PID -o pid,cmd
elif [[ "$OSTYPE" == "darwin"* ]]; then elif [[ "$OSTYPE" == "darwin"* ]]; then
ps -p $PID -o pid,comm ps -p $PID -o pid,comm
else else
openim::log::error "Unsupported OS type: $OSTYPE" openim::log::error "Unsupported OS type: $OSTYPE"
fi fi
done done
else else
openim::log::error_exit "Expected $OPENIM_MSGGATEWAY_NUM openim msgtransfer processes, but found $NUM_PROCESSES msgtransfer processes." openim::log::error_exit "Expected $OPENIM_MSGGATEWAY_NUM openim msgtransfer processes, but found $NUM_PROCESSES msgtransfer processes."
fi fi
} }
###################################### Linux Systemd ###################################### ###################################### Linux Systemd ######################################
@ -110,7 +110,7 @@ function openim::msgtransfer::install() {
# 3. Create and install the ${SERVER_NAME} systemd unit file # 3. Create and install the ${SERVER_NAME} systemd unit file
echo ${LINUX_PASSWORD} | sudo -S bash -c \ echo ${LINUX_PASSWORD} | sudo -S bash -c \
"SERVER_NAME=${SERVER_NAME} ./scripts/genconfig.sh ${ENV_FILE} deployments/templates/openim.service > ${SYSTEM_FILE_PATH}" "SERVER_NAME=${SERVER_NAME} ./scripts/genconfig.sh ${ENV_FILE} deployments/templates/openim.service > ${SYSTEM_FILE_PATH}"
openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}" openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}"
# 4. Start the openim-msgtransfer service # 4. Start the openim-msgtransfer service

@ -50,30 +50,30 @@ OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P)
SERVER_NAME="openim-push" SERVER_NAME="openim-push"
function openim::push::start() { function openim::push::start() {
openim::log::status "Start OpenIM Push, binary root: ${SERVER_NAME}" openim::log::status "Start OpenIM Push, binary root: ${SERVER_NAME}"
openim::log::info "Start OpenIM Push, path: ${OPENIM_PUSH_BINARY}" openim::log::info "Start OpenIM Push, path: ${OPENIM_PUSH_BINARY}"
openim::log::status "prepare start push process, path: ${OPENIM_PUSH_BINARY}" openim::log::status "prepare start push process, path: ${OPENIM_PUSH_BINARY}"
openim::log::status "prepare start push process, port: ${OPENIM_PUSH_PORT}, prometheus port: ${PUSH_PROM_PORT}" openim::log::status "prepare start push process, port: ${OPENIM_PUSH_PORT}, prometheus port: ${PUSH_PROM_PORT}"
OPENIM_PUSH_PORTS_ARRAY=$(openim::util::list-to-string ${OPENIM_PUSH_PORT} ) OPENIM_PUSH_PORTS_ARRAY=$(openim::util::list-to-string ${OPENIM_PUSH_PORT} )
PUSH_PROM_PORTS_ARRAY=$(openim::util::list-to-string ${PUSH_PROM_PORT} ) PUSH_PROM_PORTS_ARRAY=$(openim::util::list-to-string ${PUSH_PROM_PORT} )
openim::util::stop_services_with_name ${SERVER_NAME} openim::util::stop_services_with_name ${SERVER_NAME}
openim::log::status "push port list: ${OPENIM_PUSH_PORTS_ARRAY[@]}" openim::log::status "push port list: ${OPENIM_PUSH_PORTS_ARRAY[@]}"
openim::log::status "prometheus port list: ${PUSH_PROM_PORTS_ARRAY[@]}" openim::log::status "prometheus port list: ${PUSH_PROM_PORTS_ARRAY[@]}"
if [ ${#OPENIM_PUSH_PORTS_ARRAY[@]} -ne ${#PUSH_PROM_PORTS_ARRAY[@]} ]; then if [ ${#OPENIM_PUSH_PORTS_ARRAY[@]} -ne ${#PUSH_PROM_PORTS_ARRAY[@]} ]; then
openim::log::error_exit "The length of the two port lists is different!" openim::log::error_exit "The length of the two port lists is different!"
fi fi
for (( i=0; i<${#OPENIM_PUSH_PORTS_ARRAY[@]}; i++ )); do for (( i=0; i<${#OPENIM_PUSH_PORTS_ARRAY[@]}; i++ )); do
openim::log::info "start push process, port: ${OPENIM_PUSH_PORTS_ARRAY[$i]}, prometheus port: ${PUSH_PROM_PORTS_ARRAY[$i]}" openim::log::info "start push process, port: ${OPENIM_PUSH_PORTS_ARRAY[$i]}, prometheus port: ${PUSH_PROM_PORTS_ARRAY[$i]}"
nohup ${OPENIM_PUSH_BINARY} --port ${OPENIM_PUSH_PORTS_ARRAY[$i]} -c ${OPENIM_PUSH_CONFIG} --prometheus_port ${PUSH_PROM_PORTS_ARRAY[$i]} >> ${LOG_FILE} 2>&1 & nohup ${OPENIM_PUSH_BINARY} --port ${OPENIM_PUSH_PORTS_ARRAY[$i]} -c ${OPENIM_PUSH_CONFIG} --prometheus_port ${PUSH_PROM_PORTS_ARRAY[$i]} >> ${LOG_FILE} 2>&1 &
done done
openim::util::check_process_names ${SERVER_NAME} openim::util::check_process_names ${SERVER_NAME}
} }
###################################### Linux Systemd ###################################### ###################################### Linux Systemd ######################################
@ -100,7 +100,7 @@ function openim::push::install() {
# 3. Create and install the ${SERVER_NAME} systemd unit file # 3. Create and install the ${SERVER_NAME} systemd unit file
echo ${LINUX_PASSWORD} | sudo -S bash -c \ echo ${LINUX_PASSWORD} | sudo -S bash -c \
"SERVER_NAME=${SERVER_NAME} ./scripts/genconfig.sh ${ENV_FILE} deployments/templates/openim.service > ${SYSTEM_FILE_PATH}" "SERVER_NAME=${SERVER_NAME} ./scripts/genconfig.sh ${ENV_FILE} deployments/templates/openim.service > ${SYSTEM_FILE_PATH}"
openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}" openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}"
# 4. Start the openim-push service # 4. Start the openim-push service

@ -139,7 +139,7 @@ function openim::rpc::start() {
done done
done done
sleep 1 sleep 5
openim::util::check_ports ${OPENIM_RPC_PORT_TARGETS[@]} openim::util::check_ports ${OPENIM_RPC_PORT_TARGETS[@]}
# openim::util::check_ports ${OPENIM_RPC_PROM_PORT_TARGETS[@]} # openim::util::check_ports ${OPENIM_RPC_PROM_PORT_TARGETS[@]}

@ -104,12 +104,7 @@ function openim::tools::start_service() {
cmd="${cmd} --prometheus_port ${prometheus_port}" cmd="${cmd} --prometheus_port ${prometheus_port}"
fi fi
openim::log::status "Starting ${binary_name}..." openim::log::status "Starting ${binary_name}..."
# Later, after discarding Docker, the Docker keyword is unreliable, and Kubepods is used ${cmd} | tee -a "${LOG_FILE}"
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() { function openim::tools::start() {

File diff suppressed because it is too large Load Diff

@ -35,7 +35,7 @@ openim::chat::validate() {
local port_check_command local port_check_command
if command -v ss &> /dev/null && ss -Version | grep 'iproute2' &> /dev/null; then if command -v ss &> /dev/null && ss -Version | grep 'iproute2' &> /dev/null; then
port_check_command="ss" port_check_command="ss"
elif command -v netstat &>/dev/null; then elif command -v netstat &>/dev/null; then
port_check_command="netstat" port_check_command="netstat"
else else
openim::log::usage "unable to identify if chat is bound to port ${CHAT_PORT}. unable to find ss or netstat utilities." openim::log::usage "unable to identify if chat is bound to port ${CHAT_PORT}. unable to find ss or netstat utilities."
@ -50,20 +50,20 @@ openim::chat::validate() {
# need set the env of "CHAT_UNSUPPORTED_ARCH" on unstable arch. # need set the env of "CHAT_UNSUPPORTED_ARCH" on unstable arch.
arch=$(uname -m) arch=$(uname -m)
if [[ $arch =~ arm* ]]; then if [[ $arch =~ arm* ]]; then
export CHAT_UNSUPPORTED_ARCH=arm export CHAT_UNSUPPORTED_ARCH=arm
fi fi
# validate installed version is at least equal to minimum # validate installed version is at least equal to minimum
version=$(chat --version | grep Version | head -n 1 | cut -d " " -f 3) version=$(chat --version | grep Version | head -n 1 | cut -d " " -f 3)
if [[ $(openim::chat::version "${CHAT_VERSION}") -gt $(openim::chat::version "${version}") ]]; then if [[ $(openim::chat::version "${CHAT_VERSION}") -gt $(openim::chat::version "${version}") ]]; then
export PATH="${OPENIM_ROOT}"/third_party/chat:${PATH} export PATH="${OPENIM_ROOT}"/third_party/chat:${PATH}
hash chat hash chat
echo "${PATH}" echo "${PATH}"
version=$(chat --version | grep Version | head -n 1 | cut -d " " -f 3) version=$(chat --version | grep Version | head -n 1 | cut -d " " -f 3)
if [[ $(openim::chat::version "${CHAT_VERSION}") -gt $(openim::chat::version "${version}") ]]; then if [[ $(openim::chat::version "${CHAT_VERSION}") -gt $(openim::chat::version "${version}") ]]; then
openim::log::usage "chat version ${CHAT_VERSION} or greater required." openim::log::usage "chat version ${CHAT_VERSION} or greater required."
openim::log::info "You can use 'scripts/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 exit 1
fi fi
fi fi
} }
@ -108,7 +108,7 @@ openim::chat::start_scraping() {
} }
openim::chat::scrape() { openim::chat::scrape() {
curl -s -S "${OPENIM_INTEGRATION_CHAT_URL}/metrics" > "${CHAT_SCRAPE_DIR}/next" && mv "${CHAT_SCRAPE_DIR}/next" "${CHAT_SCRAPE_DIR}/$(date +%s).scrape" curl -s -S "${OPENIM_INTEGRATION_CHAT_URL}/metrics" > "${CHAT_SCRAPE_DIR}/next" && mv "${CHAT_SCRAPE_DIR}/next" "${CHAT_SCRAPE_DIR}/$(date +%s).scrape"
} }
openim::chat::stop() { openim::chat::stop() {
@ -162,7 +162,7 @@ openim::chat::install() {
unzip -o "${download_file}" unzip -o "${download_file}"
ln -fns "chat-v${CHAT_VERSION}-${os}-${arch}" chat ln -fns "chat-v${CHAT_VERSION}-${os}-${arch}" chat
rm "${download_file}" rm "${download_file}"
elif [[ ${os} == "linux" ]]; then elif [[ ${os} == "linux" ]]; then
url="https://github.com/coreos/chat/releases/download/v${CHAT_VERSION}/chat-v${CHAT_VERSION}-${os}-${arch}.tar.gz" url="https://github.com/coreos/chat/releases/download/v${CHAT_VERSION}/chat-v${CHAT_VERSION}-${os}-${arch}.tar.gz"
download_file="chat-v${CHAT_VERSION}-${os}-${arch}.tar.gz" download_file="chat-v${CHAT_VERSION}-${os}-${arch}.tar.gz"
openim::util::download_file "${url}" "${download_file}" openim::util::download_file "${url}" "${download_file}"

@ -21,14 +21,14 @@
# shellcheck disable=SC2034 # shellcheck disable=SC2034
if [ -z "${COLOR_OPEN+x}" ]; then if [ -z "${COLOR_OPEN+x}" ]; then
COLOR_OPEN=1 COLOR_OPEN=1
fi fi
# Function for colored echo # Function for colored echo
openim::color::echo() { openim::color::echo() {
COLOR=$1 COLOR=$1
[ $COLOR_OPEN -eq 1 ] && echo -e "${COLOR} $(date '+%Y-%m-%d %H:%M:%S') $@ ${COLOR_SUFFIX}" [ $COLOR_OPEN -eq 1 ] && echo -e "${COLOR} $(date '+%Y-%m-%d %H:%M:%S') $@ ${COLOR_SUFFIX}"
shift shift
} }
# Define color variables # Define color variables
@ -86,54 +86,54 @@ openim::color::print_color() {
# test functions # test functions
openim::color::test() { openim::color::test() {
echo "Starting the color tests..." echo "Starting the color tests..."
echo "Testing normal echo without color" echo "Testing normal echo without color"
openim::color::echo $COLOR_NORMAL "This is a normal text" openim::color::echo $COLOR_NORMAL "This is a normal text"
echo "Testing bold echo" echo "Testing bold echo"
openim::color::echo $COLOR_BOLD "This is bold text" openim::color::echo $COLOR_BOLD "This is bold text"
echo "Testing dim echo" echo "Testing dim echo"
openim::color::echo $COLOR_DIM "This is dim text" openim::color::echo $COLOR_DIM "This is dim text"
echo "Testing underlined echo" echo "Testing underlined echo"
openim::color::echo $COLOR_UNDER "This is underlined text" openim::color::echo $COLOR_UNDER "This is underlined text"
echo "Testing italic echo" echo "Testing italic echo"
openim::color::echo $COLOR_ITALIC "This is italic text" openim::color::echo $COLOR_ITALIC "This is italic text"
echo "Testing red color" echo "Testing red color"
openim::color::echo $COLOR_RED "This is red text" openim::color::echo $COLOR_RED "This is red text"
echo "Testing green color" echo "Testing green color"
openim::color::echo $COLOR_GREEN "This is green text" openim::color::echo $COLOR_GREEN "This is green text"
echo "Testing yellow color" echo "Testing yellow color"
openim::color::echo $COLOR_YELLOW "This is yellow text" openim::color::echo $COLOR_YELLOW "This is yellow text"
echo "Testing blue color" echo "Testing blue color"
openim::color::echo $COLOR_BLUE "This is blue text" openim::color::echo $COLOR_BLUE "This is blue text"
echo "Testing magenta color" echo "Testing magenta color"
openim::color::echo $COLOR_MAGENTA "This is magenta text" openim::color::echo $COLOR_MAGENTA "This is magenta text"
echo "Testing cyan color" echo "Testing cyan color"
openim::color::echo $COLOR_CYAN "This is cyan text" openim::color::echo $COLOR_CYAN "This is cyan text"
echo "Testing black background" echo "Testing black background"
openim::color::echo $COLOR_BBLACK "This is text with black background" openim::color::echo $COLOR_BBLACK "This is text with black background"
echo "Testing red background" echo "Testing red background"
openim::color::echo $COLOR_BRED "This is text with red background" openim::color::echo $COLOR_BRED "This is text with red background"
echo "Testing green background" echo "Testing green background"
openim::color::echo $COLOR_BGREEN "This is text with green background" openim::color::echo $COLOR_BGREEN "This is text with green background"
echo "Testing blue background" echo "Testing blue background"
openim::color::echo $COLOR_BBLUE "This is text with blue background" openim::color::echo $COLOR_BBLUE "This is text with blue background"
echo "All tests completed!" echo "All tests completed!"
} }
# openim::color::test # openim::color::test

@ -21,24 +21,24 @@ ENABLE_LOGGING="${ENABLE_LOGGING:-true}"
# If OPENIM_OUTPUT is not set, set it to the default value # If OPENIM_OUTPUT is not set, set it to the default value
if [ -z "${OPENIM_OUTPUT+x}" ]; then if [ -z "${OPENIM_OUTPUT+x}" ]; then
OPENIM_OUTPUT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../_output" && pwd -P)" OPENIM_OUTPUT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../_output" && pwd -P)"
fi fi
# Set the log file path # Set the log file path
LOG_FILE="${OPENIM_OUTPUT}/logs/openim_$(date '+%Y%m%d').log" LOG_FILE="${OPENIM_OUTPUT}/logs/openim_$(date '+%Y%m%d').log"
if [[ ! -d "${OPENIM_OUTPUT}/logs" ]]; then if [[ ! -d "${OPENIM_OUTPUT}/logs" ]]; then
mkdir -p "${OPENIM_OUTPUT}/logs" mkdir -p "${OPENIM_OUTPUT}/logs"
touch "$LOG_FILE" touch "$LOG_FILE"
fi fi
# Define the logging function # Define the logging function
function echo_log() { function echo_log() {
if $ENABLE_LOGGING; then if $ENABLE_LOGGING; then
echo -e "$@" | tee -a "${LOG_FILE}" echo -e "$@" | tee -a "${LOG_FILE}"
else else
echo -e "$@" echo -e "$@"
fi fi
} }
# MAX_LOG_SIZE=10485760 # 10MB # MAX_LOG_SIZE=10485760 # 10MB
@ -203,20 +203,20 @@ openim::log::status() {
openim::log::success() { openim::log::success() {
local V="${V:-0}" local V="${V:-0}"
if [[ ${OPENIM_VERBOSE} < ${V} ]]; then if [[ ${OPENIM_VERBOSE} < ${V} ]]; then
return return
fi fi
timestamp=$(date +"%m%d %H:%M:%S") timestamp=$(date +"%m%d %H:%M:%S")
echo_log -e "${COLOR_GREEN}[success ${timestamp}] ${COLOR_SUFFIX}==> " "$@" echo_log -e "${COLOR_GREEN}[success ${timestamp}] ${COLOR_SUFFIX}==> " "$@"
} }
function openim::log::test_log() { function openim::log::test_log() {
echo_log "test log" echo_log "test log"
openim::log::info "openim::log::info" openim::log::info "openim::log::info"
openim::log::progress "openim::log::progress" openim::log::progress "openim::log::progress"
openim::log::status "openim::log::status" openim::log::status "openim::log::status"
openim::log::success "openim::log::success" openim::log::success "openim::log::success"
openim::log::error "openim::log::error" openim::log::error "openim::log::error"
openim::log::error_exit "openim::log::error_exit" openim::log::error_exit "openim::log::error_exit"
} }
# openim::log::test_log # openim::log::test_log

@ -46,11 +46,11 @@ OPENIM_BUILD_CONFORMANCE=${OPENIM_BUILD_CONFORMANCE:-y}
OPENIM_BUILD_PULL_LATEST_IMAGES=${OPENIM_BUILD_PULL_LATEST_IMAGES:-y} OPENIM_BUILD_PULL_LATEST_IMAGES=${OPENIM_BUILD_PULL_LATEST_IMAGES:-y}
if [ -z "${OPENIM_ROOT}" ]; then if [ -z "${OPENIM_ROOT}" ]; then
OPENIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)" OPENIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"
fi fi
if [ -z "${TOOLS_DIR}" ]; then if [ -z "${TOOLS_DIR}" ]; then
TOOLS_DIR="${OPENIM_ROOT}/_output/tools" TOOLS_DIR="${OPENIM_ROOT}/_output/tools"
fi fi
# Validate a ci version # Validate a ci version
@ -143,24 +143,24 @@ function openim::release::package_src_tarball() {
git archive -o "${src_tarball}" HEAD git archive -o "${src_tarball}" HEAD
else else
find "${OPENIM_ROOT}" -mindepth 1 -maxdepth 1 \ find "${OPENIM_ROOT}" -mindepth 1 -maxdepth 1 \
! \( \ ! \( \
\( -path "${OPENIM_ROOT}"/_\* -o \ \( -path "${OPENIM_ROOT}"/_\* -o \
-path "${OPENIM_ROOT}"/.git\* -o \ -path "${OPENIM_ROOT}"/.git\* -o \
-path "${OPENIM_ROOT}"/.github\* -o \ -path "${OPENIM_ROOT}"/.github\* -o \
-path "${OPENIM_ROOT}"/components\* -o \ -path "${OPENIM_ROOT}"/components\* -o \
-path "${OPENIM_ROOT}"/logs\* -o \ -path "${OPENIM_ROOT}"/logs\* -o \
-path "${OPENIM_ROOT}"/.gitignore\* -o \ -path "${OPENIM_ROOT}"/.gitignore\* -o \
-path "${OPENIM_ROOT}"/.gsemver.yml\* -o \ -path "${OPENIM_ROOT}"/.gsemver.yml\* -o \
-path "${OPENIM_ROOT}"/.config\* -o \ -path "${OPENIM_ROOT}"/.config\* -o \
-path "${OPENIM_ROOT}"/.chglog\* -o \ -path "${OPENIM_ROOT}"/.chglog\* -o \
-path "${OPENIM_ROOT}"/.gitlint -o \ -path "${OPENIM_ROOT}"/.gitlint -o \
-path "${OPENIM_ROOT}"/.golangci.yml -o \ -path "${OPENIM_ROOT}"/.golangci.yml -o \
-path "${OPENIM_ROOT}"/build/goreleaser.yaml -o \ -path "${OPENIM_ROOT}"/build/goreleaser.yaml -o \
-path "${OPENIM_ROOT}"/.note.md -o \ -path "${OPENIM_ROOT}"/.note.md -o \
-path "${OPENIM_ROOT}"/.todo.md \ -path "${OPENIM_ROOT}"/.todo.md \
\) -prune \ \) -prune \
\) -print0 \ \) -print0 \
| "${TAR}" czf "${src_tarball}" --transform "s|${OPENIM_ROOT#/*}|openim|" --null -T - | "${TAR}" czf "${src_tarball}" --transform "s|${OPENIM_ROOT#/*}|openim|" --null -T -
fi fi
} }

@ -102,7 +102,7 @@ openim::util::array_contains() {
for element; do for element; do
if [[ "${element}" == "${search}" ]]; then if [[ "${element}" == "${search}" ]]; then
return 0 return 0
fi fi
done done
return 1 return 1
} }
@ -200,14 +200,14 @@ openim::util::host_os() {
case "$(uname -s)" in case "$(uname -s)" in
Darwin) Darwin)
host_os=darwin host_os=darwin
;; ;;
Linux) Linux)
host_os=linux host_os=linux
;; ;;
*) *)
openim::log::error "Unsupported host OS. Must be Linux or Mac OS X." openim::log::error "Unsupported host OS. Must be Linux or Mac OS X."
exit 1 exit 1
;; ;;
esac esac
echo "${host_os}" echo "${host_os}"
} }
@ -217,69 +217,69 @@ openim::util::host_arch() {
case "$(uname -m)" in case "$(uname -m)" in
x86_64*) x86_64*)
host_arch=amd64 host_arch=amd64
;; ;;
i?86_64*) i?86_64*)
host_arch=amd64 host_arch=amd64
;; ;;
amd64*) amd64*)
host_arch=amd64 host_arch=amd64
;; ;;
aarch64*) aarch64*)
host_arch=arm64 host_arch=arm64
;; ;;
arm64*) arm64*)
host_arch=arm64 host_arch=arm64
;; ;;
arm*) arm*)
host_arch=arm host_arch=arm
;; ;;
i?86*) i?86*)
host_arch=x86 host_arch=x86
;; ;;
s390x*) s390x*)
host_arch=s390x host_arch=s390x
;; ;;
ppc64le*) ppc64le*)
host_arch=ppc64le host_arch=ppc64le
;; ;;
*) *)
openim::log::error "Unsupported host arch. Must be x86_64, 386, arm, arm64, s390x or ppc64le." openim::log::error "Unsupported host arch. Must be x86_64, 386, arm, arm64, s390x or ppc64le."
exit 1 exit 1
;; ;;
esac esac
echo "${host_arch}" echo "${host_arch}"
} }
# Define a bash function to check the versions of Docker and Docker Compose # Define a bash function to check the versions of Docker and Docker Compose
openim::util::check_docker_and_compose_versions() { openim::util::check_docker_and_compose_versions() {
# Define the required versions of Docker and Docker Compose # Define the required versions of Docker and Docker Compose
required_docker_version="20.10.0" required_docker_version="20.10.0"
required_compose_version="2.0" required_compose_version="2.0"
# Get the currently installed Docker version # Get the currently installed Docker version
installed_docker_version=$(docker --version | awk '{print $3}' | sed 's/,//') installed_docker_version=$(docker --version | awk '{print $3}' | sed 's/,//')
# Check if the installed Docker version matches the required version # Check if the installed Docker version matches the required version
if [[ "$installed_docker_version" < "$required_docker_version" ]]; then if [[ "$installed_docker_version" < "$required_docker_version" ]]; then
echo "Docker version mismatch. Installed: $installed_docker_version, Required: $required_docker_version" echo "Docker version mismatch. Installed: $installed_docker_version, Required: $required_docker_version"
return 1 return 1
fi fi
# Check if the docker compose sub-command is available # Check if the docker compose sub-command is available
if ! docker compose version &> /dev/null; then if ! docker compose version &> /dev/null; then
echo "Docker does not support the docker compose sub-command" echo "Docker does not support the docker compose sub-command"
echo "You need to upgrade Docker to the right version" echo "You need to upgrade Docker to the right version"
return 1 return 1
fi fi
# Get the currently installed Docker Compose version # Get the currently installed Docker Compose version
installed_compose_version=$(docker compose version --short) installed_compose_version=$(docker compose version --short)
# Check if the installed Docker Compose version matches the required version # Check if the installed Docker Compose version matches the required version
if [[ "$installed_compose_version" < "$required_compose_version" ]]; then if [[ "$installed_compose_version" < "$required_compose_version" ]]; then
echo "Docker Compose version mismatch. Installed: $installed_compose_version, Required: $required_compose_version" echo "Docker Compose version mismatch. Installed: $installed_compose_version, Required: $required_compose_version"
return 1 return 1
fi fi
} }
@ -292,80 +292,80 @@ openim::util::check_docker_and_compose_versions() {
# openim::util::check_ports 8080 8081 8082 # openim::util::check_ports 8080 8081 8082
# The function returns a status of 1 if any of the processes is not running. # The function returns a status of 1 if any of the processes is not running.
openim::util::check_ports() { openim::util::check_ports() {
# An array to collect ports of processes that are not running. # An array to collect ports of processes that are not running.
local not_started=() local not_started=()
# An array to collect information about processes that are running. # An array to collect information about processes that are running.
local started=() local started=()
openim::log::info "Checking ports: $*" openim::log::info "Checking ports: $*"
# Iterate over each given port. # Iterate over each given port.
for port in "$@"; do for port in "$@"; do
# Initialize variables # Initialize variables
# Check the OS and use the appropriate command # Check the OS and use the appropriate command
if [[ "$OSTYPE" == "linux-gnu"* ]]; then if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if command -v ss > /dev/null 2>&1; then if command -v ss > /dev/null 2>&1; then
info=$(ss -ltnp | grep ":$port" || true) info=$(ss -ltnp | grep ":$port" || true)
else else
info=$(netstat -ltnp | grep ":$port" || true) info=$(netstat -ltnp | grep ":$port" || true)
fi fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
# For macOS, use lsof
info=$(lsof -P -i:"$port" | grep "LISTEN" || 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 elif [[ "$OSTYPE" == "darwin"* ]]; then
# For macOS, use lsof # Handle extraction for macOS
info=$(lsof -P -i:"$port" | grep "LISTEN" || true) pid=$(echo $info | awk '{print $2}' | cut -d'/' -f1)
fi command=$(ps -p $pid -o comm= | xargs basename)
fd=$(echo $info | awk '{print $4}' | cut -d'/' -f1)
fi
# Check if any process is using the port # Get the start time of the process using the PID
if [[ -z $info ]]; then if [[ -z $pid ]]; then
not_started+=($port) start_time="N/A"
else else
if [[ "$OSTYPE" == "linux-gnu"* ]]; then start_time=$(ps -p $pid -o lstart=)
# Extract relevant details for Linux: Process Name, PID, and FD. fi
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 started+=("Port $port - Command: $command, PID: $pid, FD: $fd, Started: $start_time")
if [[ -z $pid ]]; then fi
start_time="N/A" done
else
start_time=$(ps -p $pid -o lstart=)
fi
started+=("Port $port - Command: $command, PID: $pid, FD: $fd, Started: $start_time") # Print information about ports whose processes are not running.
fi 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 done
fi
# Print information about ports whose processes are not running. # Print information about ports whose processes are running.
if [[ ${#not_started[@]} -ne 0 ]]; then if [[ ${#started[@]} -ne 0 ]]; then
openim::log::info "\n### Not started ports:" openim::log::info "\n### Started ports:"
for port in "${not_started[@]}"; do for info in "${started[@]}"; do
openim::log::error "Port $port is not started." openim::log::info "$info"
done done
fi 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 any of the processes is not running, return a status of 1.
if [[ ${#not_started[@]} -ne 0 ]]; then if [[ ${#not_started[@]} -ne 0 ]]; then
echo "++++ OpenIM Log >> cat ${LOG_FILE}" echo "++++ OpenIM Log >> cat ${LOG_FILE}"
return 1 return 1
else else
openim::log::success "All specified processes are running." openim::log::success "All specified processes are running."
return 0 return 0
fi fi
} }
# set +o errexit # set +o errexit
@ -381,75 +381,75 @@ openim::util::check_ports() {
# openim::util::check_process_names nginx mysql redis # openim::util::check_process_names nginx mysql redis
# The function returns a status of 1 if any of the processes is not running. # The function returns a status of 1 if any of the processes is not running.
openim::util::check_process_names() { openim::util::check_process_names() {
# Function to get the port of a process # Function to get the port of a process
get_port() { get_port() {
local pid=$1 local pid=$1
if [[ "$OSTYPE" == "linux-gnu"* ]]; then if [[ "$OSTYPE" == "linux-gnu"* ]]; then
# Linux # Linux
ss -ltnp 2>/dev/null | grep $pid | awk '{print $4}' | cut -d ':' -f2 ss -ltnp 2>/dev/null | grep $pid | awk '{print $4}' | cut -d ':' -f2
elif [[ "$OSTYPE" == "darwin"* ]]; then elif [[ "$OSTYPE" == "darwin"* ]]; then
# macOS # macOS
lsof -nP -iTCP -sTCP:LISTEN -a -p $pid | awk 'NR>1 {print $9}' | sed 's/.*://' lsof -nP -iTCP -sTCP:LISTEN -a -p $pid | awk 'NR>1 {print $9}' | sed 's/.*://'
else else
echo "Unsupported OS" echo "Unsupported OS"
return 1 return 1
fi 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 # Arrays to collect details of processes
if [[ ${#pids[@]} -eq 0 ]]; then local not_started=()
not_started+=($process_name) local started=()
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 openim::log::info "Checking processes: $*"
if [[ -z $port ]]; then # Iterate over each given process name
port="N/A" for process_name in "$@"; do
fi # Use `pgrep` to find process IDs related to the given process name
local pids=($(pgrep -f $process_name))
started+=("Process $process_name - Command: $command, PID: $pid, Port: $port, Start time: $start_time") # Check if any process IDs were found
done 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 fi
done
# Print information started+=("Process $process_name - Command: $command, PID: $pid, Port: $port, Start time: $start_time")
if [[ ${#not_started[@]} -ne 0 ]]; then done
openim::log::info "Not started processes:"
for process_name in "${not_started[@]}"; do
openim::log::error "Process $process_name is not started."
done
fi fi
done
if [[ ${#started[@]} -ne 0 ]]; then # Print information
echo if [[ ${#not_started[@]} -ne 0 ]]; then
openim::log::info "Started processes:" openim::log::info "Not started processes:"
for info in "${started[@]}"; do for process_name in "${not_started[@]}"; do
openim::log::info "$info" openim::log::error "Process $process_name is not started."
done done
fi fi
# Return status if [[ ${#started[@]} -ne 0 ]]; then
if [[ ${#not_started[@]} -ne 0 ]]; then echo
echo "++++ OpenIM Log >> cat ${LOG_FILE}" openim::log::info "Started processes:"
return 1 for info in "${started[@]}"; do
else openim::log::info "$info"
openim::log::success "All processes are running." done
return 0 fi
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 # openim::util::check_process_names docker-pr
@ -462,30 +462,30 @@ openim::util::check_process_names() {
# openim::util::stop_services_on_ports 8080 8081 8082 # openim::util::stop_services_on_ports 8080 8081 8082
# The function returns a status of 1 if any service couldn't be stopped. # The function returns a status of 1 if any service couldn't be stopped.
openim::util::stop_services_on_ports() { openim::util::stop_services_on_ports() {
# An array to collect ports of processes that couldn't be stopped. # An array to collect ports of processes that couldn't be stopped.
local not_stopped=() local not_stopped=()
# An array to collect information about processes that were stopped. # An array to collect information about processes that were stopped.
local stopped=() local stopped=()
openim::log::info "Stopping services on ports: $*" openim::log::info "Stopping services on ports: $*"
# Iterate over each given port. # Iterate over each given port.
for port in "$@"; do for port in "$@"; do
# Use the `lsof` command to find process information related to the given port. # Use the `lsof` command to find process information related to the given port.
info=$(lsof -i :$port -n -P | grep LISTEN || true) 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 there's process information, it means the process associated with the port is running.
if [[ -n $info ]]; then if [[ -n $info ]]; then
# Extract the Process ID. # Extract the Process ID.
while read -r line; do while read -r line; do
local pid=$(echo $line | awk '{print $2}') local pid=$(echo $line | awk '{print $2}')
# Try to stop the service by killing its process. # Try to stop the service by killing its process.
if kill -TERM $pid; then if kill -TERM $pid; then
stopped+=($port) stopped+=($port)
else else
not_stopped+=($port) not_stopped+=($port)
fi fi
done <<< "$info" done <<< "$info"
fi fi
done done
@ -1086,7 +1086,7 @@ function openim::util::ensure-install-nginx {
exit 1 exit 1
fi fi
for port in 80 for port in "80"
do do
if echo |telnet 127.0.0.1 $port 2>&1|grep refused &>/dev/null;then if echo |telnet 127.0.0.1 $port 2>&1|grep refused &>/dev/null;then
exit 1 exit 1
@ -2320,7 +2320,7 @@ function openim::util::ensure-install-nginx {
exit 1 exit 1
fi fi
for port in 80 for port in "80"
do do
if echo |telnet 127.0.0.1 $port 2>&1|grep refused &>/dev/null;then if echo |telnet 127.0.0.1 $port 2>&1|grep refused &>/dev/null;then
exit 1 exit 1
@ -2467,7 +2467,7 @@ function openim::util::desc() {
} }
function openim::util:run::prompt() { function openim::util:run::prompt() {
echo -n "$yellow\$ $reset" echo -n "${yellow}\$ ${reset}"
} }
started="" started=""
@ -2488,7 +2488,7 @@ function openim::util::run() {
if [ -n "$DEMO_RUN_FAST" ]; then if [ -n "$DEMO_RUN_FAST" ]; then
rate=1000 rate=1000
fi fi
echo "$green$1$reset" | pv -qL $rate echo "${green}$1${reset}" | pv -qL "$rate"
if [ -n "$DEMO_RUN_FAST" ]; then if [ -n "$DEMO_RUN_FAST" ]; then
sleep 0.5 sleep 0.5
fi fi

@ -48,7 +48,7 @@ openim::version::get_version_vars() {
# something like 'HEAD -> release-1.8, tag: v1.8.3' where then 'tag: ' # something like 'HEAD -> release-1.8, tag: v1.8.3' where then 'tag: '
# can be extracted from it. # can be extracted from it.
if [[ '$Format:%D$' =~ tag:\ (v[^ ,]+) ]]; then if [[ '$Format:%D$' =~ tag:\ (v[^ ,]+) ]]; then
OPENIM_GIT_VERSION="${BASH_REMATCH[1]}" OPENIM_GIT_VERSION="${BASH_REMATCH[1]}"
fi fi
fi fi
@ -81,7 +81,7 @@ openim::version::get_version_vars() {
# shellcheck disable=SC2001 # shellcheck disable=SC2001
# We have distance to subversion (v1.1.0-subversion-1-gCommitHash) # We have distance to subversion (v1.1.0-subversion-1-gCommitHash)
OPENIM_GIT_VERSION=$(echo "${OPENIM_GIT_VERSION}" | sed "s/-\([0-9]\{1,\}\)-g\([0-9a-f]\{14\}\)$/.\1\+\2/") OPENIM_GIT_VERSION=$(echo "${OPENIM_GIT_VERSION}" | sed "s/-\([0-9]\{1,\}\)-g\([0-9a-f]\{14\}\)$/.\1\+\2/")
elif [[ "${DASHES_IN_VERSION}" == "--" ]] ; then elif [[ "${DASHES_IN_VERSION}" == "--" ]] ; then
# shellcheck disable=SC2001 # shellcheck disable=SC2001
# We have distance to base tag (v1.1.0-1-gCommitHash) # We have distance to base tag (v1.1.0-1-gCommitHash)
OPENIM_GIT_VERSION=$(echo "${OPENIM_GIT_VERSION}" | sed "s/-g\([0-9a-f]\{14\}\)$/+\1/") OPENIM_GIT_VERSION=$(echo "${OPENIM_GIT_VERSION}" | sed "s/-g\([0-9a-f]\{14\}\)$/+\1/")
@ -108,9 +108,9 @@ openim::version::get_version_vars() {
# If OPENIM_GIT_VERSION is not a valid Semantic Version, then refuse to build. # If OPENIM_GIT_VERSION is not a valid Semantic Version, then refuse to build.
if ! [[ "${OPENIM_GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then if ! [[ "${OPENIM_GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then
echo "OPENIM_GIT_VERSION should be a valid Semantic Version. Current value: ${OPENIM_GIT_VERSION}" echo "OPENIM_GIT_VERSION should be a valid Semantic Version. Current value: ${OPENIM_GIT_VERSION}"
echo "Please see more details here: https://semver.org" echo "Please see more details here: https://semver.org"
exit 1 exit 1
fi fi
fi fi
fi fi

@ -126,7 +126,7 @@ APIROOT=$(ROOT_DIR)/pkg/proto
# Linux command settings # Linux command settings
# TODO: Whether you need to join utils? # TODO: Whether you need to join utils?
FIND := find . ! -path './utils/*' ! -path './vendor/*' ! -path './third_party/*' FIND := find . ! -path './utils/*' ! -path './vendor/*' ! -path './third_party/*' ! -path './components/*' ! -path './logs/*'
XARGS := xargs -r --no-run-if-empty XARGS := xargs -r --no-run-if-empty
# Linux command settings-CODE DIRS Copyright # Linux command settings-CODE DIRS Copyright

@ -244,7 +244,7 @@ go.imports: tools.verify.goimports
## go.verify: execute all verity scripts. ## go.verify: execute all verity scripts.
.PHONY: go.verify .PHONY: go.verify
go.verify: go.verify: tools.verify.misspell
@echo "Starting verification..." @echo "Starting verification..."
@scripts_list=$$(find $(ROOT_DIR)/scripts -type f -name 'verify-*' | sort); \ @scripts_list=$$(find $(ROOT_DIR)/scripts -type f -name 'verify-*' | sort); \
for script in $$scripts_list; do \ for script in $$scripts_list; do \

@ -217,6 +217,11 @@ install.depth:
install.go-callvis: install.go-callvis:
@$(GO) install github.com/ofabry/go-callvis@latest @$(GO) install github.com/ofabry/go-callvis@latest
## install.misspell
.PHONY: install.misspell
install.misspell:
@$(GO) install github.com/client9/misspell/cmd/misspell@latest
## install.gothanks: Install gothanks, used to thank go dependencies ## install.gothanks: Install gothanks, used to thank go dependencies
.PHONY: install.gothanks .PHONY: install.gothanks
install.gothanks: install.gothanks:

@ -58,17 +58,17 @@ OPENIM_RELEASE_RUN_TESTS=${OPENIM_RELEASE_RUN_TESTS-y}
# Function to show help message # Function to show help message
show_help() { show_help() {
echo "Usage: $(basename $0) [options]" echo "Usage: $(basename $0) [options]"
echo "Options:" echo "Options:"
echo " -h, --help Show this help message" echo " -h, --help Show this help message"
echo " -se, --setup-env Execute setup environment" echo " -se, --setup-env Execute setup environment"
echo " -vp, --verify-prereqs Execute prerequisites verification" echo " -vp, --verify-prereqs Execute prerequisites verification"
echo " -bc, --build-command Execute build command" echo " -bc, --build-command Execute build command"
echo " -bi, --build-image Execute build image (default: not executed)" echo " -bi, --build-image Execute build image (default: not executed)"
echo " -pt, --package-tarballs Execute package tarballs" echo " -pt, --package-tarballs Execute package tarballs"
echo " -ut, --upload-tarballs Execute upload tarballs" echo " -ut, --upload-tarballs Execute upload tarballs"
echo " -gr, --github-release Execute GitHub release" echo " -gr, --github-release Execute GitHub release"
echo " -gc, --generate-changelog Execute generate changelog" echo " -gc, --generate-changelog Execute generate changelog"
} }
# Initialize all actions to false # Initialize all actions to false
@ -83,57 +83,57 @@ perform_generate_changelog=false
# Process command-line arguments # Process command-line arguments
while getopts "hsevpbciptutgrgc-" opt; do while getopts "hsevpbciptutgrgc-" opt; do
case "${opt}" in case "${opt}" in
h) show_help; exit 0 ;; h) show_help; exit 0 ;;
se) perform_setup_env=true ;; se) perform_setup_env=true ;;
vp) perform_verify_prereqs=true ;; vp) perform_verify_prereqs=true ;;
bc) perform_build_command=true ;; bc) perform_build_command=true ;;
bi) perform_build_image=true ;; # Handling new option bi) perform_build_image=true ;; # Handling new option
pt) perform_package_tarballs=true ;; pt) perform_package_tarballs=true ;;
ut) perform_upload_tarballs=true ;; ut) perform_upload_tarballs=true ;;
gr) perform_github_release=true ;; gr) perform_github_release=true ;;
gc) perform_generate_changelog=true ;; gc) perform_generate_changelog=true ;;
--) case "${OPTARG}" in --) case "${OPTARG}" in
help) show_help; exit 0 ;; help) show_help; exit 0 ;;
setup-env) perform_setup_env=true ;; setup-env) perform_setup_env=true ;;
verify-prereqs) perform_verify_prereqs=true ;; verify-prereqs) perform_verify_prereqs=true ;;
build-command) perform_build_command=true ;; build-command) perform_build_command=true ;;
build-image) perform_build_image=true ;; # Handling new long option build-image) perform_build_image=true ;; # Handling new long option
package-tarballs) perform_package_tarballs=true ;; package-tarballs) perform_package_tarballs=true ;;
upload-tarballs) perform_upload_tarballs=true ;; upload-tarballs) perform_upload_tarballs=true ;;
github-release) perform_github_release=true ;; github-release) perform_github_release=true ;;
generate-changelog) perform_generate_changelog=true ;; generate-changelog) perform_generate_changelog=true ;;
*) echo "Invalid option: --${OPTARG}"; show_help; exit 1 ;; *) echo "Invalid option: --${OPTARG}"; show_help; exit 1 ;;
esac ;; esac ;;
*) show_help; exit 1 ;; *) show_help; exit 1 ;;
esac esac
done done
# Enable all actions by default if no options are provided # Enable all actions by default if no options are provided
if [ "$#" -eq 0 ]; then if [ "$#" -eq 0 ]; then
perform_setup_env=true perform_setup_env=true
perform_verify_prereqs=true perform_verify_prereqs=true
perform_build_command=true perform_build_command=true
perform_package_tarballs=true perform_package_tarballs=true
perform_upload_tarballs=true perform_upload_tarballs=true
perform_github_release=true perform_github_release=true
perform_generate_changelog=true perform_generate_changelog=true
# TODO: Not enabling build_image by default # TODO: Not enabling build_image by default
# perform_build_image=true # perform_build_image=true
fi fi
# Function to perform actions # Function to perform actions
perform_action() { perform_action() {
local flag=$1 local flag=$1
local message=$2 local message=$2
local command=$3 local command=$3
if [ "$flag" == true ]; then if [ "$flag" == true ]; then
openim::log::info "## $message..." openim::log::info "## $message..."
if ! $command; then if ! $command; then
openim::log::errexit "Error in $message" openim::log::errexit "Error in $message"
fi
fi fi
fi
} }
echo "Starting script execution..." echo "Starting script execution..."

@ -39,34 +39,34 @@ openim::log::install_errexit
# Function to execute the scripts. # Function to execute the scripts.
function execute_scripts() { function execute_scripts() {
for script_path in "${OPENIM_SERVER_SCRIPT_START_LIST[@]}"; do for script_path in "${OPENIM_SERVER_SCRIPT_START_LIST[@]}"; do
# Extract the script name without extension for argument generation. # Extract the script name without extension for argument generation.
script_name_with_prefix=$(basename "$script_path" .sh) script_name_with_prefix=$(basename "$script_path" .sh)
# Remove the "openim-" prefix. # Remove the "openim-" prefix.
script_name=${script_name_with_prefix#openim-} script_name=${script_name_with_prefix#openim-}
# Construct the argument based on the script name. # Construct the argument based on the script name.
arg="openim::${script_name}::start" arg="openim::${script_name}::start"
# Check if the script file exists and is executable. # Check if the script file exists and is executable.
if [[ -x "$script_path" ]]; then if [[ -x "$script_path" ]]; then
openim::log::status "Starting script: ${script_path##*/}" # Log the script name. openim::log::status "Starting script: ${script_path##*/}" # Log the script name.
# Execute the script with the constructed argument. # Execute the script with the constructed argument.
"$script_path" "$arg" "$script_path" "$arg"
# Check if the script executed successfully. # Check if the script executed successfully.
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
openim::log::info "${script_path##*/} executed successfully." openim::log::info "${script_path##*/} executed successfully."
else else
openim::log::errexit "Error executing ${script_path##*/}." openim::log::errexit "Error executing ${script_path##*/}."
fi fi
else else
openim::log::errexit "Script ${script_path##*/} is missing or not executable." openim::log::errexit "Script ${script_path##*/} is missing or not executable."
fi fi
done done
sleep 0.5 sleep 0.5
} }

@ -38,8 +38,8 @@ openim::util::stop_services_with_name "${OPENIM_OUTPUT_HOSTBIN}"
echo -n "Stopping services 15 seconds." echo -n "Stopping services 15 seconds."
for i in {1..15}; do for i in {1..15}; do
echo -n "." echo -n "."
sleep 1 sleep 1
done done
echo -e "\nServices stopped." echo -e "\nServices stopped."

@ -28,10 +28,10 @@ source "${OPENIM_ROOT}/scripts/lib/init.sh"
openim::golang::setup_env openim::golang::setup_env
BINS=( BINS=(
gendocs gendocs
genopenimdocs genopenimdocs
genman genman
genyaml genyaml
) )
make -C "${OPENIM_ROOT}" WHAT="${BINS[*]}" make -C "${OPENIM_ROOT}" WHAT="${BINS[*]}"

@ -43,6 +43,54 @@ disabled=(
1091 1091
# this lint prefers command -v to which, they are not the same # this lint prefers command -v to which, they are not the same
2230 2230
# Error SC2155 indicates that you should separate variable declaration and assignment to avoid masking the return value of the command.
# In Bash scripts, when you declare and assign a local variable at the same time a command is executed, you only get the output of the command, but not the exit status (return value) of the command. #
2155
# ShellCheck issues SC2086 warnings when you refer to a variable in a script but don't put it in double quotes.This can lead to unexpected behavior when scripts encounter Spaces,
# newlines, and wildcards in file names or other data.
2086
2206
# TODO: 需要修复,然后开启
2034
2048
2148
2059
2214
2145
2128
2550
2046
2181
1102
2045
2068
2145
2207
2231
2013
2154
2120
1083
2001
2012
2016
2164
2223
2166
2119
2162
2295
2002
2004
2202
2178
2064
2260
2043
2178
2044
2153
) )
# comma separate for passing to shellcheck # comma separate for passing to shellcheck
join_by() { join_by() {
@ -65,14 +113,18 @@ cd "${OPENIM_ROOT}"
# forked should be linted and fixed. # forked should be linted and fixed.
all_shell_scripts=() all_shell_scripts=()
while IFS=$'\n' read -r script; while IFS=$'\n' read -r script;
do git check-ignore -q "$script" || all_shell_scripts+=("$script"); do git check-ignore -q "$script" || all_shell_scripts+=("$script");
done < <(find . -name "*.sh" \ done < <(find . -name "*.sh" \
-not \( \ -not \( \
-path ./_\* -o \ -path ./_\* -o \
-path ./.git\* -o \ -path ./.git\* -o \
-path ./vendor\* -o \ -path ./Godeps\* -o \
\( -path ./third_party\* -a -not -path ./third_party/forked\* \) \ -path ./_output\* -o \
\)) -path ./components\* -o \
-path ./logs\* -o \
-path ./vendor\* -o \
\( -path ./third_party\* -a -not -path ./third_party/forked\* \) \
\) -print 2>/dev/null)
# detect if the host machine has the required shellcheck version installed # detect if the host machine has the required shellcheck version installed
# if so, we will use that instead. # if so, we will use that instead.
@ -113,8 +165,8 @@ if ${HAVE_SHELLCHECK}; then
else else
openim::log::info "Using shellcheck ${SHELLCHECK_VERSION} docker image." openim::log::info "Using shellcheck ${SHELLCHECK_VERSION} docker image."
"${DOCKER}" run \ "${DOCKER}" run \
--rm -v "${OPENIM_ROOT}:"${OPENIM_ROOT}"" -w "${OPENIM_ROOT}" \ --rm -v "${OPENIM_ROOT}:${OPENIM_ROOT}" -w "${OPENIM_ROOT}" \
"${SHELLCHECK_IMAGE}" \ "${SHELLCHECK_IMAGE}" \
shellcheck "${SHELLCHECK_OPTIONS[@]}" "${all_shell_scripts[@]}" >&2 || res=$? shellcheck "${SHELLCHECK_OPTIONS[@]}" "${all_shell_scripts[@]}" >&2 || res=$?
fi fi

@ -25,17 +25,8 @@ OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
export OPENIM_ROOT export OPENIM_ROOT
source "${OPENIM_ROOT}/scripts/lib/init.sh" source "${OPENIM_ROOT}/scripts/lib/init.sh"
# Ensure that we find the binaries we build before anything else.
export GOBIN="${KUBE_OUTPUT_BINPATH}"
PATH="${GOBIN}:${PATH}"
# Install tools we need
pushd "${OPENIM_ROOT}/tools" >/dev/null
GO111MODULE=on go install github.com/client9/misspell/cmd/misspell
popd >/dev/null
# Spell checking # Spell checking
# All the skipping files are defined in scripts/.spelling_failures # 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}") 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 git ls-files | grep -v -e "${failing_packages}" | xargs "$OPENIM_ROOT/_output/tools/misspell" -i "Creater,creater,ect" -error -o stderr

@ -33,7 +33,7 @@ cd "${OPENIM_ROOT}"
ret=0 ret=0
TYPECHECK_SERIAL="${TYPECHECK_SERIAL:-false}" TYPECHECK_SERIAL="${TYPECHECK_SERIAL:-false}"
scripts/run-in-gopath.sh \ scripts/run-in-gopath.sh \
go run test/typecheck/typecheck.go "$@" "--serial=$TYPECHECK_SERIAL" || ret=$? go run test/typecheck/typecheck.go "$@" "--serial=$TYPECHECK_SERIAL" || ret=$?
if [[ $ret -ne 0 ]]; then if [[ $ret -ne 0 ]]; then
openim::log::error "Type Check has failed. This may cause cross platform build failures." >&2 openim::log::error "Type Check has failed. This may cause cross platform build failures." >&2
openim::log::error "Please see https://github.com/openimsdk/open-im-server/tree/main/test/typecheck for more information." >&2 openim::log::error "Please see https://github.com/openimsdk/open-im-server/tree/main/test/typecheck for more information." >&2

@ -30,119 +30,119 @@ Usage:
Timeout in seconds, zero for no timeout Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes -- COMMAND ARGS Execute command with args after the test finishes
USAGE USAGE
exit 1 exit 1
} }
wait_for() { wait_for() {
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
else
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
fi
WAITFORIT_start_ts=$(date +%s)
while :
do
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
WAITFORIT_result=$?
else else
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout" (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
WAITFORIT_result=$?
fi fi
WAITFORIT_start_ts=$(date +%s) if [[ $WAITFORIT_result -eq 0 ]]; then
while : WAITFORIT_end_ts=$(date +%s)
do echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then break
nc -z $WAITFORIT_HOST $WAITFORIT_PORT fi
WAITFORIT_result=$? sleep 1
else done
(echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1 return $WAITFORIT_result
WAITFORIT_result=$?
fi
if [[ $WAITFORIT_result -eq 0 ]]; then
WAITFORIT_end_ts=$(date +%s)
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
break
fi
sleep 1
done
return $WAITFORIT_result
} }
wait_for_wrapper() { wait_for_wrapper() {
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [[ $WAITFORIT_QUIET -eq 1 ]]; then if [[ $WAITFORIT_QUIET -eq 1 ]]; then
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
else else
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
fi fi
WAITFORIT_PID=$! WAITFORIT_PID=$!
trap "kill -INT -$WAITFORIT_PID" INT trap "kill -INT -$WAITFORIT_PID" INT
wait $WAITFORIT_PID wait $WAITFORIT_PID
WAITFORIT_RESULT=$? WAITFORIT_RESULT=$?
if [[ $WAITFORIT_RESULT -ne 0 ]]; then if [[ $WAITFORIT_RESULT -ne 0 ]]; then
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
fi fi
return $WAITFORIT_RESULT return $WAITFORIT_RESULT
} }
# process arguments # process arguments
while [[ $# -gt 0 ]] while [[ $# -gt 0 ]]
do do
case "$1" in case "$1" in
*:* ) *:* )
WAITFORIT_hostport=(${1//:/ }) WAITFORIT_hostport=(${1//:/ })
WAITFORIT_HOST=${WAITFORIT_hostport[0]} WAITFORIT_HOST=${WAITFORIT_hostport[0]}
WAITFORIT_PORT=${WAITFORIT_hostport[1]} WAITFORIT_PORT=${WAITFORIT_hostport[1]}
shift 1 shift 1
;; ;;
--child) --child)
WAITFORIT_CHILD=1 WAITFORIT_CHILD=1
shift 1 shift 1
;; ;;
-q | --quiet) -q | --quiet)
WAITFORIT_QUIET=1 WAITFORIT_QUIET=1
shift 1 shift 1
;; ;;
-s | --strict) -s | --strict)
WAITFORIT_STRICT=1 WAITFORIT_STRICT=1
shift 1 shift 1
;; ;;
-h) -h)
WAITFORIT_HOST="$2" WAITFORIT_HOST="$2"
if [[ $WAITFORIT_HOST == "" ]]; then break; fi if [[ $WAITFORIT_HOST == "" ]]; then break; fi
shift 2 shift 2
;; ;;
--host=*) --host=*)
WAITFORIT_HOST="${1#*=}" WAITFORIT_HOST="${1#*=}"
shift 1 shift 1
;; ;;
-p) -p)
WAITFORIT_PORT="$2" WAITFORIT_PORT="$2"
if [[ $WAITFORIT_PORT == "" ]]; then break; fi if [[ $WAITFORIT_PORT == "" ]]; then break; fi
shift 2 shift 2
;; ;;
--port=*) --port=*)
WAITFORIT_PORT="${1#*=}" WAITFORIT_PORT="${1#*=}"
shift 1 shift 1
;; ;;
-t) -t)
WAITFORIT_TIMEOUT="$2" WAITFORIT_TIMEOUT="$2"
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
shift 2 shift 2
;; ;;
--timeout=*) --timeout=*)
WAITFORIT_TIMEOUT="${1#*=}" WAITFORIT_TIMEOUT="${1#*=}"
shift 1 shift 1
;; ;;
--) --)
shift shift
WAITFORIT_CLI=("$@") WAITFORIT_CLI=("$@")
break break
;; ;;
--help) --help)
usage usage
;; ;;
*) *)
echoerr "Unknown argument: $1" echoerr "Unknown argument: $1"
usage usage
;; ;;
esac esac
done done
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
echoerr "Error: you need to provide a host and port to test." echoerr "Error: you need to provide a host and port to test."
usage usage
fi fi
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15} WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
@ -156,36 +156,36 @@ WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlin
WAITFORIT_BUSYTIMEFLAG="" WAITFORIT_BUSYTIMEFLAG=""
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
WAITFORIT_ISBUSY=1 WAITFORIT_ISBUSY=1
# Check if busybox timeout uses -t flag # Check if busybox timeout uses -t flag
# (recent Alpine versions don't support -t anymore) # (recent Alpine versions don't support -t anymore)
if timeout &>/dev/stdout | grep -q -e '-t '; then if timeout &>/dev/stdout | grep -q -e '-t '; then
WAITFORIT_BUSYTIMEFLAG="-t" WAITFORIT_BUSYTIMEFLAG="-t"
fi fi
else else
WAITFORIT_ISBUSY=0 WAITFORIT_ISBUSY=0
fi fi
if [[ $WAITFORIT_CHILD -gt 0 ]]; then if [[ $WAITFORIT_CHILD -gt 0 ]]; then
wait_for
WAITFORIT_RESULT=$?
exit $WAITFORIT_RESULT
else
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
wait_for_wrapper
WAITFORIT_RESULT=$?
else
wait_for wait_for
WAITFORIT_RESULT=$? WAITFORIT_RESULT=$?
exit $WAITFORIT_RESULT fi
else
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
wait_for_wrapper
WAITFORIT_RESULT=$?
else
wait_for
WAITFORIT_RESULT=$?
fi
fi fi
if [[ $WAITFORIT_CLI != "" ]]; then if [[ $WAITFORIT_CLI != "" ]]; then
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess" echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
exit $WAITFORIT_RESULT
fi
exec "${WAITFORIT_CLI[@]}"
else
exit $WAITFORIT_RESULT exit $WAITFORIT_RESULT
fi
exec "${WAITFORIT_CLI[@]}"
else
exit $WAITFORIT_RESULT
fi fi

@ -1,27 +1,52 @@
# OpenIM Typecheck # OpenIM Typecheck: Cross-Platform Source Code Type Checking for Go
OpenIM Typecheck 为所有 Go 构建平台进行跨平台源代码类型检查。 ## Introduction
## 优点 OpenIM Typecheck is a robust tool designed for cross-platform source code type checking across all Go build platforms. This utility leverages Gos built-in parsing and type-check libraries (`go/parser` and `go/types`) to deliver efficient and reliable code analysis.
- **速度**OpenIM 完整编译大约需要 3 分钟,而使用 Typecheck 只需数秒。 ## Advantages
- **资源消耗**:与需要 >40GB 的 RAM 不同Typecheck 只需 <8GB RAM
## 实现 - **Speed**: A complete compilation with OpenIM can take approximately 3 minutes. In contrast, OpenIM Typecheck achieves this in mere seconds, significantly enhancing productivity.
- **Resource Efficiency**: Unlike the typical requirement of over 40GB of RAM for standard processes, Typecheck operates effectively with less than 8GB of RAM. This reduction in resource consumption makes it highly suitable for a variety of systems, reducing overheads and facilitating smoother operations.
OpenIM Typecheck 使用 Go 内置的解析和类型检查库 (`go/parser` 和 `go/types`)。然而,这些库并不是 go 编译器所使用的。偶尔会出现不匹配的情况,但总的来说,它们是相当接近的。 ## Implementation
## 错误处理 OpenIM Typecheck employs Go's native parsing and type-checking libraries (`go/parser` and `go/types`). However, it's important to note that these libraries aren't identical to those used by the Go compiler. While occasional mismatches may occur, these libraries generally provide close approximations to the compiler's functionality, offering a reliable basis for type checking.
如果错误不会阻止构建,可以忽略。 ## Error Handling
**`go/types` 报告的错误,但 `go build` 不会** Typecheck's approach to error handling is pragmatic, focusing on practicality and build continuity.
- **真正的错误**(根据规范):
- 应尽量修复。如果无法修复或正在进行中(例如,已被外部引用的代码),则可以忽略。
- 例如:闭包中的未使用变量
- **不真实的错误**
- 应忽略并在适当的情况下向上游报告。
- 例如staging 和 generated 类型之间的类型检查不匹配
**`go build` 报告的错误,但我们不会** **Errors reported by `go/types` but not by `go build`**:
- CGo 错误,包括语法和链接器错误。 - **Actual Errors** (as per the specification):
- These should ideally be rectified. If rectification is not feasible, such as in cases of ongoing work or external dependencies in the code, these errors can be overlooked.
- Example: Unused variables within a closure.
- **False Positives**:
- These errors should be ignored and, where appropriate, reported upstream for resolution.
- Example: Type mismatches between staging and generated types.
**Errors reported by `go build` but not by us**:
- CGo-related errors, including both syntax and linker issues, are outside our scope.
## Usage
### Locally
To run Typecheck locally, simply use the following command:
```bash
make verify
```
### Continuous Integration (CI)
In CI environments, Typecheck can be integrated into the workflow as follows:
```yaml
- name: Typecheck
run: make verify
```
This streamlined process facilitates efficient error detection and resolution, ensuring a robust and reliable build pipeline.
More to learn about typecheck [share blog](https://nsddd.top/posts/concurrent-type-checking-and-cross-platform-development-in-go/)

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// do a fast type check of kubernetes code, for all platforms. // do a fast type check of openim code, for all platforms.
package main package main
import ( import (
@ -47,14 +47,12 @@ var (
crossPlatforms = []string{ crossPlatforms = []string{
"linux/amd64", "windows/386", "linux/amd64", "windows/386",
"darwin/amd64", "darwin/arm64", "darwin/amd64", "darwin/arm64",
"linux/386", "linux/386", "linux/arm",
"windows/amd64", "linux/arm64", "windows/amd64", "linux/arm64",
"linux/ppc64le", "linux/s390x", "linux/ppc64le", "linux/s390x",
"windows/arm64", "windows/arm64",
} }
// "linux/arm",
// directories we always ignore // directories we always ignore
standardIgnoreDirs = []string{ standardIgnoreDirs = []string{
// Staging code is symlinked from vendor/k8s.io, and uses import // Staging code is symlinked from vendor/k8s.io, and uses import
@ -62,17 +60,14 @@ var (
// inside of staging/, but works when typechecked as part of vendor/. // inside of staging/, but works when typechecked as part of vendor/.
"staging", "staging",
"components", "components",
"logs",
// OS-specific vendor code tends to be imported by OS-specific // OS-specific vendor code tends to be imported by OS-specific
// packages. We recursively typecheck imported vendored packages for // packages. We recursively typecheck imported vendored packages for
// each OS, but don't typecheck everything for every OS. // each OS, but don't typecheck everything for every OS.
"vendor", "vendor",
"test",
"_output", "_output",
"OpenIMSKD/tools", "*/mw/rpc_server_interceptor.go",
// 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
// in $GOSRC/$GOROOT (both typecheck and the shell script).
"pkg/kubectl/cmd/testdata/edit",
// Tools we use for maintaining the code base but not necessarily // Tools we use for maintaining the code base but not necessarily
// ship as part of the release // ship as part of the release
"sopenim::golang::setup_env:tools/yamlfmt/yamlfmt.go:tools", "sopenim::golang::setup_env:tools/yamlfmt/yamlfmt.go:tools",

@ -34,7 +34,7 @@ openim_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
wrkdir="${openim_root}/_output/wrk" wrkdir="${openim_root}/_output/wrk"
jobname="openim-api" jobname="openim-api"
duration="300s" duration="300s"
threads=$((3 * `grep -c processor /proc/cpuinfo`)) threads=$((3 * $(grep -c processor /proc/cpuinfo)))
source "${openim_root}/scripts/lib/color.sh" source "${openim_root}/scripts/lib/color.sh"
@ -122,7 +122,7 @@ if (s ~ "s") {
# Remove existing data file # Remove existing data file
function openim::wrk::prepare() { function openim::wrk::prepare() {
rm -f ${wrkdir}/${datfile} rm -f "${wrkdir}"/"${datfile}"
} }
# Plot according to gunplot data file # Plot according to gunplot data file
@ -216,7 +216,7 @@ openim::wrk::start_performance_test() {
do do
wrkcmd="${cmd} -c ${c} $1" wrkcmd="${cmd} -c ${c} $1"
echo "Running wrk command: ${wrkcmd}" echo "Running wrk command: ${wrkcmd}"
result=`eval ${wrkcmd}` result=$(eval "${wrkcmd}")
openim::wrk::convert_plot_data "${result}" openim::wrk::convert_plot_data "${result}"
done done
@ -241,9 +241,10 @@ while getopts "hd:n:" opt;do
esac esac
done done
shift $(($OPTIND-1)) shift $((OPTIND-1))
mkdir -p "${wrkdir}"
mkdir -p ${wrkdir}
case $1 in case $1 in
"diff") "diff")
if [ "$#" -lt 3 ];then if [ "$#" -lt 3 ];then
@ -255,7 +256,7 @@ case $1 in
t2=$(basename $3|sed 's/.dat//g') # 对比图中粉色线条名称 t2=$(basename $3|sed 's/.dat//g') # 对比图中粉色线条名称
join $2 $3 > /tmp/plot_diff.dat join $2 $3 > /tmp/plot_diff.dat
openim::wrk::plot_diff `basename $2` `basename $3` openim::wrk::plot_diff "$(basename "$2")" "$(basename "$3")"
exit 0 exit 0
;; ;;
*) *)

@ -31,7 +31,7 @@ var (
usernameV3 = "root" usernameV3 = "root"
passwordV3 = "openIM123" passwordV3 = "openIM123"
addrV3 = "127.0.0.1:13306" addrV3 = "127.0.0.1:13306"
databaseV3 = "openIM_v3" databaseV3 = "openim_v3"
) )
``` ```

@ -38,7 +38,7 @@ func main() {
usernameV3 = "root" // v3版本mysql用户名 usernameV3 = "root" // v3版本mysql用户名
passwordV3 = "openIM123" // v3版本mysql密码 passwordV3 = "openIM123" // v3版本mysql密码
addrV3 = "127.0.0.1:13306" // v3版本mysql地址 addrV3 = "127.0.0.1:13306" // v3版本mysql地址
databaseV3 = "openIM_v3" // v3版本mysql数据库名字 databaseV3 = "openim_v3" // v3版本mysql数据库名字
) )
var concurrency = 1 // 并发数量 var concurrency = 1 // 并发数量

@ -44,7 +44,7 @@ const (
UsernameV3 = "root" UsernameV3 = "root"
PasswordV3 = "openIM123" PasswordV3 = "openIM123"
IpV3 = "43.134.63.160:13306" IpV3 = "43.134.63.160:13306"
DatabaseV3 = "openIM_v3" DatabaseV3 = "openim_v3"
) )
// V3 chat. // V3 chat.

@ -38,7 +38,7 @@ func Cmd() {
usernameV3 = "root" usernameV3 = "root"
passwordV3 = "openIM123" passwordV3 = "openIM123"
addrV3 = "203.56.175.233:13306" addrV3 = "203.56.175.233:13306"
databaseV3 = "openIM_v3" databaseV3 = "openim_v3"
) )
log.SetFlags(log.LstdFlags | log.Llongfile) log.SetFlags(log.LstdFlags | log.Llongfile)
dsnV2 := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", usernameV2, passwordV2, addrV2, databaseV2) dsnV2 := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", usernameV2, passwordV2, addrV2, databaseV2)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save