diff --git a/docker-compose.yml b/docker-compose.yml index b5c80188c..e4449b5ad 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,15 +10,13 @@ networks: - subnet: '${DOCKER_BRIDGE_SUBNET:-172.28.0.0/16}' gateway: '${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}' - - services: mongodb: image: mongo:${MONGODB_IMAGE_VERSION-6.0.2} ports: - "${MONGO_PORT:-37017}:27017" container_name: mongo - command: --wiredTigerCacheSizeGB 1 --auth + command: ["/bin/bash", "-c", "/docker-entrypoint-initdb.d/mongo-init.sh || true; docker-entrypoint.sh mongod --wiredTigerCacheSizeGB 1 --auth"] volumes: - "${DATA_DIR:-./}/components/mongodb/data/db:/data/db" - "${DATA_DIR:-./}/components/mongodb/data/logs:/data/logs" @@ -96,7 +94,7 @@ services: ipv4_address: ${KAFKA_NETWORK_ADDRESS:-172.28.0.4} minio: - image: minio/minio:${MINIO_IMAGE_VERSION:-latest} + image: minio/minio:${MINIO_IMAGE_VERSION:-RELEASE.2024-01-11T07-46-16Z} ports: - "${MINIO_PORT:-10005}:9000" - "9090:9090" @@ -114,21 +112,104 @@ services: ipv4_address: ${MINIO_NETWORK_ADDRESS:-172.28.0.6} openim-web: - image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-web:${OPENIM_WEB_IMAGE_VERSION:-latest} + image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-web:${OPENIM_WEB_IMAGE_VERSION:-v3.5.0-docker} container_name: openim-web - environment: - - OPENIM_WEB_DIST_PATH=${OPENIM_WEB_DIST_PATH:-/app/dist} - - OPENIM_WEB_PORT=${OPENIM_WEB_PORT:-11001} restart: always ports: - - "${OPENIM_WEB_PORT:-11001}:11001" + - "${OPENIM_WEB_PORT:-11001}:80" networks: server: ipv4_address: ${OPENIM_WEB_NETWORK_ADDRESS:-172.28.0.7} +### TODO: Uncomment, or deploy using openim docker: https://github.com/openimsdk/openim-docker # Uncomment and configure the following services as needed + + # openim-server: + # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-server:${SERVER_IMAGE_VERSION:-main} + # container_name: openim-server + # ports: + # - "${OPENIM_WS_PORT:-10001}:${OPENIM_WS_PORT:-10001}" + # - "${API_OPENIM_PORT:-10002}:${API_OPENIM_PORT:-10002}" + # - "${API_PROM_PORT:-20100}:${API_PROM_PORT:-20100}" + # - "${USER_PROM_PORT:-20110}:${USER_PROM_PORT:-20110}" + # - "${FRIEND_PROM_PORT:-20120}:${FRIEND_PROM_PORT:-20120}" + # - "${MESSAGE_PROM_PORT:-20130}:${MESSAGE_PROM_PORT:-20130}" + # - "${MSG_GATEWAY_PROM_PORT:-20140}:${MSG_GATEWAY_PROM_PORT:-20140}" + # - "${GROUP_PROM_PORT:-20150}:${GROUP_PROM_PORT:-20150}" + # - "${AUTH_PROM_PORT:-20160}:${AUTH_PROM_PORT:-20160}" + # - "${PUSH_PROM_PORT:-20170}:${PUSH_PROM_PORT:-20170}" + # - "${CONVERSATION_PROM_PORT:-20230}:${CONVERSATION_PROM_PORT:-20230}" + # - "${RTC_PROM_PORT:-21300}:${RTC_PROM_PORT:-21300}" + # - "${THIRD_PROM_PORT:-21301}:${THIRD_PROM_PORT:-21301}" + # - "21400-21403:21400-21403" + # healthcheck: + # test: ["CMD", "/openim/openim-server/scripts/check-all.sh"] + # interval: 120s + # timeout: 30s + # retries: 5 + # env_file: + # - .env + # environment: + # - OPENIM_IP=${OPENIM_IP:-127.0.0.1} + # volumes: + # - "${DATA_DIR:-./}/openim-server/logs:/openim/openim-server/logs" + # - "${DATA_DIR:-./}/openim-server/_output/logs:/openim/openim-server/_output/logs" + # - "${DATA_DIR:-./}/openim-server/config:/openim/openim-server/config" + # restart: always + # depends_on: + # - kafka + # - mysql + # - mongodb + # - redis + # - minio + # logging: + # driver: json-file + # options: + # max-size: "1g" + # max-file: "2" + # networks: + # server: + # ipv4_address: ${OPENIM_SERVER_NETWORK_ADDRESS:-172.28.0.8} + + # openim-chat: + # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-chat:${CHAT_IMAGE_VERSION:-main} + # container_name: openim-chat + # healthcheck: + # test: ["CMD", "/openim/openim-chat/scripts/check_all.sh"] + # interval: 60s + # timeout: 30s + # retries: 5 + # env_file: + # - .env + # environment: + # - ZOOKEEPER_ADDRESS=${DOCKER_BRIDGE_GATEWAY:-172.28.0.1} + # - ZOOKEEPER_PORT=${ZOOKEEPER_PORT:-12181} + # - OPENIM_SERVER_ADDRESS=http://${OPENIM_SERVER_ADDRESS:-172.28.0.1} + # - API_OPENIM_PORT=${API_OPENIM_PORT:-10002} + # - MYSQL_ADDRESS=${DOCKER_BRIDGE_GATEWAY:-172.28.0.1} + # - MYSQL_PORT=${MYSQL_PORT:-13306} + # - REDIS_ADDRESS=${DOCKER_BRIDGE_GATEWAY:-172.28.0.1} + # - REDIS_PORT=${REDIS_PORT:-16379} + # ports: + # - "${OPENIM_CHAT_API_PORT:-10008}:10008" + # - "${OPENIM_ADMIN_API_PORT:-10009}:10009" + # volumes: + # - "${DATA_DIR:-./}/components/openim-chat/logs:/openim/openim-chat/logs" + # - "${DATA_DIR:-./}/components/openim-chat/config:/openim/openim-chat/config" + # restart: always + # # user: root:root + # logging: + # driver: json-file + # options: + # max-size: "1g" + # max-file: "2" + # networks: + # server: + # ipv4_address: ${OPENIM_CHAT_NETWORK_ADDRESS:-172.28.0.9} + # openim-admin: - # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-admin-front:v3.4.0 + # # https://github.com/openimsdk/open-im-server/issues/1662 + # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-admin:${ADMIN_FRONT_VERSION:-toc-base-open-docker.35} # container_name: openim-admin # restart: always # ports: @@ -143,8 +224,8 @@ services: # hostname: prometheus # restart: always # volumes: - # - ./config/prometheus.yml:/etc/prometheus/prometheus.yml - # - ./config/instance-down-rules.yml:/etc/prometheus/instance-down-rules.yml + # - "${DATA_DIR:-./}/config/instance-down-rules.yml:/etc/prometheus/instance-down-rules.yml" + # - "${DATA_DIR:-./}/config/prometheus.yml:/etc/prometheus/prometheus.yml" # ports: # - "${PROMETHEUS_PORT:-19090}:9090" # networks: @@ -157,8 +238,8 @@ services: # hostname: alertmanager # restart: always # volumes: - # - ./config/alertmanager.yml:/etc/alertmanager/alertmanager.yml - # - ./config/email.tmpl:/etc/alertmanager/email.tmpl + # - ${DATA_DIR:-./}/config/alertmanager.yml:/etc/alertmanager/alertmanager.yml + # - ${DATA_DIR:-./}/config/email.tmpl:/etc/alertmanager/email.tmpl # ports: # - "${ALERT_MANAGER_PORT:-19093}:9093" # networks: @@ -174,7 +255,7 @@ services: # ports: # - "${GRAFANA_PORT:-13000}:3000" # volumes: - # - ${DATA_DIR:-./}/components/grafana:/var/lib/grafana + # - "${DATA_DIR:-./}/components/grafana:/var/lib/grafana" # networks: # server: # ipv4_address: ${GRAFANA_NETWORK_ADDRESS:-172.28.0.11} diff --git a/internal/rpc/msg/as_read.go b/internal/rpc/msg/as_read.go index 71e038b39..06c0bc86e 100644 --- a/internal/rpc/msg/as_read.go +++ b/internal/rpc/msg/as_read.go @@ -124,6 +124,16 @@ func (m *msgServer) MarkMsgsAsRead( return } } + + req_callback := &cbapi.CallbackSingleMsgReadReq{ + UserID: req.UserID, + ConversationID: req.ConversationID, + ContentType: conversation.ConversationType, + Seqs: req.Seqs, + } + if err = CallbackSingleMsgRead(ctx, req_callback); err != nil { + return nil, err + } if err = m.sendMarkAsReadNotification(ctx, req.ConversationID, conversation.ConversationType, req.UserID, m.conversationAndGetRecvID(conversation, req.UserID), req.Seqs, hasReadSeq); err != nil { return diff --git a/internal/rpc/msg/callback.go b/internal/rpc/msg/callback.go index 5d192fb87..f98318bba 100644 --- a/internal/rpc/msg/callback.go +++ b/internal/rpc/msg/callback.go @@ -70,7 +70,7 @@ func GetContent(msg *sdkws.MsgData) string { } func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error { - if !config.Config.Callback.CallbackBeforeSendSingleMsg.Enable { + if !config.Config.Callback.CallbackBeforeSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing { return nil } req := &cbapi.CallbackBeforeSendSingleMsgReq{ @@ -85,7 +85,7 @@ func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) er } func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error { - if !config.Config.Callback.CallbackAfterSendSingleMsg.Enable { + if !config.Config.Callback.CallbackAfterSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing { return nil } req := &cbapi.CallbackAfterSendSingleMsgReq{ @@ -100,7 +100,7 @@ func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) err } func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error { - if !config.Config.Callback.CallbackBeforeSendGroupMsg.Enable { + if !config.Config.Callback.CallbackBeforeSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing { return nil } req := &cbapi.CallbackBeforeSendGroupMsgReq{ @@ -115,7 +115,7 @@ func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) err } func callbackAfterSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error { - if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable { + if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing { return nil } req := &cbapi.CallbackAfterSendGroupMsgReq{ diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index 5680c2b3d..254d0564b 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -234,7 +234,7 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR } func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPaginationUsersReq) (resp *pbuser.GetPaginationUsersResp, err error) { - total, users, err := s.PageFindUser(ctx, constant.IMOrdinaryUser, req.Pagination) + total, users, err := s.PageFindUser(ctx, constant.IMOrdinaryUser, constant.AppOrdinaryUsers, req.Pagination) if err != nil { return nil, err } diff --git a/pkg/callbackstruct/message.go b/pkg/callbackstruct/message.go index ae36d7139..35d2e82d5 100644 --- a/pkg/callbackstruct/message.go +++ b/pkg/callbackstruct/message.go @@ -94,9 +94,10 @@ type CallbackGroupMsgReadResp struct { type CallbackSingleMsgReadReq struct { CallbackCommand `json:"callbackCommand"` - SendID string `json:"sendID"` - ReceiveID string `json:"receiveID"` - ContentType int64 `json:"contentType"` + UserID string `json:"userID"` + ConversationID string `json:"conversationID"` + ContentType int32 `json:"contentType"` + Seqs []int64 `json:"seqs"` } type CallbackSingleMsgReadResp struct { diff --git a/pkg/common/db/controller/user.go b/pkg/common/db/controller/user.go index f664417db..50e3ea0fe 100644 --- a/pkg/common/db/controller/user.go +++ b/pkg/common/db/controller/user.go @@ -49,7 +49,7 @@ type UserDatabase interface { // UpdateByMap update (zero value) external guarantee userID exists UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) // FindUser - PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) + PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) // Page If not found, no error is returned Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) // IsExist true as long as one exists @@ -184,8 +184,8 @@ func (u *userDatabase) Page(ctx context.Context, pagination pagination.Paginatio return u.userDB.Page(ctx, pagination) } -func (u *userDatabase) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { - return u.userDB.PageFindUser(ctx, level, pagination) +func (u *userDatabase) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { + return u.userDB.PageFindUser(ctx, level1, level2, pagination) } // IsExist Does userIDs exist? As long as there is one, it will be true. diff --git a/pkg/common/db/mgo/user.go b/pkg/common/db/mgo/user.go index 574689fc1..49cd65fa9 100644 --- a/pkg/common/db/mgo/user.go +++ b/pkg/common/db/mgo/user.go @@ -77,8 +77,15 @@ func (u *UserMgo) Page(ctx context.Context, pagination pagination.Pagination) (c return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, pagination) } -func (u *UserMgo) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { - return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{"app_manger_level": level}, pagination) +func (u *UserMgo) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { + query := bson.M{ + "$or": []bson.M{ + {"app_manger_level": level1}, + {"app_manger_level": level2}, + }, + } + + return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, query, pagination) } func (u *UserMgo) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) { diff --git a/pkg/common/db/table/relation/user.go b/pkg/common/db/table/relation/user.go index 9844bdcee..dd7cefe59 100644 --- a/pkg/common/db/table/relation/user.go +++ b/pkg/common/db/table/relation/user.go @@ -56,7 +56,7 @@ type UserModelInterface interface { TakeNotification(ctx context.Context, level int64) (user []*UserModel, err error) TakeByNickname(ctx context.Context, nickname string) (user []*UserModel, err error) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*UserModel, err error) - PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*UserModel, err error) + PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*UserModel, err error) Exist(ctx context.Context, userID string) (exist bool, err error) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, err error) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) diff --git a/scripts/check-all.sh b/scripts/check-all.sh index 7b53e4a89..72a34a5e5 100755 --- a/scripts/check-all.sh +++ b/scripts/check-all.sh @@ -30,6 +30,7 @@ OPENIM_VERBOSE=4 openim::log::info "\n# Begin to check all openim service" +openim::log::status "Check all dependent service ports" # Elegant printing function # Elegant printing function print_services_and_ports() { @@ -60,7 +61,7 @@ print_services_and_ports "${OPENIM_DEPENDENCY_TARGETS[@]}" "${OPENIM_DEPENDENCY_ # OpenIM check echo "++ The port being checked: ${OPENIM_SERVER_PORT_LISTARIES[@]}" openim::log::info "\n## Check all dependent service ports" -echo "+++ The port being checked: ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]}" +echo "++ The port being checked: ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]}" set +e diff --git a/scripts/install/openim-tools.sh b/scripts/install/openim-tools.sh index f97b9d836..172f456fd 100755 --- a/scripts/install/openim-tools.sh +++ b/scripts/install/openim-tools.sh @@ -103,8 +103,9 @@ function openim::tools::start_service() { printf "Specifying prometheus port: %s\n" "${prometheus_port}" cmd="${cmd} --prometheus_port ${prometheus_port}" fi - openim::log::info "Starting ${binary_name}..." - ${cmd} + openim::log::status "Starting ${binary_name}..." + # Later, after discarding Docker, the Docker keyword is unreliable, and Kubepods is used + ${cmd} | tee -a "${LOG_FILE}" } function openim::tools::start() { diff --git a/scripts/lib/release.sh b/scripts/lib/release.sh index dba74c768..16f2cd97a 100755 --- a/scripts/lib/release.sh +++ b/scripts/lib/release.sh @@ -22,7 +22,6 @@ # example: ./coscli cp/sync -r /home/off-line/docker-off-line/ cos://openim-1306374445/openim/image/amd/off-line/off-line/ -e cos.ap-guangzhou.myqcloud.com # https://cloud.tencent.com/document/product/436/71763 -# Tencent cos configuration readonly BUCKET="openim-1306374445" readonly REGION="ap-guangzhou" readonly COS_RELEASE_DIR="openim-release" @@ -36,8 +35,8 @@ readonly RELEASE_TARS="${LOCAL_OUTPUT_ROOT}/release-tars" readonly RELEASE_IMAGES="${LOCAL_OUTPUT_ROOT}/release-images" # OpenIM github account info -readonly OPENIM_GITHUB_ORG=OpenIMSDK -readonly OPENIM_GITHUB_REPO=Open-IM-Server +readonly OPENIM_GITHUB_ORG=openimsdk +readonly OPENIM_GITHUB_REPO=open-im-server readonly CHAT_GITHUB_REPO=chat readonly ARTIFACT=openim.tar.gz @@ -46,6 +45,14 @@ readonly CHECKSUM=${ARTIFACT}.sha1sum OPENIM_BUILD_CONFORMANCE=${OPENIM_BUILD_CONFORMANCE:-y} OPENIM_BUILD_PULL_LATEST_IMAGES=${OPENIM_BUILD_PULL_LATEST_IMAGES:-y} +if [ -z "${OPENIM_ROOT}" ]; then + OPENIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)" +fi + +if [ -z "${TOOLS_DIR}" ]; then + TOOLS_DIR="${OPENIM_ROOT}/_output/tools" +fi + # Validate a ci version # # Globals: @@ -113,13 +120,14 @@ function openim::release::package_tarballs() { openim::util::wait-for-jobs || { openim::log::error "previous tarball phase failed"; return 1; } } -function openim::release::updload_tarballs() { +function openim::release::upload_tarballs() { openim::log::info "upload ${RELEASE_TARS}/* to cos bucket ${BUCKET}." for file in $(ls ${RELEASE_TARS}/*) do if [ "${COSTOOL}" == "coscli" ];then - coscli cp "${file}" "cos://${BUCKET}/${COS_RELEASE_DIR}/${OPENIM_GIT_VERSION}/${file##*/}" - coscli cp "${file}" "cos://${BUCKET}/${COS_RELEASE_DIR}/latest/${file##*/}" + echo "++++ ${TOOLS_DIR}/coscli cp ${file} cos://${BUCKET}/${COS_RELEASE_DIR}/${OPENIM_GIT_VERSION}/${file##*/}" + ${TOOLS_DIR}/coscli cp "${file}" "cos://${BUCKET}/${COS_RELEASE_DIR}/${OPENIM_GIT_VERSION}/${file##*/}" + ${TOOLS_DIR}/coscli cp "${file}" "cos://${BUCKET}/${COS_RELEASE_DIR}/latest/${file##*/}" else coscmd upload "${file}" "${COS_RELEASE_DIR}/${OPENIM_GIT_VERSION}/" coscmd upload "${file}" "${COS_RELEASE_DIR}/latest/" @@ -139,6 +147,8 @@ function openim::release::package_src_tarball() { \( -path "${OPENIM_ROOT}"/_\* -o \ -path "${OPENIM_ROOT}"/.git\* -o \ -path "${OPENIM_ROOT}"/.github\* -o \ + -path "${OPENIM_ROOT}"/components\* -o \ + -path "${OPENIM_ROOT}"/logs\* -o \ -path "${OPENIM_ROOT}"/.gitignore\* -o \ -path "${OPENIM_ROOT}"/.gsemver.yml\* -o \ -path "${OPENIM_ROOT}"/.config\* -o \ @@ -158,6 +168,7 @@ function openim::release::package_src_tarball() { function openim::release::package_server_tarballs() { # Find all of the built client binaries local long_platforms=("${LOCAL_OUTPUT_BINPATH}"/*/*) + if [[ -n ${OPENIM_BUILD_PLATFORMS-} ]]; then read -ra long_platforms <<< "${OPENIM_BUILD_PLATFORMS}" fi @@ -167,68 +178,81 @@ function openim::release::package_server_tarballs() { local platform_tag platform=${platform_long##${LOCAL_OUTPUT_BINPATH}/} # Strip LOCAL_OUTPUT_BINPATH platform_tag=${platform/\//-} # Replace a "/" for a "-" + openim::log::status "Starting tarball: server $platform_tag" ( local release_stage="${RELEASE_STAGE}/server/${platform_tag}/openim" + openim::log::info "release_stage: ${release_stage}" + rm -rf "${release_stage}" mkdir -p "${release_stage}/server/bin" local server_bins=("${OPENIM_SERVER_BINARIES[@]}") - # This fancy expression will expand to prepend a path - # (${LOCAL_OUTPUT_BINPATH}/${platform}/) to every item in the - # server_bins array. - cp "${server_bins[@]/bin/#/${LOCAL_OUTPUT_BINPATH}/${platform}/}" \ + openim::log::info " Copy client binaries: ${client_bins[@]/#/${LOCAL_OUTPUT_BINPATH}/${platform}/}" + openim::log::info " Copy client binaries to: ${release_stage}/server/bin" + + # Copy server binaries + cp "${server_bins[@]/#/${LOCAL_OUTPUT_BINPATH}/${platform}/}" \ "${release_stage}/server/bin/" - openim::release::clean_cruft + openim::release::clean_cruft - local package_name="${RELEASE_TARS}/openim-server-${platform_tag}.tar.gz" - openim::release::create_tarball "${package_name}" "${release_stage}/.." - ) & - done - - openim::log::status "Waiting on tarballs" - openim::util::wait-for-jobs || { openim::log::error "server tarball creation failed"; exit 1; } - } + local package_name="${RELEASE_TARS}/openim-server-${platform_tag}.tar.gz" + openim::release::create_tarball "${package_name}" "${release_stage}/.." + ) & + done + openim::log::status "Waiting on tarballs" + openim::util::wait-for-jobs || { openim::log::error "server tarball creation failed"; exit 1; } +} +# Package up all of the cross compiled clients. Over time this should grow into +# a full SDK # Package up all of the cross compiled clients. Over time this should grow into # a full SDK function openim::release::package_client_tarballs() { # Find all of the built client binaries - local long_platforms=("${LOCAL_OUTPUT_BINPATH}"/*/*) + local long_platforms=("${LOCAL_OUTPUT_BINTOOLSPATH}"/*/*) if [[ -n ${OPENIM_BUILD_PLATFORMS-} ]]; then read -ra long_platforms <<< "${OPENIM_BUILD_PLATFORMS}" fi + # echo "++++ LOCAL_OUTPUT_BINTOOLSPATH: ${LOCAL_OUTPUT_BINTOOLSPATH}" + # LOCAL_OUTPUT_BINTOOLSPATH: /data/workspaces/open-im-server/_output/bin/tools + # echo "++++ long_platforms: ${long_platforms[@]}" + # long_platforms: /data/workspaces/open-im-server/_output/bin/tools/darwin/amd64 /data/workspaces/open-im-server/_output/bin/tools/darwin/arm64 /data/workspaces/open-im-server/_output/bin/tools/linux/amd64 /data/workspaces/open-im-server/_output/bin/tools/linux/arm64 /data/workspaces/open-im-server/_output/bin/tools/linux/mips64 /data/workspaces/open-im-server/_output/bin/tools/linux/mips64le /data/workspaces/open-im-server/_output/bin/tools/linux/ppc64le /data/workspaces/open-im-server/_output/bin/tools/linux/s390x /data/workspaces/open-im-server/_output/bin/tools/windows/amd64 for platform_long in "${long_platforms[@]}"; do local platform local platform_tag - platform=${platform_long##${LOCAL_OUTPUT_BINPATH}/} # Strip LOCAL_OUTPUT_BINPATH + platform=${platform_long##${LOCAL_OUTPUT_BINTOOLSPATH}/} # Strip LOCAL_OUTPUT_BINTOOLSPATH platform_tag=${platform/\//-} # Replace a "/" for a "-" - openim::log::status "Starting tarball: client $platform_tag" + openim::log::status "Starting tarball: client $platform_tag" # darwin-amd64 ( local release_stage="${RELEASE_STAGE}/client/${platform_tag}/openim" + + openim::log::info "release_stage: ${release_stage}" + # ++++ release_stage: /data/workspaces/open-im-server/_output/release-stage/client/darwin-amd64/openim rm -rf "${release_stage}" mkdir -p "${release_stage}/client/bin" local client_bins=("${OPENIM_CLIENT_BINARIES[@]}") - # This fancy expression will expand to prepend a path - # (${LOCAL_OUTPUT_BINPATH}/${platform}/) to every item in the - # client_bins array. - cp "${client_bins[@]/bin/#/${LOCAL_OUTPUT_BINPATH}/${platform}/}" \ + # client_bins: changelog component conversion-msg conversion-mysql formitychecker imctl infra ncpu openim-web up35 versionchecker yamlfmt + # Copy client binclient_bins:aries + openim::log::info " Copy client binaries: ${client_bins[@]/#/${LOCAL_OUTPUT_BINTOOLSPATH}/${platform}/}" + openim::log::info " Copy client binaries to: ${release_stage}/client/bin" + + cp "${client_bins[@]/#/${LOCAL_OUTPUT_BINTOOLSPATH}/${platform}/}" \ "${release_stage}/client/bin/" - openim::release::clean_cruft + openim::release::clean_cruft - local package_name="${RELEASE_TARS}/openim-client-${platform_tag}.tar.gz" - openim::release::create_tarball "${package_name}" "${release_stage}/.." + local package_name="${RELEASE_TARS}/openim-client-${platform_tag}.tar.gz" + openim::release::create_tarball "${package_name}" "${release_stage}/.." ) & done - openim::log::status "Waiting on tarballs" openim::util::wait-for-jobs || { openim::log::error "client tarball creation failed"; exit 1; } } @@ -354,7 +378,7 @@ function openim::release::create_docker_images_for_server() { rm -rf "${docker_build_path}" mkdir -p "${docker_build_path}" ln "${binary_file_path}" "${docker_build_path}/${binary_name}" - ln ""${OPENIM_ROOT}"/build/nsswitch.conf" "${docker_build_path}/nsswitch.conf" + ln "${OPENIM_ROOT}/build/nsswitch.conf" "${docker_build_path}/nsswitch.conf" chmod 0644 "${docker_build_path}/nsswitch.conf" cat < "${docker_file_path}" FROM ${base_image} @@ -399,7 +423,7 @@ EOF function openim::release::package_openim_manifests_tarball() { openim::log::status "Building tarball: manifests" - local src_dir=""${OPENIM_ROOT}"/deployments" + local src_dir="${OPENIM_ROOT}/deployments" local release_stage="${RELEASE_STAGE}/manifests/openim" rm -rf "${release_stage}" @@ -420,7 +444,7 @@ function openim::release::package_openim_manifests_tarball() { #cp "${src_dir}/openim-rpc-msg.yaml" "${dst_dir}" #cp "${src_dir}/openim-rpc-third.yaml" "${dst_dir}" #cp "${src_dir}/openim-rpc-user.yaml" "${dst_dir}" - #cp ""${OPENIM_ROOT}"/cluster/gce/gci/health-monitor.sh" "${dst_dir}/health-monitor.sh" + #cp "${OPENIM_ROOT}/cluster/gce/gci/health-monitor.sh" "${dst_dir}/health-monitor.sh" openim::release::clean_cruft @@ -442,6 +466,7 @@ function openim::release::package_final_tarball() { # This isn't a "full" tarball anymore, but the release lib still expects # artifacts under "full/openim/" local release_stage="${RELEASE_STAGE}/full/openim" + openim::log::info "release_stage(final): ${release_stage}" rm -rf "${release_stage}" mkdir -p "${release_stage}" @@ -454,7 +479,8 @@ EOF # We want everything in /scripts. mkdir -p "${release_stage}/release" - cp -R ""${OPENIM_ROOT}"/scripts/release" "${release_stage}/" + mkdir -p "${OPENIM_ROOT}/scripts/release" + cp -R "${OPENIM_ROOT}/scripts/release" "${release_stage}/" cat < "${release_stage}/release/get-openim-binaries.sh" #!/usr/bin/env bash # This file download openim client and server binaries from tencent cos bucket. @@ -471,11 +497,11 @@ Server binary tarballs are no longer included in the OpenIM final tarball. Run release/get-openim-binaries.sh to download client and server binaries. EOF - # Include hack/lib as a dependency for the cluster/ scripts + # Include scripts/lib as a dependency for the cluster/ scripts #mkdir -p "${release_stage}/hack" - #cp -R ""${OPENIM_ROOT}"/hack/lib" "${release_stage}/hack/" + #cp -R "${OPENIM_ROOT}/scripts/lib" "${release_stage}/scripts/" - cp -R "${OPENIM_ROOT}"/{docs,configs,scripts,deployments,init,README.md,LICENSE} "${release_stage}/" + cp -R "${OPENIM_ROOT}"/{docs,config,scripts,deployments,README.md,LICENSE} "${release_stage}/" echo "${OPENIM_GIT_VERSION}" > "${release_stage}/version" @@ -507,7 +533,7 @@ function openim::release::install_github_release(){ # - git-chglog # - coscmd or coscli function openim::release::verify_prereqs(){ - if [ -z "$(which github-release 2>/dev/null)" ]; then + if [ -z "$(which ${TOOLS_DIR}/github-release 2>/dev/null)" ]; then openim::log::info "'github-release' tool not installed, try to install it." if ! openim::release::install_github_release; then @@ -516,7 +542,7 @@ function openim::release::verify_prereqs(){ fi fi - if [ -z "$(which git-chglog 2>/dev/null)" ]; then + if [ -z "$(which ${TOOLS_DIR}/git-chglog 2>/dev/null)" ]; then openim::log::info "'git-chglog' tool not installed, try to install it." if ! go install github.com/git-chglog/git-chglog/cmd/git-chglog@latest &>/dev/null; then @@ -525,7 +551,7 @@ function openim::release::verify_prereqs(){ fi fi - if [ -z "$(which gsemver 2>/dev/null)" ]; then + if [ -z "$(which ${TOOLS_DIR}/gsemver 2>/dev/null)" ]; then openim::log::info "'gsemver' tool not installed, try to install it." if ! go install github.com/arnaud-deprez/gsemver@latest &>/dev/null; then @@ -534,8 +560,7 @@ function openim::release::verify_prereqs(){ fi fi - - if [ -z "$(which ${COSTOOL} 2>/dev/null)" ]; then + if [ -z "$(which ${TOOLS_DIR}/${COSTOOL} 2>/dev/null)" ]; then openim::log::info "${COSTOOL} tool not installed, try to install it." if ! make -C "${OPENIM_ROOT}" tools.install.${COSTOOL}; then @@ -545,6 +570,7 @@ function openim::release::verify_prereqs(){ fi if [ -z "${TENCENT_SECRET_ID}" -o -z "${TENCENT_SECRET_KEY}" ];then + openim::log::info "You need set env: TENCENT_SECRET_ID(cos secretid) and TENCENT_SECRET_KEY(cos secretkey)" openim::log::error "can not find env: TENCENT_SECRET_ID and TENCENT_SECRET_KEY" return 1 fi @@ -584,39 +610,57 @@ EOF # https://github.com/github-release/github-release function openim::release::github_release() { # create a github release + if [ -z "${GITHUB_TOKEN}" ];then + openim::log::error "can not find env: GITHUB_TOKEN" + return 1 + fi openim::log::info "create a new github release with tag ${OPENIM_GIT_VERSION}" - github-release release \ + ${TOOLS_DIR}/github-release release \ --user ${OPENIM_GITHUB_ORG} \ --repo ${OPENIM_GITHUB_REPO} \ --tag ${OPENIM_GIT_VERSION} \ --description "" \ - --pre-release + --pre-release \ + --draft # update openim tarballs openim::log::info "upload ${ARTIFACT} to release ${OPENIM_GIT_VERSION}" - github-release upload \ + ${TOOLS_DIR}/github-release upload \ --user ${OPENIM_GITHUB_ORG} \ --repo ${OPENIM_GITHUB_REPO} \ --tag ${OPENIM_GIT_VERSION} \ --name ${ARTIFACT} \ + --label "openim-${OPENIM_GIT_VERSION}" \ --file ${RELEASE_TARS}/${ARTIFACT} - openim::log::info "upload openim-src.tar.gz to release ${OPENIM_GIT_VERSION}" - github-release upload \ - --user ${OPENIM_GITHUB_ORG} \ - --repo ${OPENIM_GITHUB_REPO} \ - --tag ${OPENIM_GIT_VERSION} \ - --name "openim-src.tar.gz" \ - --file ${RELEASE_TARS}/openim-src.tar.gz + for file in ${RELEASE_TARS}/*.tar.gz; do + if [[ -f "$file" ]]; then + filename=$(basename "$file") + openim::log::info "Update file ${filename} to release vertion ${OPENIM_GIT_VERSION}" + ${TOOLS_DIR}/github-release upload \ + --user ${OPENIM_GITHUB_ORG} \ + --repo ${OPENIM_GITHUB_REPO} \ + --tag ${OPENIM_GIT_VERSION} \ + --name "${filename}" \ + --file "${file}" + fi + done } function openim::release::generate_changelog() { openim::log::info "generate CHANGELOG-${OPENIM_GIT_VERSION#v}.md and commit it" - git-chglog ${OPENIM_GIT_VERSION} > "${OPENIM_ROOT}"/CHANGELOG/CHANGELOG-${OPENIM_GIT_VERSION#v}.md + local major_version=$(echo ${OPENIM_GIT_VERSION} | cut -d '+' -f 1) + + ${TOOLS_DIR}/git-chglog --config ${OPENIM_ROOT}/CHANGELOG/.chglog/config.yml ${OPENIM_GIT_VERSION} > ${OPENIM_ROOT}/CHANGELOG/CHANGELOG-${major_version#v}.md set +o errexit - git add "${OPENIM_ROOT}"/CHANGELOG/CHANGELOG-${OPENIM_GIT_VERSION#v}.md - git commit -a -m "docs(changelog): add CHANGELOG-${OPENIM_GIT_VERSION#v}.md" - git push -f origin main # 最后将 CHANGELOG 也 push 上去 + git add "${OPENIM_ROOT}"/CHANGELOG/CHANGELOG-${major_version#v}.md + git commit -a -m "docs(changelog): add CHANGELOG-${major_version#v}.md" + echo "" + echo "##########################################################################" + echo "git commit -a -m \"docs(changelog): add CHANGELOG-${major_version#v}.md\"" + openim::log::info "You need git push CHANGELOG-${major_version#v}.md to remote" + echo "##########################################################################" + echo "" } diff --git a/scripts/lib/util.sh b/scripts/lib/util.sh index b8d76edeb..f15a26346 100755 --- a/scripts/lib/util.sh +++ b/scripts/lib/util.sh @@ -301,29 +301,1275 @@ openim::util::check_ports() { openim::log::info "Checking ports: $*" # Iterate over each given port. for port in "$@"; do - # Use the `ss` command to find process information related to the given port. - if command -v ss > /dev/null 2>&1; then - info=$(ss -ltnp | grep ":$port" || true) + # Initialize variables + # Check the OS and use the appropriate command + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + if command -v ss > /dev/null 2>&1; then + info=$(ss -ltnp | grep ":$port" || true) + else + info=$(netstat -ltnp | grep ":$port" || true) + fi + elif [[ "$OSTYPE" == "darwin"* ]]; then + # For macOS, use lsof + info=$(lsof -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 + # Handle extraction for macOS + pid=$(echo $info | awk '{print $2}' | cut -d'/' -f1) + command=$(ps -p $pid -o comm= | xargs basename) + fd=$(echo $info | awk '{print $4}' | cut -d'/' -f1) + fi + + # Get the start time of the process using the PID + if [[ -z $pid ]]; then + start_time="N/A" + else + start_time=$(ps -p $pid -o lstart=) + fi + + started+=("Port $port - Command: $command, PID: $pid, FD: $fd, Started: $start_time") + fi + done + + # Print information about ports whose processes are not running. + if [[ ${#not_started[@]} -ne 0 ]]; then + openim::log::info "\n### Not started ports:" + for port in "${not_started[@]}"; do + openim::log::error "Port $port is not started." + done + fi + + # Print information about ports whose processes are running. + if [[ ${#started[@]} -ne 0 ]]; then + openim::log::info "\n### Started ports:" + for info in "${started[@]}"; do + openim::log::info "$info" + done + fi + + # If any of the processes is not running, return a status of 1. + if [[ ${#not_started[@]} -ne 0 ]]; then + echo "++++ OpenIM Log >> cat ${LOG_FILE}" + return 1 + else + openim::log::success "All specified processes are running." + return 0 + fi +} + +# set +o errexit +# Sample call for testing: +# openim::util::check_ports 10002 1004 12345 13306 +# set -o errexit + +# The `openim::util::check_process_names` function analyzes the state of processes based on given names. +# It accepts multiple process names as arguments and prints: +# 1. The state of the process (whether it's running or not). +# 2. The start time of the process if it's running. +# User: +# openim::util::check_process_names nginx mysql redis +# The function returns a status of 1 if any of the processes is not running. +openim::util::check_process_names() { + # Function to get the port of a process + get_port() { + local pid=$1 + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + # Linux + ss -ltnp 2>/dev/null | grep $pid | awk '{print $4}' | cut -d ':' -f2 + elif [[ "$OSTYPE" == "darwin"* ]]; then + # macOS + lsof -nP -iTCP -sTCP:LISTEN -a -p $pid | awk 'NR>1 {print $9}' | sed 's/.*://' + else + echo "Unsupported OS" + return 1 + fi + } + + # Arrays to collect details of processes + local not_started=() + local started=() + + openim::log::info "Checking processes: $*" + # Iterate over each given process name + for process_name in "$@"; do + # Use `pgrep` to find process IDs related to the given process name + local pids=($(pgrep -f $process_name)) + + # Check if any process IDs were found + if [[ ${#pids[@]} -eq 0 ]]; then + not_started+=($process_name) + else + # If there are PIDs, loop through each one + for pid in "${pids[@]}"; do + local command=$(ps -p $pid -o cmd=) + local start_time=$(ps -p $pid -o lstart=) + local port=$(get_port $pid) + + # Check if port information was found for the PID + if [[ -z $port ]]; then + port="N/A" + fi + + started+=("Process $process_name - Command: $command, PID: $pid, Port: $port, Start time: $start_time") + done + fi + done + + # Print information + if [[ ${#not_started[@]} -ne 0 ]]; then + openim::log::info "Not started processes:" + for process_name in "${not_started[@]}"; do + openim::log::error "Process $process_name is not started." + done + fi + + if [[ ${#started[@]} -ne 0 ]]; then + echo + openim::log::info "Started processes:" + for info in "${started[@]}"; do + openim::log::info "$info" + done + fi + + # Return status + if [[ ${#not_started[@]} -ne 0 ]]; then + echo "++++ OpenIM Log >> cat ${LOG_FILE}" + return 1 + else + openim::log::success "All processes are running." + return 0 + fi +} + +# openim::util::check_process_names docker-pr + +# The `openim::util::stop_services_on_ports` function stops services running on specified ports. +# It accepts multiple ports as arguments and performs the following: +# 1. Attempts to stop any services running on the specified ports. +# 2. Prints details of services successfully stopped and those that failed to stop. +# Usage: +# openim::util::stop_services_on_ports 8080 8081 8082 +# The function returns a status of 1 if any service couldn't be stopped. +openim::util::stop_services_on_ports() { + # An array to collect ports of processes that couldn't be stopped. + local not_stopped=() + + # An array to collect information about processes that were stopped. + local stopped=() + + openim::log::info "Stopping services on ports: $*" + # Iterate over each given port. + for port in "$@"; do + # Use the `lsof` command to find process information related to the given port. + info=$(lsof -i :$port -n -P | grep LISTEN || true) + + # If there's process information, it means the process associated with the port is running. + if [[ -n $info ]]; then + # Extract the Process ID. + while read -r line; do + local pid=$(echo $line | awk '{print $2}') + + # Try to stop the service by killing its process. + if kill -TERM $pid; then + stopped+=($port) + else + not_stopped+=($port) + fi + done <<< "$info" + fi + done + + # Print information about ports whose processes couldn't be stopped. + if [[ ${#not_stopped[@]} -ne 0 ]]; then + openim::log::info "Ports that couldn't be stopped:" + for port in "${not_stopped[@]}"; do + openim::log::status "Failed to stop service on port $port." + done + fi + + # Print information about ports whose processes were successfully stopped. + if [[ ${#stopped[@]} -ne 0 ]]; then + echo + openim::log::info "Stopped services on ports:" + for port in "${stopped[@]}"; do + openim::log::info "Successfully stopped service on port $port." + done + fi + + # If any of the processes couldn't be stopped, return a status of 1. + if [[ ${#not_stopped[@]} -ne 0 ]]; then + return 1 + else + openim::log::success "All specified services were stopped." + echo "" + return 0 + fi +} +# nc -l -p 12345 +# nc -l -p 123456 +# ps -ef | grep "nc -l" +# openim::util::stop_services_on_ports 1234 12345 + + +# The `openim::util::stop_services_with_name` function stops services with specified names. +# It accepts multiple service names as arguments and performs the following: +# 1. Attempts to stop any services with the specified names. +# 2. Prints details of services successfully stopped and those that failed to stop. +# Usage: +# openim::util::stop_services_with_name nginx apache +# The function returns a status of 1 if any service couldn't be stopped. +openim::util::stop_services_with_name() { + # An array to collect names of processes that couldn't be stopped. + local not_stopped=() + + # An array to collect information about processes that were stopped. + local stopped=() + + openim::log::info "Stopping services with names: $*" + # Iterate over each given service name. + for server_name in "$@"; do + # Use the `pgrep` command to find process IDs related to the given service name. + local pids=$(pgrep -f "$server_name") + + # If no process was found with the name, add it to the not_stopped list + if [[ -z $pids ]]; then + not_stopped+=("$server_name") + continue + fi + local stopped_this_time=false + for pid in $pids; do + + # Exclude the PID of the current script + if [[ "$pid" == "$$" ]]; then + continue + fi + + # If there's a Process ID, it means the service with the name is running. + if [[ -n $pid ]]; then + # Try to stop the service by killing its process. + if kill -TERM $pid 2>/dev/null; then + stopped_this_time=true + fi + fi + done + + if $stopped_this_time; then + stopped+=("$server_name") else - info=$(netstat -ltnp | grep ":$port" || true) + not_stopped+=("$server_name") + fi + done + + # Print information about services whose processes couldn't be stopped. + if [[ ${#not_stopped[@]} -ne 0 ]]; then + openim::log::info "Services that couldn't be stopped:" + for name in "${not_stopped[@]}"; do + openim::log::status "Failed to stop the $name service." + done + fi + + # Print information about services whose processes were successfully stopped. + if [[ ${#stopped[@]} -ne 0 ]]; then + echo + openim::log::info "Stopped services:" + for name in "${stopped[@]}"; do + openim::log::info "Successfully stopped the $name service." + done + fi + + openim::log::success "All specified services were stopped." + echo "" +} +# sleep 333333& +# sleep 444444& +# ps -ef | grep "sleep" +# openim::util::stop_services_with_name "sleep 333333" "sleep 444444" + +# This figures out the host platform without relying on golang. We need this as +# we don't want a golang install to be a prerequisite to building yet we need +# this info to figure out where the final binaries are placed. +openim::util::host_platform() { + echo "$(openim::util::host_os)/$(openim::util::host_arch)" +} + +# looks for $1 in well-known output locations for the platform ($2) +# $OPENIM_ROOT must be set +openim::util::find-binary-for-platform() { + local -r lookfor="$1" + local -r platform="$2" + local locations=( + "${OPENIM_ROOT}/_output/bin/${lookfor}" + "${OPENIM_ROOT}/_output/${platform}/${lookfor}" + "${OPENIM_ROOT}/_output/local/bin/${platform}/${lookfor}" + "${OPENIM_ROOT}/_output/platforms/${platform}/${lookfor}" + "${OPENIM_ROOT}/_output/platforms/bin/${platform}/${lookfor}" + ) + + # List most recently-updated location. + local -r bin=$( (ls -t "${locations[@]}" 2>/dev/null || true) | head -1 ) + echo -n "${bin}" +} + +# looks for $1 in well-known output locations for the host platform +# $OPENIM_ROOT must be set +openim::util::find-binary() { + openim::util::find-binary-for-platform "$1" "$(openim::util::host_platform)" +} + +# Run all known doc generators (today gendocs and genman for openimctl) +# $1 is the directory to put those generated documents +openim::util::gen-docs() { + local dest="$1" + + # Find binary + gendocs=$(openim::util::find-binary "gendocs") + genopenimdocs=$(openim::util::find-binary "genopenimdocs") + genman=$(openim::util::find-binary "genman") + genyaml=$(openim::util::find-binary "genyaml") + genfeddocs=$(openim::util::find-binary "genfeddocs") + + # TODO: If ${genfeddocs} is not used from anywhere (it isn't used at + # least from k/k tree), remove it completely. + openim::util::sourced_variable "${genfeddocs}" + + mkdir -p "${dest}/docs/guide/en-US/cmd/openimctl/" + "${gendocs}" "${dest}/docs/guide/en-US/cmd/openimctl/" + + mkdir -p "${dest}/docs/guide/en-US/cmd/" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-api" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-cmdutils" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-crontask" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-msggateway" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-msgtransfer" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-push" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-auth" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-conversation" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-friend" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-group" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-msg" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-third" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-user" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/openimctl" "openimctl" + + mkdir -p "${dest}/docs/man/man1/" +"${genman}" "${dest}/docs/man/man1/" "openim-api" +"${genman}" "${dest}/docs/man/man1/" "openim-cmdutils" +"${genman}" "${dest}/docs/man/man1/" "openim-crontask" +"${genman}" "${dest}/docs/man/man1/" "openim-msggateway" +"${genman}" "${dest}/docs/man/man1/" "openim-msgtransfer" +"${genman}" "${dest}/docs/man/man1/" "openim-push" +"${genman}" "${dest}/docs/man/man1/" "openim-rpc-auth" +"${genman}" "${dest}/docs/man/man1/" "openim-rpc-conversation" +"${genman}" "${dest}/docs/man/man1/" "openim-rpc-friend" +"${genman}" "${dest}/docs/man/man1/" "openim-rpc-group" +"${genman}" "${dest}/docs/man/man1/" "openim-rpc-msg" +"${genman}" "${dest}/docs/man/man1/" "openim-rpc-third" +"${genman}" "${dest}/docs/man/man1/" "openim-rpc-user" + + mkdir -p "${dest}/docs/guide/en-US/yaml/openimctl/" + "${genyaml}" "${dest}/docs/guide/en-US/yaml/openimctl/" + + # create the list of generated files + pushd "${dest}" > /dev/null || return 1 + touch docs/.generated_docs + find . -type f | cut -sd / -f 2- | LC_ALL=C sort > docs/.generated_docs + popd > /dev/null || return 1 +} + +# Removes previously generated docs-- we don't want to check them in. $OPENIM_ROOT +# must be set. +openim::util::remove-gen-docs() { + if [ -e "${OPENIM_ROOT}/docs/.generated_docs" ]; then + # remove all of the old docs; we don't want to check them in. + while read -r file; do + rm "${OPENIM_ROOT}/${file}" 2>/dev/null || true + done <"${OPENIM_ROOT}/docs/.generated_docs" + # The docs/.generated_docs file lists itself, so we don't need to explicitly + # delete it. + fi +} + +# Returns the name of the upstream remote repository name for the local git +# repo, e.g. "upstream" or "origin". +openim::util::git_upstream_remote_name() { + git remote -v | grep fetch |\ + grep -E 'github.com[/:]openimsdk/open-im-server|openim.cc/server' |\ + head -n 1 | awk '{print $1}' +} + +# Exits script if working directory is dirty. If it's run interactively in the terminal +# the user can commit changes in a second terminal. This script will wait. +openim::util::ensure_clean_working_dir() { + while ! git diff HEAD --exit-code &>/dev/null; do + echo -e "\nUnexpected dirty working directory:\n" + if tty -s; then + git status -s + else + git diff -a # be more verbose in log files without tty + exit 1 + fi | sed 's/^/ /' + echo -e "\nCommit your changes in another terminal and then continue here by pressing enter." + read -r + done 1>&2 +} + +# Find the base commit using: +# $PULL_BASE_SHA if set (from Prow) +# current ref from the remote upstream branch +openim::util::base_ref() { + local -r git_branch=$1 + + if [[ -n ${PULL_BASE_SHA:-} ]]; then + echo "${PULL_BASE_SHA}" + return + fi + + full_branch="$(openim::util::git_upstream_remote_name)/${git_branch}" + + # make sure the branch is valid, otherwise the check will pass erroneously. + if ! git describe "${full_branch}" >/dev/null; then + # abort! + exit 1 + fi + + echo "${full_branch}" +} + +# Checks whether there are any files matching pattern $2 changed between the +# current branch and upstream branch named by $1. +# Returns 1 (false) if there are no changes +# 0 (true) if there are changes detected. +openim::util::has_changes() { + local -r git_branch=$1 + local -r pattern=$2 + local -r not_pattern=${3:-totallyimpossiblepattern} + + local base_ref + base_ref=$(openim::util::base_ref "${git_branch}") + echo "Checking for '${pattern}' changes against '${base_ref}'" + + # notice this uses ... to find the first shared ancestor + if git diff --name-only "${base_ref}...HEAD" | grep -v -E "${not_pattern}" | grep "${pattern}" > /dev/null; then + return 0 + fi + # also check for pending changes + if git status --porcelain | grep -v -E "${not_pattern}" | grep "${pattern}" > /dev/null; then + echo "Detected '${pattern}' uncommitted changes." + return 0 + fi + echo "No '${pattern}' changes detected." + return 1 +} + +openim::util::download_file() { + local -r url=$1 + local -r destination_file=$2 + + rm "${destination_file}" 2&> /dev/null || true + + for i in $(seq 5) + do + if ! curl -fsSL --retry 3 --keepalive-time 2 "${url}" -o "${destination_file}"; then + echo "Downloading ${url} failed. $((5-i)) retries left." + sleep 1 + else + echo "Downloading ${url} succeed" + return 0 + fi + done + return 1 +} + +# Test whether openssl is installed. +# Sets: +# OPENSSL_BIN: The path to the openssl binary to use +function openim::util::test_openssl_installed { + if ! openssl version >& /dev/null; then + echo "Failed to run openssl. Please ensure openssl is installed" + exit 1 + fi + + OPENSSL_BIN=$(command -v openssl) +} + +# creates a client CA, args are sudo, dest-dir, ca-id, purpose +# purpose is dropped in after "key encipherment", you usually want +# '"client auth"' +# '"server auth"' +# '"client auth","server auth"' +function openim::util::create_signing_certkey { + local sudo=$1 + local dest_dir=$2 + local id=$3 + local purpose=$4 + # Create client ca + ${sudo} /usr/bin/env bash -e < "${dest_dir}/${id}-ca-config.json" +EOF +} + +# signs a client certificate: args are sudo, dest-dir, CA, filename (roughly), username, groups... +function openim::util::create_client_certkey { + local sudo=$1 + local dest_dir=$2 + local ca=$3 + local id=$4 + local cn=${5:-$4} + local groups="" + local SEP="" + shift 5 + while [ -n "${1:-}" ]; do + groups+="${SEP}{\"O\":\"$1\"}" + SEP="," + shift 1 + done + ${sudo} /usr/bin/env bash -e < /dev/null +apiVersion: v1 +kind: Config +clusters: + - cluster: + certificate-authority: ${ca_file} + server: https://${api_host}:${api_port}/ + name: local-up-cluster +users: + - user: + token: ${token} + client-certificate: ${dest_dir}/client-${client_id}.crt + client-key: ${dest_dir}/client-${client_id}.key + name: local-up-cluster +contexts: + - context: + cluster: local-up-cluster + user: local-up-cluster + name: local-up-cluster +current-context: local-up-cluster +EOF + + # flatten the openimconfig files to make them self contained + username=$(whoami) + ${sudo} /usr/bin/env bash -e < "/tmp/${client_id}.openimconfig" + mv -f "/tmp/${client_id}.openimconfig" "${dest_dir}/${client_id}.openimconfig" + chown ${username} "${dest_dir}/${client_id}.openimconfig" +EOF +} + +# Determines if docker can be run, failures may simply require that the user be added to the docker group. +function openim::util::ensure_docker_daemon_connectivity { + IFS=" " read -ra DOCKER <<< "${DOCKER_OPTS}" + # Expand ${DOCKER[@]} only if it's not unset. This is to work around + # Bash 3 issue with unbound variable. + DOCKER=(docker ${DOCKER[@]:+"${DOCKER[@]}"}) + if ! "${DOCKER[@]}" info > /dev/null 2>&1 ; then + cat <<'EOF' >&2 +Can't connect to 'docker' daemon. please fix and retry. + +Possible causes: + - Docker Daemon not started + - Linux: confirm via your init system + - macOS w/ docker-machine: run `docker-machine ls` and `docker-machine start ` + - macOS w/ Docker for Mac: Check the menu bar and start the Docker application + - DOCKER_HOST hasn't been set or is set incorrectly + - Linux: domain socket is used, DOCKER_* should be unset. In Bash run `unset ${!DOCKER_*}` + - macOS w/ docker-machine: run `eval "$(docker-machine env )"` + - macOS w/ Docker for Mac: domain socket is used, DOCKER_* should be unset. In Bash run `unset ${!DOCKER_*}` + - Other things to check: + - Linux: User isn't in 'docker' group. Add and relogin. + - Something like 'sudo usermod -a -G docker ${USER}' + - RHEL7 bug and workaround: https://bugzilla.redhat.com/show_bug.cgi?id=1119282#c8 +EOF + return 1 + fi +} + +# Wait for background jobs to finish. Return with +# an error status if any of the jobs failed. +openim::util::wait-for-jobs() { + local fail=0 + local job + for job in $(jobs -p); do + wait "${job}" || fail=$((fail + 1)) + done + return ${fail} +} + +# openim::util::join +# Concatenates the list elements with the delimiter passed as first parameter +# +# Ex: openim::util::join , a b c +# -> a,b,c +function openim::util::join { + local IFS="$1" + shift + echo "$*" +} + +# Function: openim::util::list-to-string +# Description: Converts a list to a string, removing spaces, brackets, and commas. +# Example input: [1002 3 , 2 32 3 , 3 434 ,] +# Example output: 10023 2323 3434 +# Example usage: +# result=$(openim::util::list-to-string "[10023, 2323, 3434]") +# echo $result +function openim::util::list-to-string() { + # Capture all arguments into a single string + ports_list="$*" + + # Use sed for transformations: + # 1. Remove spaces + # 2. Replace commas with spaces + # 3. Remove opening and closing brackets + ports_array=$(echo "$ports_list" | sed 's/ //g; s/,/ /g; s/^\[\(.*\)\]$/\1/') + # For external use, we might want to echo the result so that it can be captured by callers + echo "$ports_array" +} +# MSG_GATEWAY_PROM_PORTS=$(openim::util::list-to-string "10023, 2323, 34 34") +# read -a MSG_GATEWAY_PROM_PORTS <<< $(openim::util::list-to-string "10023, 2323, 34 34") +# echo ${MSG_GATEWAY_PROM_PORTS} +# echo "${#MSG_GATEWAY_PROM_PORTS[@]}" +# Downloads cfssl/cfssljson/cfssl-certinfo into $1 directory if they do not already exist in PATH +# +# Assumed vars: +# $1 (cfssl directory) (optional) +# +# Sets: +# CFSSL_BIN: The path of the installed cfssl binary +# CFSSLJSON_BIN: The path of the installed cfssljson binary +# CFSSLCERTINFO_BIN: The path of the installed cfssl-certinfo binary +# +function openim::util::ensure-cfssl { + if command -v cfssl &>/dev/null && command -v cfssljson &>/dev/null && command -v cfssl-certinfo &>/dev/null; then + CFSSL_BIN=$(command -v cfssl) + CFSSLJSON_BIN=$(command -v cfssljson) + CFSSLCERTINFO_BIN=$(command -v cfssl-certinfo) + return 0 + fi + + host_arch=$(openim::util::host_arch) + + if [[ "${host_arch}" != "amd64" ]]; then + echo "Cannot download cfssl on non-amd64 hosts and cfssl does not appear to be installed." + echo "Please install cfssl, cfssljson and cfssl-certinfo and verify they are in \$PATH." + echo "Hint: export PATH=\$PATH:\$GOPATH/bin; go get -u github.com/cloudflare/cfssl/cmd/..." + exit 1 + fi + + # Create a temp dir for cfssl if no directory was given + local cfssldir=${1:-} + if [[ -z "${cfssldir}" ]]; then + cfssldir="$HOME/bin" + fi + + mkdir -p "${cfssldir}" + pushd "${cfssldir}" > /dev/null || return 1 + + echo "Unable to successfully run 'cfssl' from ${PATH}; downloading instead..." + kernel=$(uname -s) + case "${kernel}" in + Linux) + curl --retry 10 -L -o cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 + curl --retry 10 -L -o cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 + curl --retry 10 -L -o cfssl-certinfo https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 + ;; + Darwin) + curl --retry 10 -L -o cfssl https://pkg.cfssl.org/R1.2/cfssl_darwin-amd64 + curl --retry 10 -L -o cfssljson https://pkg.cfssl.org/R1.2/cfssljson_darwin-amd64 + curl --retry 10 -L -o cfssl-certinfo https://pkg.cfssl.org/R1.2/cfssl-certinfo_darwin-amd64 + ;; + *) + echo "Unknown, unsupported platform: ${kernel}." >&2 + echo "Supported platforms: Linux, Darwin." >&2 + exit 2 + esac + + chmod +x cfssl || true + chmod +x cfssljson || true + chmod +x cfssl-certinfo || true + + CFSSL_BIN="${cfssldir}/cfssl" + CFSSLJSON_BIN="${cfssldir}/cfssljson" + CFSSLCERTINFO_BIN="${cfssldir}/cfssl-certinfo" + if [[ ! -x ${CFSSL_BIN} || ! -x ${CFSSLJSON_BIN} || ! -x ${CFSSLCERTINFO_BIN} ]]; then + echo "Failed to download 'cfssl'." + echo "Please install cfssl, cfssljson and cfssl-certinfo and verify they are in \$PATH." + echo "Hint: export PATH=\$PATH:\$GOPATH/bin; go get -u github.com/cloudflare/cfssl/cmd/..." + exit 1 + fi + popd > /dev/null || return 1 +} + +function openim::util::ensure-docker-buildx { + # podman returns 0 on `docker buildx version`, docker on `docker buildx`. One of them must succeed. + if docker buildx version >/dev/null 2>&1 || docker buildx >/dev/null 2>&1; then + return 0 + else + echo "ERROR: docker buildx not available. Docker 19.03 or higher is required with experimental features enabled" + exit 1 + fi +} + +# openim::util::ensure-bash-version +# Check if we are using a supported bash version +# +function openim::util::ensure-bash-version { + # shellcheck disable=SC2004 + if ((${BASH_VERSINFO[0]}<4)) || ( ((${BASH_VERSINFO[0]}==4)) && ((${BASH_VERSINFO[1]}<2)) ); then + echo "ERROR: This script requires a minimum bash version of 4.2, but got version of ${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}" + if [ "$(uname)" = 'Darwin' ]; then + echo "On macOS with homebrew 'brew install bash' is sufficient." + fi + exit 1 + fi +} + +# openim::util::ensure-install-nginx +# Check if nginx is installed +# +function openim::util::ensure-install-nginx { + if ! command -v nginx &>/dev/null; then + echo "ERROR: nginx not found. Please install nginx." + exit 1 + fi + + for port in 80 + do + if echo |telnet 127.0.0.1 $port 2>&1|grep refused &>/dev/null;then + exit 1 + fi + done +} + +# openim::util::ensure-gnu-sed +# Determines which sed binary is gnu-sed on linux/darwin +# +# Sets: +# SED: The name of the gnu-sed binary +# +function openim::util::ensure-gnu-sed { + # NOTE: the echo below is a workaround to ensure sed is executed before the grep. + # see: https://github.com/openimrnetes/openimrnetes/issues/87251 + sed_help="$(LANG=C sed --help 2>&1 || true)" + if echo "${sed_help}" | grep -q "GNU\|BusyBox"; then + SED="sed" + elif command -v gsed &>/dev/null; then + SED="gsed" + else + openim::log::error "Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed." >&2 + return 1 + fi + openim::util::sourced_variable "${SED}" +} + +# openim::util::ensure-gnu-date +# Determines which date binary is gnu-date on linux/darwin +# +# Sets: +# DATE: The name of the gnu-date binary +# +function openim::util::ensure-gnu-date { + # NOTE: the echo below is a workaround to ensure date is executed before the grep. + date_help="$(LANG=C date --help 2>&1 || true)" + if echo "${date_help}" | grep -q "GNU\|BusyBox"; then + DATE="date" + elif command -v gdate &>/dev/null; then + DATE="gdate" + else + openim::log::error "Failed to find GNU date as date or gdate. If you are on Mac: brew install coreutils." >&2 + return 1 + fi + openim::util::sourced_variable "${DATE}" +} + +# openim::util::check-file-in-alphabetical-order +# Check that the file is in alphabetical order +# +function openim::util::check-file-in-alphabetical-order { + local failure_file="$1" + if ! diff -u "${failure_file}" <(LC_ALL=C sort "${failure_file}"); then + { + echo + echo "${failure_file} is not in alphabetical order. Please sort it:" + echo + echo " LC_ALL=C sort -o ${failure_file} ${failure_file}" + echo + } >&2 + false + fi +} + +# openim::util::require-jq +# Checks whether jq is installed. +function openim::util::require-jq { + if ! command -v jq &>/dev/null; then + openim::log::errexit "jq not found. Please install." 1>&2 + fi +} + +# openim::util::require-dig +# Checks whether dig is installed and provides installation instructions if it is not. +function openim::util::require-dig { + if ! command -v dig &>/dev/null; then + openim::log::error "Please install 'dig' to use this feature. OR Set the environment variable for OPENIM_IP" + openim::log::error "Installation instructions:" + openim::log::error " For Ubuntu/Debian: sudo apt-get install dnsutils" + openim::log::error " For CentOS/RedHat: sudo yum install bind-utils" + openim::log::error " For macOS: 'dig' should be preinstalled. If missing, try: brew install bind" + openim::log::error " For Windows: Install BIND9 tools from https://www.isc.org/download/" + openim::log::error_exit "dig command not found." + fi + return 0 +} + +# outputs md5 hash of $1, works on macOS and Linux +function openim::util::md5() { + if which md5 >/dev/null 2>&1; then + md5 -q "$1" + else + md5sum "$1" | awk '{ print $1 }' + fi +} + +# openim::util::read-array +# Reads in stdin and adds it line by line to the array provided. This can be +# used instead of "mapfile -t", and is bash 3 compatible. +# +# Assumed vars: +# $1 (name of array to create/modify) +# +# Example usage: +# openim::util::read-array files < <(ls -1) +# +function openim::util::read-array { + local i=0 + unset -v "$1" + while IFS= read -r "$1[i++]"; do :; done + eval "[[ \${$1[--i]} ]]" || unset "$1[i]" # ensures last element isn't empty +} + +# Some useful colors. +if [[ -z "${color_start-}" ]]; then + declare -r color_start="\033[" + declare -r color_red="${color_start}0;31m" + declare -r color_yellow="${color_start}0;33m" + declare -r color_green="${color_start}0;32m" + declare -r color_blue="${color_start}1;34m" + declare -r color_cyan="${color_start}1;36m" + declare -r color_norm="${color_start}0m" + + openim::util::sourced_variable "${color_start}" + openim::util::sourced_variable "${color_red}" + openim::util::sourced_variable "${color_yellow}" + openim::util::sourced_variable "${color_green}" + openim::util::sourced_variable "${color_blue}" + openim::util::sourced_variable "${color_cyan}" + openim::util::sourced_variable "${color_norm}" +fi + +# ex: ts=2 sw=2 et filetype=sh + +function openim::util::desc() { + openim::util:run::maybe_first_prompt + rate=25 + if [ -n "$DEMO_RUN_FAST" ]; then + rate=1000 + fi + echo "$blue# $@$reset" | pv -qL $rate#!/usr/bin/env bash +# Copyright © 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this script is used to check whether the code is formatted by gofmt or not +# +# Usage: source scripts/lib/util.sh +################################################################################ + +# TODO Debug: Just for testing, please comment out +# OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +# source "${OPENIM_ROOT}/scripts/lib/logging.sh" + +#1、将IP写在一个文件里,比如文件名为hosts_file,一行一个IP地址。 +#2、修改ssh-mutual-trust.sh里面的用户名及密码,默认为root用户及密码123。 +# hosts_file_path="path/to/your/hosts/file" +# openim:util::setup_ssh_key_copy "$hosts_file_path" "root" "123" +function openim:util::setup_ssh_key_copy() { + local hosts_file="$1" + local username="${2:-root}" + local password="${3:-123}" + + local sshkey_file=~/.ssh/id_rsa.pub + + # check sshkey file + if [[ ! -e $sshkey_file ]]; then + expect -c " + spawn ssh-keygen -t rsa + expect \"Enter*\" { send \"\n\"; exp_continue; } + " + fi + + # get hosts list + local hosts=$(awk '/^[^#]/ {print $1}' "${hosts_file}") + + ssh_key_copy() { + local target=$1 + + # delete history + sed -i "/$target/d" ~/.ssh/known_hosts + + # copy key + expect -c " + set timeout 100 + spawn ssh-copy-id $username@$target + expect { + \"yes/no\" { send \"yes\n\"; exp_continue; } + \"*assword\" { send \"$password\n\"; } + \"already exist on the remote system\" { exit 1; } + } + expect eof + " + } + + # auto sshkey pair + for host in $hosts; do + if ! ping -i 0.2 -c 3 -W 1 "$host" > /dev/null 2>&1; then + echo "[ERROR]: Can't connect $host" + continue + fi + + local host_entry=$(awk "/$host/"'{print $1, $2}' /etc/hosts) + if [[ $host_entry ]]; then + local hostaddr=$(echo "$host_entry" | awk '{print $1}') + local hostname=$(echo "$host_entry" | awk '{print $2}') + ssh_key_copy "$hostaddr" + ssh_key_copy "$hostname" + else + ssh_key_copy "$host" + fi + done +} + +function openim::util::sourced_variable { + # Call this function to tell shellcheck that a variable is supposed to + # be used from other calling context. This helps quiet an "unused + # variable" warning from shellcheck and also document your code. + true +} + +openim::util::sortable_date() { + date "+%Y%m%d-%H%M%S" +} + +# arguments: target, item1, item2, item3, ... +# returns 0 if target is in the given items, 1 otherwise. +openim::util::array_contains() { + local search="$1" + local element + shift + for element; do + if [[ "${element}" == "${search}" ]]; then + return 0 + fi + done + return 1 +} + +openim::util::wait_for_url() { + local url=$1 + local prefix=${2:-} + local wait=${3:-1} + local times=${4:-30} + local maxtime=${5:-1} + + command -v curl >/dev/null || { + openim::log::usage "curl must be installed" + exit 1 + } + + local i + for i in $(seq 1 "${times}"); do + local out + if out=$(curl --max-time "${maxtime}" -gkfs "${url}" 2>/dev/null); then + openim::log::status "On try ${i}, ${prefix}: ${out}" + return 0 + fi + sleep "${wait}" + done + openim::log::error "Timed out waiting for ${prefix} to answer at ${url}; tried ${times} waiting ${wait} between each" + return 1 +} + +# Example: openim::util::wait_for_success 120 5 "openimctl get nodes|grep localhost" +# arguments: wait time, sleep time, shell command +# returns 0 if the shell command get output, 1 otherwise. +openim::util::wait_for_success(){ + local wait_time="$1" + local sleep_time="$2" + local cmd="$3" + while [ "$wait_time" -gt 0 ]; do + if eval "$cmd"; then + return 0 + else + sleep "$sleep_time" + wait_time=$((wait_time-sleep_time)) + fi + done + return 1 +} + +# Example: openim::util::trap_add 'echo "in trap DEBUG"' DEBUG +# See: http://stackoverflow.com/questions/3338030/multiple-bash-traps-for-the-same-signal +openim::util::trap_add() { + local trap_add_cmd + trap_add_cmd=$1 + shift + + for trap_add_name in "$@"; do + local existing_cmd + local new_cmd + + # Grab the currently defined trap commands for this trap + existing_cmd=$(trap -p "${trap_add_name}" | awk -F"'" '{print $2}') + + if [[ -z "${existing_cmd}" ]]; then + new_cmd="${trap_add_cmd}" + else + new_cmd="${trap_add_cmd};${existing_cmd}" + fi + + # Assign the test. Disable the shellcheck warning telling that trap + # commands should be single quoted to avoid evaluating them at this + # point instead evaluating them at run time. The logic of adding new + # commands to a single trap requires them to be evaluated right away. + # shellcheck disable=SC2064 + trap "${new_cmd}" "${trap_add_name}" + done +} + +# Opposite of openim::util::ensure-temp-dir() +openim::util::cleanup-temp-dir() { + rm -rf "${OPENIM_TEMP}" +} + +# Create a temp dir that'll be deleted at the end of this bash session. +# +# Vars set: +# OPENIM_TEMP +openim::util::ensure-temp-dir() { + if [[ -z ${OPENIM_TEMP-} ]]; then + OPENIM_TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t openimrnetes.XXXXXX) + openim::util::trap_add openim::util::cleanup-temp-dir EXIT + fi +} + +openim::util::host_os() { + local host_os + case "$(uname -s)" in + Darwin) + host_os=darwin + ;; + Linux) + host_os=linux + ;; + *) + openim::log::error "Unsupported host OS. Must be Linux or Mac OS X." + exit 1 + ;; + esac + echo "${host_os}" +} + +openim::util::host_arch() { + local host_arch + case "$(uname -m)" in + x86_64*) + host_arch=amd64 + ;; + i?86_64*) + host_arch=amd64 + ;; + amd64*) + host_arch=amd64 + ;; + aarch64*) + host_arch=arm64 + ;; + arm64*) + host_arch=arm64 + ;; + arm*) + host_arch=arm + ;; + i?86*) + host_arch=x86 + ;; + s390x*) + host_arch=s390x + ;; + ppc64le*) + host_arch=ppc64le + ;; + *) + openim::log::error "Unsupported host arch. Must be x86_64, 386, arm, arm64, s390x or ppc64le." + exit 1 + ;; + esac + echo "${host_arch}" +} + +# Define a bash function to check the versions of Docker and Docker Compose +openim::util::check_docker_and_compose_versions() { + # Define the required versions of Docker and Docker Compose + required_docker_version="20.10.0" + required_compose_version="2.0" + + # Get the currently installed Docker version + installed_docker_version=$(docker --version | awk '{print $3}' | sed 's/,//') + + # Check if the installed Docker version matches the required version + if [[ "$installed_docker_version" < "$required_docker_version" ]]; then + echo "Docker version mismatch. Installed: $installed_docker_version, Required: $required_docker_version" + return 1 + fi + + # Check if the docker compose sub-command is available + if ! docker compose version &> /dev/null; then + echo "Docker does not support the docker compose sub-command" + echo "You need to upgrade Docker to the right version" + return 1 + fi + + # Get the currently installed Docker Compose version + installed_compose_version=$(docker compose version --short) + + # Check if the installed Docker Compose version matches the required version + if [[ "$installed_compose_version" < "$required_compose_version" ]]; then + echo "Docker Compose version mismatch. Installed: $installed_compose_version, Required: $required_compose_version" + return 1 + fi + +} + + +# The `openim::util::check_ports` function analyzes the state of processes based on given ports. +# It accepts multiple ports as arguments and prints: +# 1. The state of the process (whether it's running or not). +# 2. The start time of the process if it's running. +# User: +# openim::util::check_ports 8080 8081 8082 +# The function returns a status of 1 if any of the processes is not running. +openim::util::check_ports() { + # An array to collect ports of processes that are not running. + local not_started=() + + # An array to collect information about processes that are running. + local started=() + + openim::log::info "Checking ports: $*" + # Iterate over each given port. + for port in "$@"; do + # Initialize variables + # Check the OS and use the appropriate command + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + if command -v ss > /dev/null 2>&1; then + info=$(ss -ltnp | grep ":$port" || true) + echo "!!!!!!!!!!! port=$port" + echo "!!!!!!!!!!! info=$info" + else + info=$(netstat -ltnp | grep ":$port" || true) + echo "!!!!!!!!!!! port=$port" + echo "!!!!!!!!!!! info=$info" + fi + elif [[ "$OSTYPE" == "darwin"* ]]; then + # For macOS, use lsof + info=$(lsof -i:"$port" | grep "\*:$port" || true) fi - # If there's no process information, it means the process associated with the port is not running. + # Check if any process is using the port if [[ -z $info ]]; then not_started+=($port) else - # Extract relevant details: Process Name, PID, and FD. - local details=$(echo $info | sed -n 's/.*users:(("\([^"]*\)",pid=\([^,]*\),fd=\([^)]*\))).*/\1 \2 \3/p') - local command=$(echo $details | awk '{print $1}') - local pid=$(echo $details | awk '{print $2}') - local fd=$(echo $details | awk '{print $3}') - + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + # Extract relevant details for Linux: Process Name, PID, and FD. + details=$(echo $info | sed -n 's/.*users:(("\([^"]*\)",pid=\([^,]*\),fd=\([^)]*\))).*/\1 \2 \3/p') + command=$(echo $details | awk '{print $1}') + pid=$(echo $details | awk '{print $2}') + fd=$(echo $details | awk '{print $3}') + elif [[ "$OSTYPE" == "darwin"* ]]; then + # Handle extraction for macOS + pid=$(echo $info | awk '{print $2}' | cut -d'/' -f1) + command=$(ps -p $pid -o comm= | xargs basename) + fd=$(echo $info | awk '{print $4}' | cut -d'/' -f1) + fi + # Get the start time of the process using the PID if [[ -z $pid ]]; then - local start_time="N/A" + start_time="N/A" else - # Get the start time of the process using the PID - local start_time=$(ps -p $pid -o lstart=) + start_time=$(ps -p $pid -o lstart=) fi started+=("Port $port - Command: $command, PID: $pid, FD: $fd, Started: $start_time") @@ -355,6 +1601,7 @@ openim::util::check_ports() { return 0 fi } + # set +o errexit # Sample call for testing: # openim::util::check_ports 10002 1004 12345 13306 @@ -371,12 +1618,15 @@ openim::util::check_process_names() { # Function to get the port of a process get_port() { local pid=$1 - if command -v ss > /dev/null 2>&1; then - # used ss comment + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + # Linux ss -ltnp 2>/dev/null | grep $pid | awk '{print $4}' | cut -d ':' -f2 + elif [[ "$OSTYPE" == "darwin"* ]]; then + # macOS + lsof -nP -iTCP -sTCP:LISTEN -a -p $pid | awk 'NR>1 {print $9}' | sed 's/.*://' else - # used netstat comment replace ss - netstat -ltnp 2>/dev/null | grep $pid | awk '{print $4}' | sed 's/.*://' + echo "Unsupported OS" + return 1 fi } @@ -457,7 +1707,7 @@ openim::util::stop_services_on_ports() { for port in "$@"; do # Use the `lsof` command to find process information related to the given port. info=$(lsof -i :$port -n -P | grep LISTEN || true) - + # If there's process information, it means the process associated with the port is running. if [[ -n $info ]]; then # Extract the Process ID. @@ -496,6 +1746,7 @@ openim::util::stop_services_on_ports() { return 1 else openim::log::success "All specified services were stopped." + echo "" return 0 fi } @@ -572,6 +1823,7 @@ openim::util::stop_services_with_name() { fi openim::log::success "All specified services were stopped." + echo "" } # sleep 333333& # sleep 444444& @@ -591,11 +1843,11 @@ openim::util::find-binary-for-platform() { local -r lookfor="$1" local -r platform="$2" local locations=( - ""${OPENIM_ROOT}"/_output/bin/${lookfor}" - ""${OPENIM_ROOT}"/_output/${platform}/${lookfor}" - ""${OPENIM_ROOT}"/_output/local/bin/${platform}/${lookfor}" - ""${OPENIM_ROOT}"/_output/platforms/${platform}/${lookfor}" - ""${OPENIM_ROOT}"/_output/platforms/bin/${platform}/${lookfor}" + "${OPENIM_ROOT}/_output/bin/${lookfor}" + "${OPENIM_ROOT}/_output/${platform}/${lookfor}" + "${OPENIM_ROOT}/_output/local/bin/${platform}/${lookfor}" + "${OPENIM_ROOT}/_output/platforms/${platform}/${lookfor}" + "${OPENIM_ROOT}/_output/platforms/bin/${platform}/${lookfor}" ) # List most recently-updated location. @@ -672,11 +1924,11 @@ openim::util::gen-docs() { # Removes previously generated docs-- we don't want to check them in. $OPENIM_ROOT # must be set. openim::util::remove-gen-docs() { - if [ -e ""${OPENIM_ROOT}"/docs/.generated_docs" ]; then + if [ -e "${OPENIM_ROOT}/docs/.generated_docs" ]; then # remove all of the old docs; we don't want to check them in. while read -r file; do - rm ""${OPENIM_ROOT}"/${file}" 2>/dev/null || true - done <""${OPENIM_ROOT}"/docs/.generated_docs" + rm "${OPENIM_ROOT}/${file}" 2>/dev/null || true + done <"${OPENIM_ROOT}/docs/.generated_docs" # The docs/.generated_docs file lists itself, so we don't need to explicitly # delete it. fi @@ -1146,8 +2398,13 @@ function openim::util::require-jq { # Checks whether dig is installed and provides installation instructions if it is not. function openim::util::require-dig { if ! command -v dig &>/dev/null; then - openim::log::error "dig command not found." - return 1 + openim::log::error "Please install 'dig' to use this feature. OR Set the environment variable for OPENIM_IP" + openim::log::error "Installation instructions:" + openim::log::error " For Ubuntu/Debian: sudo apt-get install dnsutils" + openim::log::error " For CentOS/RedHat: sudo yum install bind-utils" + openim::log::error " For macOS: 'dig' should be preinstalled. If missing, try: brew install bind" + openim::log::error " For Windows: Install BIND9 tools from https://www.isc.org/download/" + openim::log::error_exit "dig command not found." fi return 0 } @@ -1384,4 +2641,184 @@ function openim::util::gen_os_arch() { if [[ "$*" =~ openim::util:: ]];then eval $* -fi \ No newline at end of file +fi + + openim::util:run::prompt +} + +function openim::util:run::prompt() { + echo -n "$yellow\$ $reset" +} + +started="" +function openim::util:run::maybe_first_prompt() { + if [ -z "$started" ]; then + openim::util:run::prompt + started=true + fi +} + +# After a `run` this variable will hold the stdout of the command that was run. +# If the command was interactive, this will likely be garbage. +DEMO_RUN_STDOUT="" + +function openim::util::run() { + openim::util:run::maybe_first_prompt + rate=25 + if [ -n "$DEMO_RUN_FAST" ]; then + rate=1000 + fi + echo "$green$1$reset" | pv -qL $rate + if [ -n "$DEMO_RUN_FAST" ]; then + sleep 0.5 + fi + OFILE="$(mktemp -t $(basename $0).XXXXXX)" + if [ "$(uname)" == "Darwin" ]; then + script -q "$OFILE" $1 + else + script -eq -c "$1" -f "$OFILE" + fi + r=$? + read -d '' -t "${timeout}" -n 10000 # clear stdin + openim::util:run::prompt + if [ -z "$DEMO_AUTO_RUN" ]; then + read -s + fi + DEMO_RUN_STDOUT="$(tail -n +2 $OFILE | sed 's/\r//g')" + return $r +} + +function openim::util::run::relative() { + for arg; do + echo "$(realpath $(dirname $(which $0)))/$arg" | sed "s|$(realpath $(pwd))|.|" + done +} + +# This function retrieves the IP address of the current server. +# It primarily uses the `curl` command to fetch the public IP address from ifconfig.me. +# If curl or the service is not available, it falls back +# to the internal IP address provided by the hostname command. +# TODO: If a delay is found, the delay needs to be addressed +function openim::util::get_server_ip() { + # Check if the 'curl' command is available + if command -v curl &> /dev/null; then + # Try to retrieve the public IP address using curl and ifconfig.me + IP=$(dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | sed 's/"//g' | tr -d '\n') + + # Check if IP retrieval was successful + if [[ -z "$IP" ]]; then + # If not, get the internal IP address + IP=$(ip addr show | grep 'inet ' | grep -v 127.0.0.1 | awk '{print $2}' | cut -d'/' -f1 | head -n 1) + fi + else + # If curl is not available, get the internal IP address + IP=$(ip addr show | grep 'inet ' | grep -v 127.0.0.1 | awk '{print $2}' | cut -d'/' -f1 | head -n 1) + fi + + # Return the fetched IP address + echo "$IP" +} + +function openim::util::onCtrlC() { + echo -e "\n${t_reset}Ctrl+C Press it. It's exiting openim make init..." + exit 1 +} + +# Function Function: Remove Spaces in the string +function openim::util::remove_space() { + value=$* # 获取传入的参数 + result=$(echo $value | sed 's/ //g') # 去除空格 +} + +function openim::util::gencpu() { + # Check the system type + system_type=$(uname) + + if [[ "$system_type" == "Darwin" ]]; then + # macOS (using sysctl) + cpu_count=$(sysctl -n hw.ncpu) + elif [[ "$system_type" == "Linux" ]]; then + # Linux (using lscpu) + cpu_count=$(lscpu --parse | grep -E '^([^#].*,){3}[^#]' | sort -u | wc -l) + else + echo "Unsupported operating system: $system_type" + exit 1 + fi + echo $cpu_count +} + +function openim::util::set_max_fd() { + local desired_fd=$1 + local max_fd_limit + + # Check if we're not on cygwin or darwin. + if [ "$(uname -s | tr '[:upper:]' '[:lower:]')" != "cygwin" ] && [ "$(uname -s | tr '[:upper:]' '[:lower:]')" != "darwin" ]; then + # Try to get the hard limit. + max_fd_limit=$(ulimit -H -n) + if [ $? -eq 0 ]; then + # If desired_fd is 'maximum' or 'max', set it to the hard limit. + if [ "$desired_fd" = "maximum" ] || [ "$desired_fd" = "max" ]; then + desired_fd="$max_fd_limit" + fi + + # Check if desired_fd is less than or equal to max_fd_limit. + if [ "$desired_fd" -le "$max_fd_limit" ]; then + ulimit -n "$desired_fd" + if [ $? -ne 0 ]; then + echo "Warning: Could not set maximum file descriptor limit to $desired_fd" + fi + else + echo "Warning: Desired file descriptor limit ($desired_fd) is greater than the hard limit ($max_fd_limit)" + fi + else + echo "Warning: Could not query the maximum file descriptor hard limit." + fi + else + echo "Warning: Not attempting to modify file descriptor limit on Cygwin or Darwin." + fi +} + + +function openim::util::gen_os_arch() { + # Get the current operating system and architecture + OS=$(uname -s | tr '[:upper:]' '[:lower:]') + ARCH=$(uname -m) + + # Select the repository home directory based on the operating system and architecture + if [[ "$OS" == "darwin" ]]; then + if [[ "$ARCH" == "x86_64" ]]; then + REPO_DIR="darwin/amd64" + else + REPO_DIR="darwin/386" + fi + elif [[ "$OS" == "linux" ]]; then + if [[ "$ARCH" == "x86_64" ]]; then + REPO_DIR="linux/amd64" + elif [[ "$ARCH" == "arm64" ]]; then + REPO_DIR="linux/arm64" + elif [[ "$ARCH" == "mips64" ]]; then + REPO_DIR="linux/mips64" + elif [[ "$ARCH" == "mips64le" ]]; then + REPO_DIR="linux/mips64le" + elif [[ "$ARCH" == "ppc64le" ]]; then + REPO_DIR="linux/ppc64le" + elif [[ "$ARCH" == "s390x" ]]; then + REPO_DIR="linux/s390x" + else + REPO_DIR="linux/386" + fi + elif [[ "$OS" == "windows" ]]; then + if [[ "$ARCH" == "x86_64" ]]; then + REPO_DIR="windows/amd64" + else + REPO_DIR="windows/386" + fi + else + echo -e "${RED_PREFIX}Unsupported OS: $OS${COLOR_SUFFIX}" + exit 1 + fi +} + +if [[ "$*" =~ openim::util:: ]];then + eval $* +fi diff --git a/scripts/release.sh b/scripts/release.sh index 9e1f99bc4..042a6c3a0 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -13,27 +13,138 @@ # See the License for the specific language governing permissions and # limitations under the License. - +# Description: +# This script automates the process of building and releasing OpenIM, +# including tasks like setting up the environment, verifying prerequisites, +# building commands, packaging tarballs, uploading tarballs, creating GitHub +# releases, and generating changelogs. +# +# Usage: +# ./scripts/release.sh [options] +# Options include: +# -h, --help : Show help message +# -se, --setup-env : Execute setup environment +# -vp, --verify-prereqs : Execute prerequisites verification +# -bc, --build-command : Execute build command +# -bi, --build-image : Execute build image (default: not executed) +# -pt, --package-tarballs : Execute package tarballs +# -ut, --upload-tarballs : Execute upload tarballs +# -gr, --github-release : Execute GitHub release +# -gc, --generate-changelog: Execute generate changelog +# +# This script can also be executed via the 'make release' command as an alternative. +# +# Dependencies: +# This script depends on external scripts found in the 'scripts' directory and +# assumes the presence of necessary tools and permissions for building and +# releasing software. +# +# Note: +# The script uses standard bash script practices with error handling, +# and it defaults to executing all steps if no specific option is provided. +# # Build a OpenIM release. This will build the binaries, create the Docker # images and other build artifacts. +# Build a OpenIM release. This script supports various flags for flexible execution control. set -o errexit set -o nounset set -o pipefail - OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. source "${OPENIM_ROOT}/scripts/common.sh" source "${OPENIM_ROOT}/scripts/lib/release.sh" OPENIM_RELEASE_RUN_TESTS=${OPENIM_RELEASE_RUN_TESTS-y} -openim::golang::setup_env -openim::build::verify_prereqs -openim::release::verify_prereqs -#openim::build::build_image -openim::build::build_command -openim::release::package_tarballs -openim::release::updload_tarballs -git push origin ${VERSION} -#openim::release::github_release -#openim::release::generate_changelog +# Function to show help message +show_help() { + echo "Usage: $(basename $0) [options]" + echo "Options:" + echo " -h, --help Show this help message" + echo " -se, --setup-env Execute setup environment" + echo " -vp, --verify-prereqs Execute prerequisites verification" + echo " -bc, --build-command Execute build command" + echo " -bi, --build-image Execute build image (default: not executed)" + echo " -pt, --package-tarballs Execute package tarballs" + echo " -ut, --upload-tarballs Execute upload tarballs" + echo " -gr, --github-release Execute GitHub release" + echo " -gc, --generate-changelog Execute generate changelog" +} + +# Initialize all actions to false +perform_setup_env=false +perform_verify_prereqs=false +perform_build_command=false +perform_build_image=false # New flag for build image +perform_package_tarballs=false +perform_upload_tarballs=false +perform_github_release=false +perform_generate_changelog=false + +# Process command-line arguments +while getopts "hsevpbciptutgrgc-" opt; do + case "${opt}" in + h) show_help; exit 0 ;; + se) perform_setup_env=true ;; + vp) perform_verify_prereqs=true ;; + bc) perform_build_command=true ;; + bi) perform_build_image=true ;; # Handling new option + pt) perform_package_tarballs=true ;; + ut) perform_upload_tarballs=true ;; + gr) perform_github_release=true ;; + gc) perform_generate_changelog=true ;; + --) case "${OPTARG}" in + help) show_help; exit 0 ;; + setup-env) perform_setup_env=true ;; + verify-prereqs) perform_verify_prereqs=true ;; + build-command) perform_build_command=true ;; + build-image) perform_build_image=true ;; # Handling new long option + package-tarballs) perform_package_tarballs=true ;; + upload-tarballs) perform_upload_tarballs=true ;; + github-release) perform_github_release=true ;; + generate-changelog) perform_generate_changelog=true ;; + *) echo "Invalid option: --${OPTARG}"; show_help; exit 1 ;; + esac ;; + *) show_help; exit 1 ;; + esac +done + +# Enable all actions by default if no options are provided +if [ "$#" -eq 0 ]; then + perform_setup_env=true + perform_verify_prereqs=true + perform_build_command=true + perform_package_tarballs=true + perform_upload_tarballs=true + perform_github_release=true + perform_generate_changelog=true + # TODO: Not enabling build_image by default + # perform_build_image=true +fi + +# Function to perform actions +perform_action() { + local flag=$1 + local message=$2 + local command=$3 + + if [ "$flag" == true ]; then + openim::log::info "## $message..." + if ! $command; then + openim::log::errexit "Error in $message" + fi + fi +} + +echo "Starting script execution..." + +perform_action $perform_setup_env "Setting up environment" "openim::golang::setup_env" +perform_action $perform_verify_prereqs "Verifying prerequisites" "openim::build::verify_prereqs && openim::release::verify_prereqs" +perform_action $perform_build_command "Executing build command" "openim::build::build_command" +perform_action $perform_build_image "Building image" "openim::build::build_image" +perform_action $perform_package_tarballs "Packaging tarballs" "openim::release::package_tarballs" +perform_action $perform_upload_tarballs "Uploading tarballs" "openim::release::upload_tarballs" +perform_action $perform_github_release "Creating GitHub release" "openim::release::github_release" +perform_action $perform_generate_changelog "Generating changelog" "openim::release::generate_changelog" + +openim::log::success "OpenIM Relase Script Execution Completed." diff --git a/tools/component/component.go b/tools/component/component.go index 62f2c60ac..220b845ee 100644 --- a/tools/component/component.go +++ b/tools/component/component.go @@ -33,19 +33,20 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/minio/minio-go/v7/pkg/credentials" "github.com/minio/minio-go/v7" - "github.com/redis/go-redis/v9" - "gopkg.in/yaml.v3" + "github.com/minio/minio-go/v7/pkg/credentials" + "github.com/redis/go-redis/v9" + "gopkg.in/yaml.v3" ) const ( // defaultCfgPath is the default path of the configuration file. defaultCfgPath = "../../../../../config/config.yaml" minioHealthCheckDuration = 1 - maxRetry = 100 + maxRetry = 300 componentStartErrCode = 6000 configErrCode = 6001 + mongoConnTimeout = 30 * time.Second ) const ( @@ -55,8 +56,7 @@ const ( ) var ( - cfgPath = flag.String("c", defaultCfgPath, "Path to the configuration file") - + cfgPath = flag.String("c", defaultCfgPath, "Path to the configuration file") ErrComponentStart = errs.NewCodeError(componentStartErrCode, "ComponentStartErr") ErrConfig = errs.NewCodeError(configErrCode, "Config file is incorrect") ) @@ -95,7 +95,7 @@ func main() { for i := 0; i < maxRetry; i++ { if i != 0 { - time.Sleep(3 * time.Second) + time.Sleep(1 * time.Second) } fmt.Printf("Checking components Round %v...\n", i+1) @@ -141,19 +141,25 @@ func getEnv(key, fallback string) string { return fallback } -// checkMongo checks the MongoDB connection +// checkMongo checks the MongoDB connection without retries func checkMongo() (string, error) { - // Use environment variables or fallback to config uri := getEnv("MONGO_URI", buildMongoURI()) - client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri)) + ctx, cancel := context.WithTimeout(context.Background(), mongoConnTimeout) + defer cancel() + str := "ths addr is:" + strings.Join(config.Config.Mongo.Address, ",") + + client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri)) if err != nil { return "", errs.Wrap(errStr(err, str)) } - defer client.Disconnect(context.TODO()) + defer client.Disconnect(context.Background()) + + ctx, cancel = context.WithTimeout(context.Background(), mongoConnTimeout) + defer cancel() - if err = client.Ping(context.TODO(), nil); err != nil { + if err = client.Ping(ctx, nil); err != nil { return "", errs.Wrap(errStr(err, str)) } @@ -222,8 +228,8 @@ func checkMinio() (string, error) { defer cancel() if minioClient.IsOffline() { - // str := fmt.Sprintf("Minio server is offline;%s", str) - // return "", ErrComponentStart.Wrap(str) + str := fmt.Sprintf("Minio server is offline;%s", str) + return "", ErrComponentStart.Wrap(str) } // Check for localhost in API URL and Minio SignEndpoint