Compare commits

...

22 Commits
main ... v3.7.1

Author SHA1 Message Date
chao
b1c1ab0e06
Merge pull request #2304 from withchao/release-v3.7
fix: s3 config
2024-05-15 11:36:12 +08:00
withchao
4265f99a7e kafka 2024-05-15 11:34:37 +08:00
withchao
bb6b2ec542 fix: oss panic 2024-05-15 11:34:32 +08:00
withchao
7b9c729b40 Merge remote-tracking branch 'upstream/release-v3.7' into release-v3.7 2024-05-14 15:49:33 +08:00
withchao
0d1eea3cdb fix: s3 config 2024-05-14 15:47:33 +08:00
chao
fcfc7da4d0
fix: SearchMessage (#2289) 2024-05-08 19:38:08 +08:00
withchao
bff1266315 fix: SearchMessage 2024-05-08 16:25:09 +08:00
skiffer-git
fe399d72f2
update gomake (#2285) 2024-05-08 15:08:25 +08:00
skiffer-git
d57fd8fdd1
Skip minio check (#2279)
* If MinIO is not being used, then do not perform the MinIO check.

* If MinIO is not being used, then do not perform the MinIO check.

* If MinIO is not being used, then do not perform the MinIO check.

* If MinIO is not being used, then do not perform the MinIO check.

* kill binary before build

* Stop the process before compiling.

* Stop the process before compiling.
2024-05-07 21:03:17 +08:00
chao
eb4698a44e
Merge pull request #2264 from withchao/release-v3.7
fix: minio config url recognition error
2024-04-29 16:09:13 +08:00
withchao
bbd9ff9ef4 fix: minio config url recognition error
(cherry picked from commit 480ccc70b0512219f98913ac02550f3a77586254)
2024-04-29 15:16:04 +08:00
chao
d697eaca0e
feat: optimize corn tasks (#2238)
* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* cicd: robot automated Change

* fix: component

* fix: getConversationInfo

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* fix bug: get localIP

* update some ci file (#2200)

* Update openimci.yml

* Update golangci-lint.yml

* Update e2e-test.yml

* 3.6.1 code conventions (#2202)

* refactor: webhooks update.

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* feat: s3 api addr

* refactor: webhooks update.

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* refactor: webhooks update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* refactor: kafka update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Windows can compile and run.

* Windows can compile and run.

* refactor: kafka update.

* feat: msg cache split

* refactor: webhooks update

* refactor: webhooks update

* refactor: friends update

* refactor: group update

* refactor: third update

* refactor: api update

* refactor: crontab update

* refactor: msggateway update

* mage

* mage

* refactor: all module update.

* check

* refactor: all module update.

* load config

* load config

* load config

* load config

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update tools

* update tools

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update protocol

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: api remove token auth by redis directly.

* Code Refactoring

* refactor: websocket auth change to call rpc of auth.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: remove msggateway redis.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* fix: runtime: goroutine stack exceeds

* refactor: cmd update.

* refactor notification

* refactor notification

* refactor

* refactor: cmd update.

* refactor: cmd update.

* refactor

* refactor

* refactor

* protojson

* protojson

* protojson

* go mod

* wrapperspb

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: context update.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: api name change.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: update file

* refactor

* refactor

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: callback update.

* fix: callback update.

* refactor

* fix: update message.

* fix: msg cache timeout.

* refactor

* refactor

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* refactor

* refactor

* fix: push update.

* fix: websocket handle error remove when upgrade error.

* fix: priority url

* fix: minio config

* refactor: add zk logger.

* refactor

* fix: minio config

* refactor

* refactor

* refactor

* refactor

* refactor: remove zk logger.

* refactor: update tools version.

* refactor

* refactor: update server version to 3.7.0.

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor

* refactor

* refactor

* refactor: log level change.

* refactor: 3.7.0 code conventions.

---------

Co-authored-by: skiffer-git <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>

* Update action (#2211)

* Rename golangci-lint.yml to golangci-lint.bak

* Update e2e-test.yml

* Update openimci.yml

* Update action (#2213)

* Rename golangci-lint.yml to golangci-lint.bak

* Update e2e-test.yml

* Update openimci.yml

* Rename docker-buildx.yml to docker-buildx.bak

* update go.mod go.sum (#2210)

* 3.6.1 code conventions (#2203)

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* refactor: webhooks update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* refactor: kafka update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Windows can compile and run.

* Windows can compile and run.

* refactor: kafka update.

* feat: msg cache split

* refactor: webhooks update

* refactor: webhooks update

* refactor: friends update

* refactor: group update

* refactor: third update

* refactor: api update

* refactor: crontab update

* refactor: msggateway update

* mage

* mage

* refactor: all module update.

* check

* refactor: all module update.

* load config

* load config

* load config

* load config

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update tools

* update tools

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update protocol

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: api remove token auth by redis directly.

* Code Refactoring

* refactor: websocket auth change to call rpc of auth.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: remove msggateway redis.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* fix: runtime: goroutine stack exceeds

* refactor: cmd update.

* refactor notification

* refactor notification

* refactor

* refactor: cmd update.

* refactor: cmd update.

* refactor

* refactor

* refactor

* protojson

* protojson

* protojson

* go mod

* wrapperspb

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: context update.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: api name change.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: update file

* refactor

* refactor

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: callback update.

* fix: callback update.

* refactor

* fix: update message.

* fix: msg cache timeout.

* refactor

* refactor

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* refactor

* refactor

* fix: push update.

* fix: websocket handle error remove when upgrade error.

* fix: priority url

* fix: minio config

* refactor: add zk logger.

* refactor

* fix: minio config

* refactor

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* fix bug: get localIP

* refactor

* refactor

* refactor

* refactor: remove zk logger.

* refactor: update tools version.

* refactor

* refactor: update server version to 3.7.0.

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor

* refactor

* refactor

* refactor: log level change.

* refactor: 3.7.0 code conventions.

---------

Co-authored-by: skiffer-git <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: root <root@localhost.localdomain>

* update go.mod go.sum

* Remove Chinese comments

* user localhost for minio

* user localhost for minio

* Remove Chinese comments

* Remove Chinese comments

* Remove Chinese comments

* Set up 4 instances of transfer

* Set up 4 instances of transfer

* Add comments to the configuration file

* Add comments to the configuration file

---------

Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: root <root@localhost.localdomain>

* Update the document  (#2219)

* 3.6.1 code conventions (#2203)

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* refactor: webhooks update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* refactor: kafka update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Windows can compile and run.

* Windows can compile and run.

* refactor: kafka update.

* feat: msg cache split

* refactor: webhooks update

* refactor: webhooks update

* refactor: friends update

* refactor: group update

* refactor: third update

* refactor: api update

* refactor: crontab update

* refactor: msggateway update

* mage

* mage

* refactor: all module update.

* check

* refactor: all module update.

* load config

* load config

* load config

* load config

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update tools

* update tools

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update protocol

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: api remove token auth by redis directly.

* Code Refactoring

* refactor: websocket auth change to call rpc of auth.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: remove msggateway redis.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* fix: runtime: goroutine stack exceeds

* refactor: cmd update.

* refactor notification

* refactor notification

* refactor

* refactor: cmd update.

* refactor: cmd update.

* refactor

* refactor

* refactor

* protojson

* protojson

* protojson

* go mod

* wrapperspb

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: context update.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: api name change.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: update file

* refactor

* refactor

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: callback update.

* fix: callback update.

* refactor

* fix: update message.

* fix: msg cache timeout.

* refactor

* refactor

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* refactor

* refactor

* fix: push update.

* fix: websocket handle error remove when upgrade error.

* fix: priority url

* fix: minio config

* refactor: add zk logger.

* refactor

* fix: minio config

* refactor

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* fix bug: get localIP

* refactor

* refactor

* refactor

* refactor: remove zk logger.

* refactor: update tools version.

* refactor

* refactor: update server version to 3.7.0.

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor

* refactor

* refactor

* refactor: log level change.

* refactor: 3.7.0 code conventions.

---------

Co-authored-by: skiffer-git <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: root <root@localhost.localdomain>

* update go.mod go.sum (#2209)

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* fix bug: get localIP

* update some ci file (#2200)

* Update openimci.yml

* Update golangci-lint.yml

* Update e2e-test.yml

* 3.6.1 code conventions (#2202)

* refactor: webhooks update.

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* feat: s3 api addr

* refactor: webhooks update.

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* refactor: webhooks update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* refactor: kafka update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Windows can compile and run.

* Windows can compile and run.

* refactor: kafka update.

* feat: msg cache split

* refactor: webhooks update

* refactor: webhooks update

* refactor: friends update

* refactor: group update

* refactor: third update

* refactor: api update

* refactor: crontab update

* refactor: msggateway update

* mage

* mage

* refactor: all module update.

* check

* refactor: all module update.

* load config

* load config

* load config

* load config

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update tools

* update tools

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update protocol

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: api remove token auth by redis directly.

* Code Refactoring

* refactor: websocket auth change to call rpc of auth.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: remove msggateway redis.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* fix: runtime: goroutine stack exceeds

* refactor: cmd update.

* refactor notification

* refactor notification

* refactor

* refactor: cmd update.

* refactor: cmd update.

* refactor

* refactor

* refactor

* protojson

* protojson

* protojson

* go mod

* wrapperspb

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: context update.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: api name change.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: update file

* refactor

* refactor

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: callback update.

* fix: callback update.

* refactor

* fix: update message.

* fix: msg cache timeout.

* refactor

* refactor

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* refactor

* refactor

* fix: push update.

* fix: websocket handle error remove when upgrade error.

* fix: priority url

* fix: minio config

* refactor: add zk logger.

* refactor

* fix: minio config

* refactor

* refactor

* refactor

* refactor

* refactor: remove zk logger.

* refactor: update tools version.

* refactor

* refactor: update server version to 3.7.0.

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor

* refactor

* refactor

* refactor: log level change.

* refactor: 3.7.0 code conventions.

---------

Co-authored-by: skiffer-git <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>

* update go.mod go.sum

* Remove Chinese comments

* user localhost for minio

* user localhost for minio

* Remove Chinese comments

* Remove Chinese comments

* Remove Chinese comments

* Set up 4 instances of transfer

* Set up 4 instances of transfer

* Add comments to the configuration file

* Add comments to the configuration file

---------

Co-authored-by: root <root@localhost.localdomain>
Co-authored-by: xuan <146319162+wxuanF@users.noreply.github.com>
Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>

* Update the document

* Update the document

---------

Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: root <root@localhost.localdomain>
Co-authored-by: xuan <146319162+wxuanF@users.noreply.github.com>

* feat: cron task

* feat: cron task

* feat: cron task

* update action (#2225)

* Rename e2e-test.yml to e2e-test.bak

* Rename create-branch-on-tag.yml to create-branch-on-tag.bak

* Rename pull-request.yml to pull-request.bak

* Update  slack invite link

* Update slack invite link

* feat: cron task

* feat: cron task

* go.mod

* fix: go.mod

---------

Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: skiffer-git <44203734@qq.com>
Co-authored-by: root <root@localhost.localdomain>
Co-authored-by: xuan <146319162+wxuanF@users.noreply.github.com>
Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: skiffer-git <72860476+skiffer-git@users.noreply.github.com>
2024-04-28 16:08:53 +08:00
xuan
c4842610dc
Update action v3.7 (#2257)
* Delete .github/workflows/check-coverage.yml

* Delete .github/workflows/create-branch-on-tag.yml

* Delete .github/workflows/release.yml

* Delete .github/workflows/docker-buildx.yml

* Update .env

* Delete .github/workflows/sync.yml

* Delete .github/workflows/sync-release.yml
2024-04-28 14:35:38 +08:00
chao
4f8626b55b
Merge pull request #2252 from skiffer-git/mage_start_error_2251
fix bug:If there are uppercase letters in the directory, 'mage start' encounters an error
2024-04-28 14:35:21 +08:00
skiffer-git
d28df5b94b
Remove redundant scripts (#2255)
* Remove redundant scripts

* Remove redundant scripts
2024-04-28 12:12:12 +08:00
skiffer-git
7a7d761e65 fix bug:
If there are uppercase letters in the directory, 'mage start' encounters an error
2024-04-28 10:43:13 +08:00
skiffer-git
3c62733275
update web/admin front image (#2246) 2024-04-26 20:59:30 +08:00
skiffer-git
049c62c401
Update CODEOWNERS 2024-04-26 19:31:04 +08:00
skiffer-git
e710b259d1
use openim/openim-admin openim/openim-web image (#2231) 2024-04-26 09:25:15 +08:00
skiffer-git
e11b928f4f
Update the document (#2221)
* Update the document

* Update the document
2024-04-25 14:17:17 +08:00
skiffer-git
837e365a80
update go.mod go.sum (#2209)
* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* fix bug: get localIP

* update some ci file (#2200)

* Update openimci.yml

* Update golangci-lint.yml

* Update e2e-test.yml

* 3.6.1 code conventions (#2202)

* refactor: webhooks update.

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* feat: s3 api addr

* refactor: webhooks update.

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* refactor: webhooks update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* refactor: kafka update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Windows can compile and run.

* Windows can compile and run.

* refactor: kafka update.

* feat: msg cache split

* refactor: webhooks update

* refactor: webhooks update

* refactor: friends update

* refactor: group update

* refactor: third update

* refactor: api update

* refactor: crontab update

* refactor: msggateway update

* mage

* mage

* refactor: all module update.

* check

* refactor: all module update.

* load config

* load config

* load config

* load config

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update tools

* update tools

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update protocol

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: api remove token auth by redis directly.

* Code Refactoring

* refactor: websocket auth change to call rpc of auth.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: remove msggateway redis.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* fix: runtime: goroutine stack exceeds

* refactor: cmd update.

* refactor notification

* refactor notification

* refactor

* refactor: cmd update.

* refactor: cmd update.

* refactor

* refactor

* refactor

* protojson

* protojson

* protojson

* go mod

* wrapperspb

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: context update.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: api name change.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: update file

* refactor

* refactor

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: callback update.

* fix: callback update.

* refactor

* fix: update message.

* fix: msg cache timeout.

* refactor

* refactor

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* refactor

* refactor

* fix: push update.

* fix: websocket handle error remove when upgrade error.

* fix: priority url

* fix: minio config

* refactor: add zk logger.

* refactor

* fix: minio config

* refactor

* refactor

* refactor

* refactor

* refactor: remove zk logger.

* refactor: update tools version.

* refactor

* refactor: update server version to 3.7.0.

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor

* refactor

* refactor

* refactor: log level change.

* refactor: 3.7.0 code conventions.

---------

Co-authored-by: skiffer-git <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>

* update go.mod go.sum

* Remove Chinese comments

* user localhost for minio

* user localhost for minio

* Remove Chinese comments

* Remove Chinese comments

* Remove Chinese comments

* Set up 4 instances of transfer

* Set up 4 instances of transfer

* Add comments to the configuration file

* Add comments to the configuration file

---------

Co-authored-by: root <root@localhost.localdomain>
Co-authored-by: xuan <146319162+wxuanF@users.noreply.github.com>
Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
2024-04-24 15:43:03 +08:00
OpenIM-Gordon
4a38307581
3.6.1 code conventions (#2203)
* Adjust configuration settings

* Adjust configuration settings

* Adjust configuration settings

* refactor: webhooks update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* refactor: kafka update.

* refactor: kafka update.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Simplify the Docker Compose configuration, remove unnecessary environment variables, and eliminate the gateway service.

* Windows can compile and run.

* Windows can compile and run.

* refactor: kafka update.

* feat: msg cache split

* refactor: webhooks update

* refactor: webhooks update

* refactor: friends update

* refactor: group update

* refactor: third update

* refactor: api update

* refactor: crontab update

* refactor: msggateway update

* mage

* mage

* refactor: all module update.

* check

* refactor: all module update.

* load config

* load config

* load config

* load config

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* refactor: all module update.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update tools

* update tools

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* update protocol

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: all module update.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* Optimize Docker configuration and script.

* refactor: api remove token auth by redis directly.

* Code Refactoring

* refactor: websocket auth change to call rpc of auth.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: kick online user and remove token change to call auth rpc.

* refactor: remove msggateway redis.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor webhook

* refactor: cmd update.

* refactor: cmd update.

* fix: runtime: goroutine stack exceeds

* refactor: cmd update.

* refactor notification

* refactor notification

* refactor

* refactor: cmd update.

* refactor: cmd update.

* refactor

* refactor

* refactor

* protojson

* protojson

* protojson

* go mod

* wrapperspb

* refactor: cmd update.

* refactor: cmd update.

* refactor: cmd update.

* refactor: context update.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: websocket update info.

* refactor: api name change.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: update file

* refactor

* refactor

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* refactor: debug info.

* fix: callback update.

* fix: callback update.

* refactor

* fix: update message.

* fix: msg cache timeout.

* refactor

* refactor

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* fix: push update.

* refactor

* refactor

* fix: push update.

* fix: websocket handle error remove when upgrade error.

* fix: priority url

* fix: minio config

* refactor: add zk logger.

* refactor

* fix: minio config

* refactor

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* remove \r

* fix bug: get localIP

* refactor

* refactor

* refactor

* refactor: remove zk logger.

* refactor: update tools version.

* refactor

* refactor: update server version to 3.7.0.

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor: zk log debug.

* refactor

* refactor

* refactor

* refactor: log level change.

* refactor: 3.7.0 code conventions.

---------

Co-authored-by: skiffer-git <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: root <root@localhost.localdomain>
2024-04-24 12:11:36 +08:00
154 changed files with 928 additions and 19130 deletions

View File

@ -5,9 +5,8 @@
.git
# Ignore build artifacts
_output/
logs/
_output/
# Ignore non-essential documentation
README.md
README-zh_CN.md
@ -18,8 +17,6 @@ CHANGELOG/
# Ignore testing and linting configuration
.golangci.yml
# Ignore deployment-related files
docker-compose.yaml
# Ignore assets
assets/

8
.env
View File

@ -6,8 +6,12 @@ KAFKA_IMAGE=bitnami/kafka:3.5.1
MINIO_IMAGE=minio/minio:RELEASE.2024-01-11T07-46-16Z
OPENIM_WEB_FRONT_IMAGE=ghcr.io/openimsdk/openim-web:v3.5.0-docker
OPENIM_ADMIN_FRONT_IMAGE=ghcr.io/openimsdk/openim-admin:toc-base-open-docker.35
OPENIM_WEB_FRONT_IMAGE=openim/openim-web-front:release-v3.5.1
OPENIM_ADMIN_FRONT_IMAGE=openim/openim-admin-front:release-v1.7
#FRONT_IMAGE: use aliyun images
#OPENIM_WEB_FRONT_IMAGE=registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-web-front:release-v3.5.1
#OPENIM_ADMIN_FRONT_IMAGE=registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-admin-front:release-v1.7
DATA_DIR=./

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.sh text eol=lf

View File

@ -1,59 +0,0 @@
# Copyright © 2023 OpenIM open source community. 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.
name: OpenIM Check Coverage
on:
workflow_dispatch:
push:
branches: [ "main" ]
paths-ignore:
- "docs/**"
- "**/*.md"
- "**/*.yaml"
- "CONTRIBUTORS"
- "CHANGELOG/**"
pull_request:
branches: [ "*" ]
paths-ignore:
- "docs/**"
- "**/*.md"
- "**/*.yaml"
- "CONTRIBUTORS"
- "CHANGELOG/**"
env:
# Common versions
GO_VERSION: "1.20"
jobs:
coverage:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Golang with cache
uses: magnetikonline/action-golang-cache@v4
with:
go-version: ${{ env.GO_VERSION }}
- name: Install Dependencies
run: sudo apt update && sudo apt install -y libgpgme-dev libbtrfs-dev libdevmapper-dev
- name: Run Cover
run: make cover
continue-on-error: true
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v4

View File

View File

@ -1,77 +0,0 @@
# 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.
name: Create Branch on Tag
on:
push:
tags:
- 'v*.*.0'
permissions:
contents: write
actions: write
jobs:
create-branch:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Git
run: |
git config --global user.name 'kubbot'
git config --global user.email '3293172751yxy@gmail.com'
- name: Install git-chglog
run: make install.git-chglog
- name: Create Branch and Push
env:
TAG_NAME: ${{ github.ref_name }}
run: |
IFS='.' read -ra VERSION_PARTS <<< "$TAG_NAME"
if [[ "${VERSION_PARTS[2]}" = "0" ]]; then
BRANCH_NAME="release-v${VERSION_PARTS[0]}.${VERSION_PARTS[1]}"
echo "Creating branch $BRANCH_NAME"
git checkout -b "$BRANCH_NAME"
git push origin "$BRANCH_NAME"
else
echo "Not a release tag. Skipping branch creation."
fi
continue-on-error: true
- name: Create and Commit CHANGELOG
if: endsWith(github.ref_name, '.0')
run: |
git fetch --all
TAG_NAME=${GITHUB_REF#refs/tags/}
IFS='.' read -ra VERSION_PARTS <<< "$TAG_NAME"
git checkout main
cd CHANGELOG
git-chglog --tag-filter-pattern "v${VERSION_PARTS[0]}.${VERSION_PARTS[1]}.*" -o "CHANGELOG-${VERSION_PARTS[0]}.${VERSION_PARTS[1]}.md"
git add "CHANGELOG-${VERSION_PARTS[0]}.${VERSION_PARTS[1]}.md"
git commit -m "Update CHANGELOG for $TAG_NAME" || echo "No changes to commit."
continue-on-error: true
- name: Push CHANGELOG to Main
if: steps.create-and-commit-changelog.outputs.changes == 'true'
uses: ad-m/github-push-action@v0.8.0
with:
github_token: ${{ secrets.BOT_GITHUB_TOKEN }}
branch: main
continue-on-error: true

0
.github/workflows/docker-buildx.bak vendored Normal file
View File

View File

@ -1,502 +0,0 @@
# Copyright © 2023 OpenIM open source community. 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.
name: Docker Buildx Images CI
on:
schedule:
- cron: '30 1 * * *'
push:
branches:
- release-*
tags:
- v*
workflow_dispatch:
jobs:
build-ghcr:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
install: true
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to AliYun Docker Hub
uses: docker/login-action@v3
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: ${{ secrets.ALIREGISTRY_USERNAME }}
password: ${{ secrets.ALIREGISTRY_TOKEN }}
################################################
# build/
# └── docker
# ├── openim-api
# │ └── Dockerfile
# ├── openim-cmdutils
# │ └── Dockerfile
# ├── openim-crontask
# │ └── Dockerfile
# ├── openim-msggateway
# │ └── Dockerfile
# ├── openim-msgtransfer
# │ └── Dockerfile
# ├── openim-push
# │ └── Dockerfile
# ├── openim-rpc-auth
# │ └── Dockerfile
# ├── openim-rpc-conversation
# │ └── Dockerfile
# ├── openim-rpc-friend
# │ └── Dockerfile
# ├── openim-rpc-group
# │ └── Dockerfile
# ├── openim-rpc-msg
# │ └── Dockerfile
# ├── openim-rpc-third
# │ └── Dockerfile
# └── openim-rpc-user
# └── Dockerfile
#############################################
- name: Extract metadata (tags, labels) for Docker openim-api
id: meta1
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-api
openim/openim-api
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-api
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-api
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-api/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta1.outputs.tags }}
labels: ${{ steps.meta1.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-cmdutils
id: meta2
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-cmdutils
openim/openim-cmdutils
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-cmdutils
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-cmdutils
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-cmdutils/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta2.outputs.tags }}
labels: ${{ steps.meta2.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-crontask
id: meta3
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-crontask
openim/openim-crontask
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-crontask
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-crontask
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-crontask/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta3.outputs.tags }}
labels: ${{ steps.meta3.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-msggateway
id: meta4
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-msggateway
openim/openim-msggateway
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-msggateway
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-msggateway
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-msggateway/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta4.outputs.tags }}
labels: ${{ steps.meta4.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-msgtransfer
id: meta5
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-msgtransfer
openim/openim-msgtransfer
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-msgtransfer
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-msgtransfer
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-msgtransfer/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta5.outputs.tags }}
labels: ${{ steps.meta5.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-push
id: meta6
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-push
openim/openim-push
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-push
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-push
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-push/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta6.outputs.tags }}
labels: ${{ steps.meta6.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-rpc-auth
id: meta7
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-rpc-auth
openim/openim-rpc-auth
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-auth
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-rpc-auth
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-rpc-auth/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta7.outputs.tags }}
labels: ${{ steps.meta7.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-rpc-conversation
id: meta8
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-rpc-conversation
openim/openim-rpc-conversation
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-conversation
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-rpc-conversation
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-rpc-conversation/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta8.outputs.tags }}
labels: ${{ steps.meta8.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-rpc-friend
id: meta9
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-rpc-friend
openim/openim-rpc-friend
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-friend
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-rpc-friend
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-rpc-friend/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta9.outputs.tags }}
labels: ${{ steps.meta9.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-rpc-group
id: meta10
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-rpc-group
openim/openim-rpc-group
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-group
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-rpc-group
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-rpc-group/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta10.outputs.tags }}
labels: ${{ steps.meta10.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-rpc-msg
id: meta11
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-rpc-msg
openim/openim-rpc-msg
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-msg
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-rpc-msg
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-rpc-msg/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta11.outputs.tags }}
labels: ${{ steps.meta11.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-rpc-third
id: meta12
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-rpc-third
openim/openim-rpc-third
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-third
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-rpc-third
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-rpc-third/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta12.outputs.tags }}
labels: ${{ steps.meta12.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Extract metadata (tags, labels) for Docker openim-rpc-user
id: meta13
uses: docker/metadata-action@v5.5.1
with:
images: |
ghcr.io/openimsdk/openim-rpc-user
openim/openim-rpc-user
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-rpc-user
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image for openim-rpc-user
uses: docker/build-push-action@v5
with:
context: .
file: ./build/images/openim-rpc-user/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta13.outputs.tags }}
labels: ${{ steps.meta13.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache

0
.github/workflows/e2e-test.bak vendored Normal file
View File

View File

@ -1,148 +0,0 @@
# 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.
name: OpenIM E2E And API Test
on:
workflow_dispatch:
pull_request:
push:
schedule:
# run e2e test every 4 hours
- cron: 0 */4 * * *
env:
CALLBACK_ENABLE: true
jobs:
build:
name: Test
runs-on: ubuntu-latest
env:
GO111MODULE: on
steps:
- name: Set up Go 1.21
uses: actions/setup-go@v5
with:
go-version: 1.21
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v4
- name: Create e2e test
run: |
echo "...test e2e"
execute-linux-systemd-scripts:
name: Execute OpenIM script on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
environment:
name: openim
strategy:
matrix:
go_version: ["1.20"]
os: ["ubuntu-latest"]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go ${{ matrix.go_version }}
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go_version }}
id: go
- name: Install Task
uses: arduino/setup-task@v1
with:
version: '3.x' # If available, use the latest major version that's compatible
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Docker Operations
run: |
sudo make init
sudo docker compose up -d
sudo sleep 20
- name: Module Operations
run: |
sudo make tidy
sudo make tools.verify.go-gitlint
- name: Build, Start(make build && make start)
run: |
sudo ./scripts/install/install.sh -i
- name: Exec OpenIM System Status Chack
run: |
sudo ./scripts/install/install.sh -s
- name: Exec OpenIM API test (make test-api)
run: |
mkdir -p ./tmp
touch ./tmp/test.md
echo "# OpenIM Test" >> ./tmp/test.md
echo "## OpenIM API Test" >> ./tmp/test.md
echo "<details><summary>Command Output for OpenIM API Test</summary>" >> ./tmp/test.md
echo "<pre><code>" >> ./tmp/test.md
sudo make test-api | tee -a ./tmp/test.md
echo "</code></pre>" >> ./tmp/test.md
echo "</details>" >> ./tmp/test.md
sudo make test-api
- name: Exec OpenIM E2E Test (make test-e2e)
run: |
echo "" >> ./tmp/test.md
echo "## OpenIM E2E Test" >> ./tmp/test.md
echo "<details><summary>Command Output for OpenIM E2E Test</summary>" >> ./tmp/test.md
echo "<pre><code>" >> ./tmp/test.md
sudo make test-e2e | tee -a ./tmp/test.md
echo "</code></pre>" >> ./tmp/test.md
echo "</details>" >> ./tmp/test.md
sudo make test-e2e
- name: Comment PR with file
uses: thollander/actions-comment-pull-request@v2
with:
filePath: ./tmp/test.md
comment_tag: nrt_file
reactions: eyes, rocket
mode: recreate
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
continue-on-error: true
- name: Check outputs
run: |
echo "id : ${{ steps.nrt_message.outputs.id }}"
echo "body : ${{ steps.nrt_message.outputs.body }}"
echo "html_url : ${{ steps.nrt_message.outputs.html_url }}"
- name: Exec OpenIM System uninstall
run: |
sudo ./scripts/install/install.sh -u
- name: gobenchdata publish
uses: bobheadxi/gobenchdata@v1
with:
PRUNE_COUNT: 30
GO_TEST_FLAGS: -cpu 1,2
PUBLISH: true
PUBLISH_BRANCH: gh-pages
env:
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
continue-on-error: true

0
.github/workflows/golangci-lint.bak vendored Normal file
View File

View File

@ -1,52 +0,0 @@
# Copyright © 2023 OpenIM open source community. 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.
name: OpenIM golangci-lint
on:
push:
branches: [main]
pull_request:
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: false
- name: OpenIM Scripts Verification(make verify)
run: sudo make verify
- name: golangci-lint
uses: golangci/golangci-lint-action@v4.0.0
with:
# Require: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: v1.54
# Optional: working directory, useful for monorepos
# working-directory: server
# Optional: golangci-lint command line arguments.
#
# Note: by default the `.golangci.yml` file should be at the root of the repository.
# The location of the configuration file can be changed by using `--config=`
# args: --timeout=30m --config=/scripts/.golangci.yml --issues-exit-code=0
# Optional: show only new issues if it's a pull request. The default value is `false`.
only-new-issues: true
# Optional:The mode to install golangci-lint. It can be 'binary' or 'goinstall'.
# install-mode: "goinstall"

View File

@ -1,3 +1,4 @@
# Copyright © 2023 OpenIM open source community. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@ -11,8 +12,7 @@
# 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.
name: OpenIM CI Aotu Build and Install
name: OpenIM CI Auto Build
on:
push:
@ -36,270 +36,156 @@ on:
- "CONTRIBUTING/**"
- "**.md"
- "docs/**"
env:
GO_VERSION: "1.19"
GOLANGCI_VERSION: "v1.50.1"
workflow_dispatch:
jobs:
openim:
name: Test with go ${{ matrix.go_version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
permissions:
contents: write
pull-requests: write
environment:
name: openim
strategy:
matrix:
go_version: ["1.19","1.20","1.21"]
os: [ubuntu-latest]
steps:
- name: Setup
uses: actions/checkout@v4
- name: Set up Go ${{ matrix.go_version }}
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go_version }}
id: go
- name: Install Task
uses: arduino/setup-task@v1
with:
version: '3.x' # If available, use the latest major version that's compatible
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Code Typecheck Detector
uses: kubecub/typecheck@main
- name: Conformity Checker for Project
uses: kubecub/standardizer@main
- name: Module Operations
run: |
sudo make tidy
sudo make tools.verify.go-gitlint
- name: Format Code
run: sudo make format
continue-on-error: true
- name: Generate Files
run: make gen
continue-on-error: true
- name: Build Source
run: sudo make build
- name: Build multiarch PLATFORMS
if: startsWith(github.ref, 'refs/heads/release-')
run: |
sudo make multiarch
- name: Cleanup Build
run: sudo make clean
- name: Set Current Directory
id: set_directory
run: echo "::set-output name=directory::$(pwd)"
continue-on-error: true
- name: Collect and Display Test Coverage
id: collect_coverage
run: |
cd ${{ steps.set_directory.outputs.directory }}
make cover
echo "::set-output name=coverage_file::./_output/tmp/coverage.out"
echo "Test Coverage:"
cat ${{ steps.collect_coverage.outputs.coverage_file }}
continue-on-error: true
openim-start:
name: Test OpenIM install/start on ${{ matrix.os }}-${{ matrix.arch }}
runs-on: ${{ matrix.os }}
permissions:
contents: write
pull-requests: write
environment:
name: openim
strategy:
matrix:
go_version: ["1.21"]
os: ["ubuntu-latest"]
steps:
- name: Checkout and Install OpenIM
uses: actions/checkout@v4
- name: Install Task
uses: arduino/setup-task@v1
with:
version: '3.x' # If available, use the latest major version that's compatible
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Run OpenIM make install start
run: |
sudo make install
# - name: Check the OpenIM environment and status
# run: |
# sudo docker images
# sudo docker ps
- name: Check the OpenIM environment and status
if: runner.os == 'Linux' && matrix.arch == 'amd64'
id: docker_info
run: |
sleep 30
echo "images<<EOF" >> $GITHUB_ENV
sudo docker images >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
echo "containers<<EOF" >> $GITHUB_ENV
sudo docker ps >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Comment PR
uses: thollander/actions-comment-pull-request@v2
if: runner.os == 'Linux' && matrix.arch == 'amd64'
with:
message: |
> [!TIP]
> Run make install to check the status
### Docker Images:
<details><summary>Click to expand docker images</summary>
```bash
${{ env.images }}
```
</details>
### Docker Processes:
<details><summary>Click to expand docker ps</summary>
```bash
${{ env.containers }}
```
</details>
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
execute-scripts:
name: Execute OpenIM Script On ${{ matrix.os }}-${{ matrix.arch }}
runs-on: ${{ matrix.os }}
permissions:
contents: write
pull-requests: write
environment:
name: openim
strategy:
matrix:
go_version: ["1.21"]
os: ["ubuntu-latest", "macos-latest"]
arch: [arm64, armv7, amd64]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go ${{ matrix.go_version }}
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go_version }}
id: go
- name: Install Task
uses: arduino/setup-task@v1
with:
version: '3.x' # If available, use the latest major version that's compatible
repo-token: ${{ secrets.GITHUB_TOKEN }}
# - name: Install latest Bash (macOS only)
# if: runner.os == 'macOS' && matrix.arch == 'arm64'
# run: |
# /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# brew update
# brew install bash
# brew install gnu-sed
# echo "/usr/local/bin" >> $GITHUB_PATH
# echo "$(brew --prefix)/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH
# continue-on-error: true
- name: Set up Docker for Ubuntu
if: runner.os == 'Linux'
run: |
sudo make init
sudo docker compose up -d
sudo sleep 20
# - name: Set up Docker for macOS
# if: runner.os == 'macOS' && matrix.arch == 'arm64'
# run: |
# brew install --cask docker
# open /Applications/Docker.app
# sleep 10
# docker-compose --version || brew install docker-compose
# docker-compose up -d
# sleep 20
- name: Module Operations for Ubuntu
if: runner.os == 'Linux'
run: |
sudo make tidy
sudo make tools.verify.go-gitlint
# - name: Module Operations for macOS
# if: runner.os == 'macOS'
# run: |
# make tidy
# make tools.verify.go-gitlint
- name: Build, Start, Check Services and Print Logs for Ubuntu
if: runner.os == 'Linux'
run: |
sudo make build
sudo make start
sudo make check
- name: Restart Services and Print Logs for Ubuntu
if: runner.os == 'Linux' && matrix.arch == 'amd64'
run: |
sudo make restart
sudo make check
- name: Build, Start, Check Services and Print Logs for macOS
if: runner.os == 'macOS' && matrix.arch == 'arm64'
run: |
make build
openim-test-build-image:
name: Build OpenIM Docker Image
build-linux:
name: Execute OpenIM Script On Linux
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
contents: write
pull-requests: write
environment:
name: openim
strategy:
matrix:
arch: [arm64, armv7, amd64]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go ${{ matrix.go_version }}
uses: actions/setup-go@v5
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go_version }}
id: go
go-version: '1.21'
- name: Install Task
uses: arduino/setup-task@v1
with:
version: '3.x' # If available, use the latest major version that's compatible
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Test Docker Build
- name: Set up Docker for Linux
run: |
sudo make init
sudo make image
sudo docker compose up -d
sudo sleep 30 # Increased sleep time for better stability
timeout-minutes: 20 # Increased timeout for Docker setup
- name: Get OpenIM Docker Images Status
id: docker_processes
- name: init
run: sudo bash bootstrap.sh
timeout-minutes: 20
- name: Build, Start, Check Services and Print Logs for Linux
run: |
sudo docker images
sudo docker ps
sudo mage
sudo mage start
sudo mage check
- name: Restart Services and Print Logs
run: |
sudo mage stop
sudo mage start
sudo mage check
# build-mac:
# name: Execute OpenIM Script On macOS
# runs-on: macos-latest
# permissions:
# contents: write
# pull-requests: write
# environment:
# name: openim
# strategy:
# matrix:
# arch: [arm64, armv7, amd64]
#
# steps:
# - uses: actions/checkout@v3
# - name: Set up Go
# uses: actions/setup-go@v4
# with:
# go-version: '1.21'
# while ! docker system info > /dev/null 2>&1; do
# echo "Waiting for Docker to start..."
# sleep 10 # Increased delay to ensure Docker starts properly
# done
# - name: Install Docker
# run: |
# brew install docker
# brew install docker-compose
# sleep 10
# docker-compose up -d
# sleep 30
# timeout-minutes: 20
#
# - name: init
# run: sudo bash bootstrap.sh
# timeout-minutes: 20
# - name: Build, Start, Check Services and Print Logs for Linux
# run: |
# sudo mage
# sudo mage start
# sudo mage check
# - name: Restart Services and Print Logs
# run: |
# sudo mage stop
# sudo mage start
# sudo mage check
# build-windows:
# name: Execute OpenIM Script On Windows
# runs-on: windows-latest
# permissions:
# contents: write
# pull-requests: write
# environment:
# name: openim
# strategy:
# matrix:
# arch: [arm64, armv7, amd64]
#
# steps:
# - uses: actions/checkout@v3
# - name: Set up Go
# uses: actions/setup-go@v4
# with:
# go-version: '1.21'
# - name: Set up Docker for Windows
# run: |
# $images = @("zookeeper", "redis", "kafka")
# foreach ($image in $images) {
# $tag = "$image:latest"
# docker pull $tag | Out-Null
# if ($LASTEXITCODE -ne 0) {
# Write-Host "Skipping $image as it is not available for Windows"
# } else {
# Write-Host "Successfully pulled $image"
# }
# }
# docker compose up -d
# Start-Sleep -Seconds 30
# timeout-minutes: 20
# shell: pwsh
# - name: init
# run: bootstrap.bat
# timeout-minutes: 20
# - name: Build, Start, Check Services and Print Logs for Linux
# run: |
# mage
# mage start
# mage check
# - name: Restart Services and Print Logs
# run: |
# mage stop
# mage start
# mage check

View File

@ -1,81 +0,0 @@
# 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.
name: OpenIM Server Release Workflow
on:
push:
# run only against tags
tags:
- '*'
permissions:
contents: write
packages: write
issues: write
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: git fetch --force --tags
- uses: actions/setup-go@v5
with:
go-version: stable
# More assembly might be required: Docker logins, GPG, etc. It all depends
# on your needs.
- uses: goreleaser/goreleaser-action@v5
with:
# either 'goreleaser' (default) or 'goreleaser-pro':
distribution: goreleaser
version: latest
workdir: .
args: release -f ./build/goreleaser.yaml --clean --release-footer-tmpl=scripts/template/footer.md.tmpl --release-header-tmpl=scripts/template/head.md.tmpl
env:
USERNAME: ${{ github.repository_owner }}
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
FURY_TOKEN: ${{ secrets.FURY_TOKEN }}
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro'
# distribution:
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
goreleaser-check-pkgs:
runs-on: ubuntu-latest
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
needs: [ goreleaser ]
if: github.ref == 'refs/heads/main'
strategy:
matrix:
format: [ deb, rpm, apk ]
steps:
- uses: actions/checkout@v4 # v3
with:
fetch-depth: 0
- uses: arduino/setup-task@e26d8975574116b0097a1161e0fe16ba75d84c1c # v1
with:
version: 3.x
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/setup-qemu-action@326560df218a7ea9cf6ab49bbc88b8b306bb437e # v2
- uses: actions/cache@a2ed59d39b352305bdd2f628719a53b2cc4f9613 # v3
with:
path: |
./_output/dist/*.deb
./_output/dist/*.rpm
./_output/dist/*.apk
key: ${{ github.ref }}
- run: task goreleaser:test:${{ matrix.format }}

View File

@ -1,44 +0,0 @@
# Copyright © 2023 KubeCub open source community. All rights reserved.
# Licensed under the MIT License (the "License");
# you may not use this file except in compliance with the License.
# https://github.com/BetaHuhn/repo-file-sync-action
name: Synchronize OpenIM Release Branch Public Code To Other Repositories
on:
push:
paths:
- scripts/*
- docs/*
- config/*
branches:
- release-v*.*
workflow_dispatch:
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run GitHub File Sync
uses: BetaHuhn/repo-file-sync-action@latest
with:
GH_INSTALLATION_TOKEN: "${{ secrets.BOT_GITHUB_TOKEN }}"
CONFIG_PATH: .github/sync-release.yml
ORIGINAL_MESSAGE: true
SKIP_PR: true
COMMIT_EACH_FILE: false
COMMIT_BODY: "🤖 kubbot to synchronize the warehouse"
GIT_EMAIL: "3293172751ysy@gmail.com"
GIT_USERNAME: "kubbot"
PR_BODY: 👌 kubecub provides automated community services
REVIEWERS: |
kubbot
cubxxw
PR_LABELS: |
file-sync
automerge
ASSIGNEES: |
kubbot
continue-on-error: true

View File

@ -1,40 +0,0 @@
# Copyright © 2023 KubeCub open source community. All rights reserved.
# Licensed under the MIT License (the "License");
# you may not use this file except in compliance with the License.
# https://github.com/BetaHuhn/repo-file-sync-action
name: Synchronize OpenIM Main Branch Public Code To Other Repositories
on:
push:
branches:
- main
workflow_dispatch:
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run GitHub File Sync
uses: BetaHuhn/repo-file-sync-action@latest
with:
GH_INSTALLATION_TOKEN: "${{ secrets.BOT_GITHUB_TOKEN }}"
CONFIG_PATH: .github/sync.yml
ORIGINAL_MESSAGE: true
SKIP_PR: true
COMMIT_EACH_FILE: false
COMMIT_BODY: "🤖 kubbot to synchronize the warehouse"
GIT_EMAIL: "3293172751ysy@gmail.com"
GIT_USERNAME: "kubbot"
PR_BODY: 👌 kubecub provides automated community services
REVIEWERS: |
kubbot
cubxxw
PR_LABELS: |
file-sync
automerge
ASSIGNEES: |
kubbot
continue-on-error: true

View File

@ -1,30 +1,49 @@
# Build Stage
FROM golang:1.20 AS builder
# Use Go 1.21 Alpine as the base image for building the application
FROM golang:1.21-alpine as builder
# Set go mod installation source and proxy
ARG GO111MODULE=on
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
ENV GO111MODULE=$GO111MODULE
ENV GOPROXY=$GOPROXY
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set up the working directory
WORKDIR /openim/openim-server
# Set the Go proxy to improve dependency resolution speed
ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod download
# Install Mage to use for building the application
RUN go install github.com/magefile/mage@v1.15.0
# Optionally build your application if needed
RUN mage build
# Using Alpine Linux with Go environment for the final image
FROM golang:1.21-alpine
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy all files to the container
ADD . .
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
COPY --from=builder /go/bin/mage /usr/local/bin/mage
COPY --from=builder $SERVER_DIR/magefile_windows.go $SERVER_DIR/
COPY --from=builder $SERVER_DIR/magefile_unix.go $SERVER_DIR/
COPY --from=builder $SERVER_DIR/magefile.go $SERVER_DIR/
COPY --from=builder $SERVER_DIR/start-config.yml $SERVER_DIR/
COPY --from=builder $SERVER_DIR/go.mod $SERVER_DIR/
COPY --from=builder $SERVER_DIR/go.sum $SERVER_DIR/
RUN make clean
RUN make build
RUN go get github.com/openimsdk/gomake@v0.0.13
FROM ghcr.io/openim-sigs/openim-ubuntu-image:latest
WORKDIR ${SERVER_WORKDIR}
# Copy scripts and binary files to the production image
COPY --from=builder ${OPENIM_SERVER_BINDIR} /openim/openim-server/_output/bin
COPY --from=builder ${OPENIM_SERVER_CMDDIR} /openim/openim-server/scripts
COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config
COPY --from=builder ${SERVER_WORKDIR}/deployments /openim/openim-server/deployments
CMD ["/openim/openim-server/scripts/docker-start-all.sh"]
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "mage start && tail -f /dev/null"]

128
README.md
View File

@ -51,137 +51,89 @@
</p>
## :busts_in_silhouette: Community
## :busts_in_silhouette: Join Our Community
+ 💬 [Follow our Twitter account](https://twitter.com/founder_im63606)
+ 👫 [Join our Reddit](https://www.reddit.com/r/OpenIMessaging)
+ 🚀 [Join our Slack community](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q)
+ :eyes: [Join our wechat (微信群)](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
+ 📚 [OpenIM Community](https://github.com/OpenIMSDK/community)
+ 💕 [OpenIM Interest Group](https://github.com/Openim-sigs)
+ 💬 [Follow us on Twitter](https://twitter.com/founder_im63606)
+ 🚀 [Join our Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q)
+ :eyes: [Join our WeChat Group](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
## Ⓜ️ About OpenIM
OpenIM is a service platform specifically designed for integrating chat, audio-video calls, notifications, and AI chatbots into applications. It provides a range of powerful APIs and Webhooks, enabling developers to easily incorporate these interactive features into their applications. OpenIM is not a standalone chat application, but rather serves as a platform to support other applications in achieving rich communication functionalities. The following diagram illustrates the interaction between AppServer, AppClient, OpenIMServer, and OpenIMSDK to explain in detail.
Unlike standalone chat applications such as Telegram, Signal, and Rocket.Chat, OpenIM offers an open-source instant messaging solution designed specifically for developers rather than as a directly installable standalone chat app. Comprising OpenIM SDK and OpenIM Server, it provides developers with a complete set of tools and services to integrate instant messaging functions into their applications, including message sending and receiving, user management, and group management. Overall, OpenIM aims to provide developers with the necessary tools and framework to implement efficient instant messaging solutions in their applications.
![App-OpenIM Relationship](./docs/images/oepnim-design.png)
## 🚀 About OpenIMSDK
## 🚀 Introduction to OpenIMSDK
**OpenIMSDK** is an IM SDK designed for **OpenIMServer**, created specifically for embedding in client applications. Its main features and modules are as follows:
**OpenIMSDK**, designed for **OpenIMServer**, is an IM SDK created specifically for integration into client applications. It supports various functionalities and modules:
+ 🌟 Main Features:
- 📦 Local storage
- 🔔 Listener callbacks
- 🛡️ API wrapping
- 🌐 Connection management
- 📦 Local Storage
- 🔔 Listener Callbacks
- 🛡️ API Wrapping
- 🌐 Connection Management
+ 📚 Main Modules:
1. 🚀 Initialization and Login
2. 👤 User Management
3. 👫 Friend Management
3. 👫 Friends Management
4. 🤖 Group Functions
5. 💬 Conversation Handling
5. 💬 Session Handling
It is built using Golang and supports cross-platform deployment, ensuring a consistent access experience across all platforms.
Built with Golang and supports cross-platform deployment to ensure a consistent integration experience across all platforms.
👉 **[Explore GO SDK](https://github.com/openimsdk/openim-sdk-core)**
👉 **[Explore the GO SDK](https://github.com/openimsdk/openim-sdk-core)**
## 🌐 About OpenIMServer
## 🌐 Introduction to OpenIMServer
+ **OpenIMServer** has the following characteristics:
- 🌐 Microservice architecture: Supports cluster mode, including a gateway and multiple rpc services.
- 🚀 Diverse deployment methods: Supports deployment via source code, Kubernetes, or Docker.
- Support for massive user base: Super large groups with hundreds of thousands of users, tens of millions of users, and billions of messages.
+ **OpenIMServer** features include:
- 🌐 Microservices Architecture: Supports cluster mode, including a gateway and multiple rpc services.
- 🚀 Diverse Deployment Options: Supports source code, Kubernetes, or Docker deployment.
- Massive User Support: Supports large-scale groups with hundreds of thousands, millions of users, and billions of messages.
### Enhanced Business Functionality:
### Enhanced Business Functions:
+ **REST API**: OpenIMServer offers REST APIs for business systems, aimed at empowering businesses with more functionalities, such as creating groups and sending push messages through backend interfaces.
+ **Webhooks**: OpenIMServer provides callback capabilities to extend more business forms. A callback means that OpenIMServer sends a request to the business server before or after a certain event, like callbacks before or after sending a message.
+ **REST API**: Provides a REST API for business systems to enhance functionality, such as group creation and message pushing through backend interfaces.
👉 **[Learn more](https://docs.openim.io/guides/introduction/product)**
## :building_construction: Overall Architecture
Delve into the heart of Open-IM-Server's functionality with our architecture diagram.
![Overall Architecture](./docs/images/architecture-layers.png)
+ **Webhooks**: Expands business forms through callbacks, sending requests to business servers before or after certain events.
![Overall Architecture](./docs/images/architecture-layers.png)
## :rocket: Quick Start
We support many platforms. Here are the addresses for quick experience on the web side
Experience online for iOS/Android/H5/PC/Web:
👉 **[OpenIM online web demo](https://web-enterprise.rentsoft.cn/)**
👉 **[OpenIM Online Demo](https://www.openim.io/en/commercial)**
🤲 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 preferred deployment method from the list below:
+ **[Source Code Deployment Guide](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
+ **[Docker Deployment Guide](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
+ **[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
## System Support
[![Open in Dev Container](https://img.shields.io/static/v1?label=Dev%20Container&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/github/openimsdk/open-im-server)
Supports Linux, Windows, Mac systems, and ARM and AMD CPU architectures.
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/openimsdk/open-im-server)
## :link: Links
OpenIM Our goal is to build a top-level open source community. We have a set of standards, in the [Community repository](https://github.com/OpenIMSDK/community).
+ **[Developer Manual](https://docs.openim.io/)**
+ **[Changelog](https://github.com/openimsdk/open-im-server/blob/main/CHANGELOG.md)**
If you'd like to contribute to this Open-IM-Server repository, please read our [contributor documentation](https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md).
## :writing_hand: How to Contribute
Before you start, please make sure your changes are in demand. The best for that is to create a [new discussion](https://github.com/openimsdk/open-im-server/discussions/new/choose) OR [Slack Communication](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q), or if you find an issue, [report it](https://github.com/openimsdk/open-im-server/issues/new/choose) first.
We welcome contributions of any kind! Please make sure to read our [Contributor Documentation](https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md) before submitting a Pull Request.
- [OpenIM API Reference](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/api.md)
- [OpenIM Bash Logging](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/bash-log.md)
- [OpenIM CI/CD Actions](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/cicd-actions.md)
- [OpenIM Code Conventions](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/code-conventions.md)
- [OpenIM Commit Guidelines](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/commit.md)
- [OpenIM Development Guide](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/development.md)
- [OpenIM Directory Structure](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/directory.md)
- [OpenIM Environment Setup](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/environment.md)
- [OpenIM Error Code Reference](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/error-code.md)
- [OpenIM Git Workflow](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/git-workflow.md)
- [OpenIM Git Cherry Pick Guide](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/gitcherry-pick.md)
- [OpenIM GitHub Workflow](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/github-workflow.md)
- [OpenIM Go Code Standards](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/go-code.md)
- [OpenIM Image Guidelines](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/images.md)
- [OpenIM Initial Configuration](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/init-config.md)
- [OpenIM Docker Installation Guide](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/install-docker.md)
- [OpenIM OpenIM Linux System Installation](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/install-openim-linux-system.md)
- [OpenIM Linux Development Guide](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/linux-development.md)
- [OpenIM Local Actions Guide](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/local-actions.md)
- [OpenIM Logging Conventions](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/logging.md)
- [OpenIM Offline Deployment](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/offline-deployment.md)
- [OpenIM Protoc Tools](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/protoc-tools.md)
- [OpenIM Testing Guide](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/test.md)
- [OpenIM Utility Go](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/util-go.md)
- [OpenIM Makefile Utilities](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/util-makefile.md)
- [OpenIM Script Utilities](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/util-scripts.md)
- [OpenIM Versioning](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/version.md)
- [Manage backend and monitor deployment](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/prometheus-grafana.md)
- [Mac Developer Deployment Guide for OpenIM](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/mac-developer-deployment-guide.md)
+ **[Report a Bug](https://github.com/openimsdk/open-im-server/issues/new?assignees=&labels=bug&template=bug_report.md&title=)**
+ **[Suggest a Feature](https://github.com/openimsdk/open-im-server/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=)**
+ **[Submit a Pull Request](https://github.com/openimsdk/open-im-server/pulls)**
## :calendar: Community Meetings
Thank you for contributing to building a powerful instant messaging solution!
We want anyone to get involved in our community and contributing code, we offer gifts and rewards, and we welcome you to join us every Thursday night.
## :closed_book: License
Our conference is in the [OpenIM Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q) 🎯, then you can search the Open-IM-Server pipeline to join
OpenIMSDK is available under the Apache License 2.0. See the [LICENSE file](https://github.com/openimsdk/open-im-server/blob/main/LICENSE) for more information.
We take notes of each [biweekly meeting](https://github.com/orgs/OpenIMSDK/discussions/categories/meeting) in [GitHub discussions](https://github.com/openimsdk/open-im-server/discussions/categories/meeting), Our historical meeting notes, as well as replays of the meetings are available at [Google Docs :bookmark_tabs:](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing).
## :eyes: Who Are Using OpenIM
Check out our [user case studies](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) page for a list of the project users. Don't hesitate to leave a [📝comment](https://github.com/openimsdk/open-im-server/issues/379) and share your use case.
## :page_facing_up: License
OpenIM is licensed under the Apache 2.0 license. See [LICENSE](https://github.com/openimsdk/open-im-server/tree/main/LICENSE) for the full license text.
The OpenIM logo, including its variations and animated versions, displayed in this repository [OpenIM](https://github.com/openimsdk/open-im-server) under the [assets/logo](./assets/logo) and [assets/logo-gif](assets/logo-gif) directories, are protected by copyright laws.
## 🔮 Thanks to our contributors!

View File

@ -51,31 +51,29 @@
</p>
## 🟢 扫描微信进群交流
<img src="./docs/images/wechat.jpg" width="300">
## :busts_in_silhouette: 加入我们的社区
+ 💬 [关注我们的 Twitter](https://twitter.com/founder_im63606)
+ 🚀 [加入我们的 Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q)
+ :eyes: [加入我们的微信群](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
## Ⓜ️ 关于 OpenIM
OpenIM 是一个专门设计用于在应用程序中集成聊天、音视频通话、通知以及AI聊天机器人等通信功能的服务平台。它通过提供一系列强大的API和Webhooks使开发者可以轻松地在他们的应用中加入这些交互特性。OpenIM 本身并不是一个独立运行的聊天应用,而是作为一个平台,为其他应用提供支持,实现丰富的通信功能。下图展示 AppServer、AppClient、OpenIMServer 和 OpenIMSDK 之间的交互关系来具体说明。
与Telegram、Signal、Rocket.Chat等独立聊天应用不同OpenIM提供了专为开发者设计的开源即时通讯解决方案而不是直接安装使用的独立聊天应用。OpenIM由OpenIM SDK和OpenIM Server两大部分组成为开发者提供了一整套集成即时通讯功能的工具和服务包括消息发送接收、用户管理和群组管理等。总体来说OpenIM旨在为开发者提供必要的工具和框架帮助他们在自己的应用中实现高效的即时通讯解决方案。
![App-OpenIM 关系](./docs/images/oepnim-design.png)
## 🚀 关于 OpenIMSDK
## 🚀 OpenIMSDK 介绍
**OpenIMSDK** 是为 **OpenIMServer** 设计的IM SDK专为嵌入客户端应用而生。其主要功能及模块如下
**OpenIMSDK** 是为 **OpenIMServer** 设计的IM SDK专为集成到客户端应用而生。它支持多种功能和模块
+ 🌟 主要功能:
- 📦 本地存储
- 🔔 监听器回调
- 🛡️ API封装
- 🌐 连接管理
## 📚 主要模块:
+ 📚 主要模块:
1. 🚀 初始化及登录
2. 👤 用户管理
3. 👫 好友管理
@ -86,81 +84,52 @@ OpenIM 是一个专门设计用于在应用程序中集成聊天、音视频通
👉 **[探索 GO SDK](https://github.com/openimsdk/openim-sdk-core)**
## 🌐 关于 OpenIMServer
## 🌐 OpenIMServer 介绍
+ **OpenIMServer** 具有以下特点
+ **OpenIMServer** 的特点包括
- 🌐 微服务架构:支持集群模式,包括网关(gateway)和多个rpc服务。
- 🚀 部署方式多样支持源代码、kubernetes或docker部署。
- 海量用户支持:十万超级大群,千万用户,及百亿消息
- 🚀 多样的部署方式支持源代码、Kubernetes或Docker部署。
- 海量用户支持:支持十万级超大群组,千万级用户和百亿级消息。
### 增强的业务功能:
+ **REST API**OpenIMServer 提供了REST API供业务系统使用旨在赋予业务更多功能例如通过后台接口建立群组、发送推送消息等。
+ **Webhooks**OpenIMServer提供了回调能力以扩展更多的业务形态所谓回调即OpenIMServer会在某一事件发生之前或者之后向业务服务器发送请求如发送消息之前或之后的回调。
+ **REST API**为业务系统提供REST API增加群组创建、消息推送等后台接口功能。
👉 **[了解更多](https://docs.openim.io/guides/introduction/product)**
+ **Webhooks**:通过事件前后的回调,向业务服务器发送请求,扩展更多的业务形态。
## :rocket: 快速开始
![整体架构](./docs/images/architecture-layers.png)
## :rocket: 快速入门
在线体验iOS/Android/H5/PC/Web
👉 **[OpenIM online demo](https://www.openim.io/zh/commercial)**
👉 **[OpenIM在线演示](https://www.openim.io/en/commercial)**
🤲 为了便用户体验,我们提供了多种部署解决方案,您可以根据下面的列表选择自己的部署方法
为了便用户体验,我们提供了多种部署解决方案,您可以根据以下列表选择适合您的部署方式
+ **[源代码部署指南](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
+ **[Docker 部署指南](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
+ **[Kubernetes 部署指南](https://docs.openim.io/guides/gettingStarted/k8s-deployment)**
## :hammer_and_wrench: 开始开发 OpenIM
## 系统支持
OpenIM 我们的目标是建立一个顶级的开源社区。我们有一套标准,在[社区仓库](https://github.com/OpenIMSDK/community)中
支持 Linux、Windows、Mac 系统以及 ARM 和 AMD CPU 架构
如果你想为这个 Open-IM-Server 仓库做贡献,请阅读我们的[贡献者文档](https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md)。
## :link: 相关链接
在开始之前,请确保你的更改是有需求的。最好的方法是创建一个[新的讨论](https://github.com/openimsdk/open-im-server/discussions/new/choose) 或 [Slack 通信](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q),或者如果你发现一个问题,首先[报告它](https://github.com/openimsdk/open-im-server/issues/new/choose)。
+ [代码标准](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/go-code.md)
+ [Docker 镜像标准](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/images.md)
+ [目录标准](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/directory.md)
+ [提交标准](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/commit.md)
+ [版本控制标准](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/version.md)
+ [接口标准](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/interface.md)
+ [OpenIM配置和环境变量设置](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/environment.md)
> **Note**
> 针对中国的用户,阅读我们的 [Docker 镜像标准](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/images.md) 以便使用国内 aliyun 的镜像地址。OpenIM 也有针对中国的 gitee 同步仓库,你可以在 [gitee.com](https://gitee.com/openimsdk) 上找到它。
## :link: 链接
+ **[完整文档](https://doc.rentsoft.cn/)**
+ **[开发手册](https://docs.openim.io/)**
+ **[更新日志](https://github.com/openimsdk/open-im-server/blob/main/CHANGELOG.md)**
+ **[FAQ](https://github.com/openimsdk/open-im-server/blob/main/FAQ.md)**
+ **[代码示例](https://github.com/openimsdk/open-im-server/blob/main/examples)**
## :handshake: 社区
## :writing_hand: 如何贡献
+ **[GitHub Discussions](https://github.com/openimsdk/open-im-server/discussions)**
+ **[Slack 通信](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q)**
+ **[GitHub Issues](https://github.com/openimsdk/open-im-server/issues)**
您可以加入这些平台,讨论问题,提出建议,或分享您的成功故事!
## :writing_hand: 贡献
我们欢迎任何形式的贡献!请确保在提交 Pull Request 之前阅读我们的[贡献者文档](https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md)。
我们欢迎任何形式的贡献!在提交 Pull Request 之前,请确保阅读我们的[贡献者文档](https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md)
+ **[报告 Bug](https://github.com/openimsdk/open-im-server/issues/new?assignees=&labels=bug&template=bug_report.md&title=)**
+ **[提出新特性](https://github.com/openimsdk/open-im-server/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=)**
+ **[提交 Pull Request](https://github.com/openimsdk/open-im-server/pulls)**
感谢您的贡献,我们一起打造一个强大的即时通信解决方案!
感谢您的贡献,一起来打造强大的即时通讯解决方案!
## :closed_book: 许可证

63
config/README.md Normal file
View File

@ -0,0 +1,63 @@
---
title: 'OpenIM Configuration Files and Common Configuration Item Modifications Guide'
## Configuration Files Explanation
| Configuration File | Description |
| ------------------------------- | ------------------------------------------------------------ |
| **kafka.yml** | Configurations for Kafka username, password, address, etc. |
| **redis.yml** | Configurations for Redis password, address, etc. |
| **minio.yml** | Configurations for MinIO username, password, address, and external IP/domain; failing to modify external IP or domain may cause image file sending failures |
| **zookeeper.yml** | Configurations for ZooKeeper user, password, address, etc. |
| **mongodb.yml** | Configurations for MongoDB username, password, address, etc. |
| **log.yml** | Configurations for log level and storage directory. |
| **notification.yml** | Configurations for events like adding friends, creating groups, etc. |
| **share.yml** | Common configurations needed by various OpenIM services, such as secret. |
| **webhooks.yml** | Configurations for URLs in Webhook. |
| **local-cache.yml** | Local cache configurations. |
| **openim-rpc-third.yml** | Configurations for listening IP, port, and storage settings for images and videos in openim-rpc-third service. |
| **openim-rpc-user.yml** | Configurations for listening IP and port in openim-rpc-user service. |
| **openim-api.yml** | Configurations for listening IP, port, etc., in openim-api service. |
| **openim-crontask.yml** | Configurations for openim-crontask service. |
| **openim-msggateway.yml** | Configurations for listening IP, port, etc., in openim-msggateway service. |
| **openim-msgtransfer.yml** | Configurations for openim-msgtransfer service. |
| **openim-push.yml** | Configurations for listening IP, port, and offline push settings in openim-push service. |
| **openim-rpc-auth.yml** | Configurations for listening IP, port, and token expiration settings in openim-rpc-auth service. |
| **openim-rpc-conversation.yml** | Configurations for listening IP, port, etc., in openim-rpc-conversation service. |
| **openim-rpc-friend.yml** | Configurations for listening IP, port, etc., in openim-rpc-friend service. |
| **openim-rpc-group.yml** | Configurations for listening IP, port, etc., in openim-rpc-group service. |
| **openim-rpc-msg.yml** | Configurations for listening IP, port, and whether to verify friendship before sending messages in openim-rpc-msg service. |
## Common Configuration Item Modifications
| Configuration Item Modification | Configuration File |
| ----------------------------------------------------- | ----------------------- |
| Using MinIO for image and video file object storage | `minio.yml` |
| Adjusting production environment logs | `log.yml` |
| Verifying friendship before sending messages | `openim-rpc-msg.yml` |
| Modifying secret | `share.yml` |
| Using OSS, COS, AWS, Kodo for image and video storage | `openim-rpc-third.yml` |
| Setting multiple login policy | `openim-msggateway.yml` |
| Setting up offline push | `openim-push.yml` |
## Starting Multiple Instances of an OpenIM Service
To start multiple instances of an OpenIM service, simply increase the corresponding port numbers and modify the `start-config.yml` file in the project root directory. Restart the service to take effect. For example, the configuration to start 2 instances of `openim-rpc-user` is as follows:
```yaml
rpc:
registerIP: ''
listenIP: 0.0.0.0
ports: [ 10110, 10111 ]
prometheus:
enable: true
ports: [ 20100, 20101 ]
```
Modify `start-config.yml`:
```yaml
serviceBinaries:
openim-rpc-user: 2
```

View File

@ -1,18 +1,36 @@
# Username for authentication
username: ''
# Password for authentication
password: ''
# Producer acknowledgment settings
producerAck: ""
# Compression type to use (e.g., none, gzip, snappy)
compressType: "none"
# List of Kafka broker addresses
address: [ localhost:19094 ]
# Kafka topic for Redis integration
toRedisTopic: "toRedis"
# Kafka topic for MongoDB integration
toMongoTopic: "toMongo"
# Kafka topic for push notifications
toPushTopic: "toPush"
# Consumer group ID for Redis topic
toRedisGroupID: redis
# Consumer group ID for MongoDB topic
toMongoGroupID: mongo
# Consumer group ID for push notifications topic
toPushGroupID: push
# TLS (Transport Layer Security) configuration
tls:
# Enable or disable TLS
enableTLS: false
# CA certificate file path
caCrt: ""
# Client certificate file path
clientCrt: ""
# Client key file path
clientKey: ""
# Client key password
clientKeyPwd: ""
# Whether to skip TLS verification (not recommended for production)
insecureSkipVerify: false

View File

@ -1,9 +1,16 @@
# Name of the bucket in MinIO
bucket: "openim"
port: 10005
# Access key ID for MinIO authentication
accessKeyID: "root"
# Secret access key for MinIO authentication
secretAccessKey: "openIM123"
# Session token for MinIO authentication (optional)
sessionToken: ''
internalIP: localhost
externalIP: 150.109.93.151
url: https://image.rentsoft.cn/
# Internal address of the MinIO server
internalAddress: "localhost:10005"
# External address of the MinIO server, accessible from outside. Supports both HTTP and HTTPS using a domain name
externalAddress: "http://external_ip:10005"
# Flag to enable or disable public read access to the bucket
publicRead: false

View File

@ -1,7 +1,14 @@
# URI for database connection, leave empty if using address and credential settings directly
uri: ''
# List of MongoDB server addresses
address: [ localhost:37017 ]
# Name of the database
database: openim_v3
# Username for database authentication
username: openIM
# Password for database authentication
password: openIM123
# Maximum number of connections in the connection pool
maxPoolSize: 100
maxRetry: 10
# Maximum number of retry attempts for a failed database connection
maxRetry: 10

View File

@ -17,32 +17,23 @@
# The options field 'isNotification' indicates if it's a notification.
groupCreated:
isSendMsg: true
# Reliability level of the message sending.
# Set to 1 to send only when online, 2 for guaranteed delivery.
reliabilityLevel: 1
# This setting is effective only when 'isSendMsg' is true.
# It controls whether to count unread messages.
unreadCount: false
# Configuration for offline push notifications.
offlinePush:
# Enables or disables offline push notifications.
enable: false
# Title for the notification when a group is created.
title: "create group title"
# Description for the notification.
desc: "create group desc"
# Additional information for the notification.
ext: "create group ext"
# Content type is not added here.
# Content should use a JSON structure conforming to the protobuf format.
groupInfoSet:
isSendMsg: false
reliabilityLevel: 1

View File

@ -1,4 +1,2 @@
chatRecordsClearTime: "0 2 * * 3"
msgDestructTime: "0 2 * * *"
chatRecordsClearTime: "0 2 * * *"
retainChatRecords: 365
enableCronLocker: false

View File

@ -1,19 +1,30 @@
rpc:
# The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP
registerIP: ''
# List of ports that the RPC service listens on; configuring multiple ports will launch multiple instances. These must match the number of configured prometheus ports
ports: [ 10140 ]
prometheus:
# Enable or disable Prometheus monitoring
enable: true
# List of ports that Prometheus listens on; these must match the number of rpc.ports to ensure correct monitoring setup
ports: [ 20112 ]
# IP address that the RPC/WebSocket service listens on; setting to 0.0.0.0 listens on both internal and external IPs. If left blank, it automatically uses the internal network IP
listenIP: 0.0.0.0
longConnSvr:
# WebSocket listening ports, must match the number of rpc.ports
ports: [ 10001 ]
# Maximum number of WebSocket connections
websocketMaxConnNum: 100000
# Maximum length of the entire WebSocket message packet
websocketMaxMsgLen: 4096
# WebSocket connection handshake timeout in seconds
websocketTimeout: 10
# 1: For Android, iOS, Windows, Mac, and web platforms, only one instance can be online at a time
multiLoginPolicy: 1

View File

@ -1,3 +1,6 @@
prometheus:
# Enable or disable Prometheus monitoring
enable: true
# List of ports that Prometheus listens on; each port corresponds to an instance of monitoring. Ensure these are managed accordingly
# Because four instances have been launched, four ports need to be specified
ports: [ 20108, 20109, 20110, 20111 ]

View File

@ -1,14 +1,20 @@
rpc:
# The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP
registerIP: ''
# IP address that the RPC service listens on; setting to 0.0.0.0 listens on both internal and external IPs. If left blank, it automatically uses the internal network IP
listenIP: 0.0.0.0
# List of ports that the RPC service listens on; configuring multiple ports will launch multiple instances. These must match the number of configured prometheus ports
ports: [ 10170 ]
prometheus:
# Enable or disable Prometheus monitoring
enable: true
# List of ports that Prometheus listens on; these must match the number of rpc.ports to ensure correct monitoring setup
ports: [ 20107 ]
maxConcurrentWorkers: 3
enable: getui
#"Use geTui for offline push notifications, or choose fcm or jpns; corresponding configuration settings must be specified."
enable: "geTui"
geTui:
pushUrl: "https://restapi.getui.com/v2/$appId"
masterSecret: ''
@ -24,6 +30,7 @@ jpns:
pushURL: ''
pushIntent: ''
# iOS system push sound and badge count
iosPush:
pushSound: "xxx"
badgeCount: true

View File

@ -1,13 +1,18 @@
rpc:
# The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP
registerIP: ''
# IP address that the RPC service listens on; setting to 0.0.0.0 listens on both internal and external IPs. If left blank, it automatically uses the internal network IP
listenIP: 0.0.0.0
# List of ports that the RPC service listens on; configuring multiple ports will launch multiple instances. These must match the number of configured prometheus ports
ports: [ 10160 ]
prometheus:
# Enable or disable Prometheus monitoring
enable: true
# List of ports that Prometheus listens on; these must match the number of rpc.ports to ensure correct monitoring setup
ports: [ 20106 ]
tokenPolicy:
#token有效期单位
# Token validity period, in days
expire: 90

View File

@ -1,11 +1,13 @@
rpc:
# The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP
registerIP: ''
# IP address that the RPC service listens on; setting to 0.0.0.0 listens on both internal and external IPs. If left blank, it automatically uses the internal network IP
listenIP: 0.0.0.0
# List of ports that the RPC service listens on; configuring multiple ports will launch multiple instances. These must match the number of configured prometheus ports
ports: [ 10180 ]
prometheus:
# Enable or disable Prometheus monitoring
enable: true
# List of ports that Prometheus listens on; these must match the number of rpc.ports to ensure correct monitoring setup
ports: [ 20105 ]

View File

@ -1,8 +1,13 @@
rpc:
# The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP
registerIP: ''
# IP address that the RPC service listens on; setting to 0.0.0.0 listens on both internal and external IPs. If left blank, it automatically uses the internal network IP
listenIP: 0.0.0.0
# List of ports that the RPC service listens on; configuring multiple ports will launch multiple instances. These must match the number of configured prometheus ports
ports: [ 10120 ]
prometheus:
# Enable or disable Prometheus monitoring
enable: true
# List of ports that Prometheus listens on; these must match the number of rpc.ports to ensure correct monitoring setup
ports: [ 20104 ]

View File

@ -1,9 +1,13 @@
rpc:
# The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP
registerIP: ''
# IP address that the RPC service listens on; setting to 0.0.0.0 listens on both internal and external IPs. If left blank, it automatically uses the internal network IP
listenIP: 0.0.0.0
# List of ports that the RPC service listens on; configuring multiple ports will launch multiple instances. These must match the number of configured prometheus ports
ports: [ 10150 ]
prometheus:
# Enable or disable Prometheus monitoring
enable: true
# List of ports that Prometheus listens on; these must match the number of rpc.ports to ensure correct monitoring setup
ports: [ 20103 ]

View File

@ -1,13 +1,19 @@
rpc:
# The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP
registerIP: ''
# IP address that the RPC service listens on; setting to 0.0.0.0 listens on both internal and external IPs. If left blank, it automatically uses the internal network IP
listenIP: 0.0.0.0
# List of ports that the RPC service listens on; configuring multiple ports will launch multiple instances. These must match the number of configured prometheus ports
ports: [ 10130 ]
prometheus:
# Enable or disable Prometheus monitoring
enable: true
# List of ports that Prometheus listens on; these must match the number of rpc.ports to ensure correct monitoring setup
ports: [ 20102 ]
#发消息是否需要好友验证
# Does sending messages require friend verification
friendVerify: false

View File

@ -1,13 +1,20 @@
rpc:
# The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP
registerIP: ''
# IP address that the RPC service listens on; setting to 0.0.0.0 listens on both internal and external IPs. If left blank, it automatically uses the internal network IP
listenIP: 0.0.0.0
# List of ports that the RPC service listens on; configuring multiple ports will launch multiple instances. These must match the number of configured prometheus ports
ports: [ 10190 ]
prometheus:
# Enable or disable Prometheus monitoring
enable: true
# List of ports that Prometheus listens on; these must match the number of rpc.ports to ensure correct monitoring setup
ports: [ 20101 ]
object:
# Use MinIO as object storage, or set to "cos", "oss", "kodo", "aws", while also configuring the corresponding settings
enable: "minio"
cos:
bucketURL: https://temp-1252357374.cos.ap-chengdu.myqcloud.com
@ -22,19 +29,4 @@ object:
accessKeyID: ''
accessKeySecret: ''
sessionToken: ''
publicRead: false
kodo:
endpoint: "webhook://s3.cn-east-1.qiniucs.com"
bucket: "demo-9999999"
bucketURL: "webhook://your.domain.com"
accessKeyID: ''
accessKeySecret: ''
sessionToken: ''
publicRead: false
aws:
endpoint: "''"
region: "us-east-1"
bucket: "demo-9999999"
accessKeyID: ''
accessKeySecret: ''
publicRead: false
publicRead: false

View File

@ -1,47 +0,0 @@
# 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.
###################### AlertManager Configuration ######################
# AlertManager configuration using environment variables
#
# Resolve timeout
# SMTP configuration for sending alerts
# Templates for email notifications
# Routing configurations for alerts
# Receiver configurations
global:
resolve_timeout: 5m
smtp_from: alert@openim.io
smtp_smarthost: smtp.163.com:465
smtp_auth_username: alert@openim.io
smtp_auth_password: YOURAUTHPASSWORD
smtp_require_tls: false
smtp_hello: xxx监控告警
templates:
- /etc/alertmanager/email.tmpl
route:
group_by: ['alertname']
group_wait: 5s
group_interval: 5s
repeat_interval: 5m
receiver: email
receivers:
- name: email
email_configs:
- to: 'alert@example.com'
html: '{{ template "email.to.html" . }}'
headers: { Subject: "[OPENIM-SERVER]Alarm" }
send_resolved: true

View File

@ -1,552 +0,0 @@
envs:
discovery: zookeeper
###################### Zookeeper ######################
# Zookeeper configuration
# It's not recommended to modify the schema
#
# Zookeeper address
# Zookeeper username
# Zookeeper password
zookeeper:
schema: openim
address: [ 172.28.0.1:12181 ]
username: ''
password: ''
###################### Mongo ######################
# MongoDB configuration
# If uri is not empty, it will be used directly for the MongoDB connection.
# This is a complete MongoDB URI string.
# Example: mongodb://user:password@host1:port1,host2:port2/dbname?options
mongo:
uri: ''
# List of MongoDB server addresses.
# Used for constructing the MongoDB URI if 'uri' above is empty.
# For a standalone setup, specify the address of the single server.
# For a sharded cluster, specify the addresses of the Mongos servers.
# Example: [ '172.28.0.1:37017', '172.28.0.2:37017' ]
# Default MongoDB database name
# Maximum connection pool size
address: [ 172.28.0.1:37017 ]
database: openim_v3
username: openIM
password: openIM123
maxPoolSize: 100
###################### Redis configuration information ######################
# Redis configuration
#
# Username is required only for Redis version 6.0+
redis:
address: [ 172.28.0.1:16379 ]
username: ''
password: openIM123
###################### Kafka configuration information ######################
# Kafka configuration
#
# Kafka username
# Kafka password
# It's not recommended to modify this topic name
# Consumer group ID, it's not recommended to modify
kafka:
username: ''
password: ''
addr: [ 172.28.0.1:19094 ]
latestMsgToRedis:
topic: "latestMsgToRedis"
offlineMsgToMongo:
topic: "offlineMsgToMongoMysql"
msgToPush:
topic: "msgToPush"
consumerGroupID:
msgToRedis: redis
msgToMongo: mongo
msgToMySql: mysql
msgToPush: push
###################### RPC configuration information ######################
# RPC configuration
#
# IP address to register with zookeeper when starting RPC, the IP and corresponding rpcPort should be accessible by api/gateway
# Default listen IP is 0.0.0.0
rpc:
registerIP: ''
listenIP: 0.0.0.0
###################### API configuration information ######################
# API configuration
#
# API service port
# Default listen IP is 0.0.0.0
api:
openImApiPort: [ 10002 ]
listenIP: 0.0.0.0
###################### Object configuration information ######################
# Object storage configuration
#
# Use minio for object storage
# API URL should be accessible by the app
# It's not recommended to modify the bucket name
# Endpoint should be accessible by the app
# Session token
# Configuration for Tencent COS
# Configuration for Aliyun OSS
# apiURL is the address of the api, the access address of the app, use s3 must be configured
# minio.endpoint can be configured as an intranet address,
# minio.signEndpoint is minio public network address
object:
enable: "minio"
apiURL: "http://127.0.0.1:10002"
minio:
bucket: "openim"
endpoint: "http://172.28.0.1:10005"
accessKeyID: "root"
secretAccessKey: "openIM123"
sessionToken: ''
signEndpoint: "http://127.0.0.1:10005"
publicRead: false
cos:
bucketURL: https://temp-1252357374.cos.ap-chengdu.myqcloud.com
secretID: ''
secretKey: ''
sessionToken: ''
publicRead: false
oss:
endpoint: "https://oss-cn-chengdu.aliyuncs.com"
bucket: "demo-9999999"
bucketURL: "https://demo-9999999.oss-cn-chengdu.aliyuncs.com"
accessKeyID: ''
accessKeySecret: ''
sessionToken: ''
publicRead: false
kodo:
endpoint: "http://s3.cn-east-1.qiniucs.com"
bucket: "demo-9999999"
bucketURL: "http://your.domain.com"
accessKeyID: ''
accessKeySecret: ''
sessionToken: ''
publicRead: false
aws:
endpoint: "''" # This might not be necessary unless you're using a custom endpoint
region: "us-east-1"
bucket: "demo-9999999"
accessKeyID: ''
accessKeySecret: ''
publicRead: false
###################### RPC Port Configuration ######################
# RPC service ports
# These ports are passed into the program by the script and are not recommended to modify
# For launching multiple programs, just fill in multiple ports separated by commas
# For example, [10110, 10111]
rpcPort:
openImUserPort: [ 10110 ]
openImFriendPort: [ 10120 ]
openImMessagePort: [ 10130 ]
openImGroupPort: [ 10150 ]
openImAuthPort: [ 10160 ]
openImPushPort: [ 10170 ]
openImConversationPort: [ 10180 ]
openImThirdPort: [ 10190 ]
###################### RPC Register Name Configuration ######################
# RPC service names for registration, it's not recommended to modify these
rpcRegisterName:
openImUserName: User
openImFriendName: Friend
openImMsgName: Msg
openImPushName: Push
openImMessageGatewayName: MessageGateway
openImGroupName: Group
openImAuthName: Auth
openImConversationName: Conversation
openImThirdName: Third
###################### Log Configuration ######################
# Log configuration
#
# Storage directory
# Log rotation time
# Maximum number of logs to retain
# Log level, 6 means all levels
# Whether to output to stdout
# Whether to output in json format
# Whether to include stack trace in logs
log:
storageLocation: /data/workspaces/open-im-server/_output/logs/
rotationTime: 24
remainRotationCount: 2
remainLogLevel: 6
isStdout: false
isJson: false
withStack: false
###################### Variables definition ######################
# Long connection server configuration
#
# Websocket port for msg_gateway
# Maximum number of websocket connections
# Maximum length of websocket request package
# Websocket connection handshake timeout
longConnSvr:
openImWsPort: [ 10001 ]
websocketMaxConnNum: 100000
openImMessageGatewayPort: [ 10140 ]
websocketMaxMsgLen: 4096
websocketTimeout: 10
# Push notification service configuration
#
# Use GeTui for push notifications
# GeTui offline push configuration
# FCM offline push configuration
# Account file, place it in the config directory
# JPush configuration, modify these after applying in JPush backend
push:
enable: getui
geTui:
pushUrl: "https://restapi.getui.com/v2/$appId"
masterSecret: ''
appKey: ''
intent: ''
channelID: ''
channelName: ''
fcm:
serviceAccount: "x.json"
jpns:
appKey: ''
masterSecret: ''
pushUrl: ''
pushIntent: ''
# App manager configuration
#
# Built-in app manager user IDs
# Built-in app manager nicknames
# Attention, this configure is discarded. If you have used him before, configure your own
manager:
userID:
nickname:
# 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
# For each platform(Android, iOS, Windows, Mac, web), only one can be online at a time
multiLoginPolicy: 1
# Whether to store messages in MySQL, messages in MySQL are only used for management background
chatPersistenceMysql: true
# Message cache timeout in seconds, it's not recommended to modify
msgCacheTimeout: 86400
# Whether to enable read receipts for group chat
groupMessageHasReadReceiptEnable: true
# Whether to enable read receipts for single chat
singleMessageHasReadReceiptEnable: true
# MongoDB offline message retention period in days
retainChatRecords: 365
# Schedule to clear expired messages(older than retainChatRecords days) in MongoDB every Wednesday at 2am
# This deletion is just for cleaning up disk usage according to previous configuration retainChatRecords, no notification will be sent
chatRecordsClearTime: "0 2 * * 3"
# Schedule to auto delete messages every day at 2am
# This deletion is for messages that have been retained for more than msg_destruct_time (seconds) in the conversation field
msgDestructTime: "0 2 * * *"
# Secret key
secret: openIM123
# Token policy
#
# Token expiration period in days
tokenPolicy:
expire: 90
# Message verification policy
#
# Whether to verify friendship when sending messages
messageVerify:
friendVerify: false
# iOS push notification configuration
#
# iOS push notification sound
# Whether to count badge
# Whether it's production environment
iosPush:
pushSound: "xxx"
badgeCount: true
production: false
###################### Third-party service configuration ######################
# Callback configuration
#
# Callback URL
# Whether to enable this callback event
# Timeout in seconds
# Whether to continue execution if callback fails
callback:
url: "http://127.0.0.1:10008/callbackExample"
beforeSendSingleMsg:
enable: false
timeout: 5
failedContinue: true
beforeUpdateUserInfoEx:
enable: false
timeout: 5
failedContinue: true
afterUpdateUserInfoEx:
enable: false
timeout: 5
failedContinue: true
afterSendSingleMsg:
enable: false
timeout: 5
failedContinue: true
beforeSendGroupMsg:
enable: false
timeout: 5
failedContinue: true
afterSendGroupMsg:
enable: false
timeout: 5
failedContinue: true
msgModify:
enable: false
timeout: 5
failedContinue: true
userOnline:
enable: false
timeout: 5
failedContinue: true
userOffline:
enable: false
timeout: 5
failedContinue: true
userKickOff:
enable: false
timeout: 5
failedContinue: true
offlinePush:
enable: false
timeout: 5
failedContinue: true
onlinePush:
enable: false
timeout: 5
failedContinue: true
superGroupOnlinePush:
enable: false
timeout: 5
failedContinue: true
beforeAddFriend:
enable: false
timeout: 5
failedContinue: true
beforeUpdateUserInfo:
enable: false
timeout: 5
failedContinue: true
beforeCreateGroup:
enable: false
timeout: 5
failedContinue: true
afterCreateGroup:
enable: false
timeout: 5
failedContinue: true
beforeMemberJoinGroup:
enable: false
timeout: 5
failedContinue: true
beforeSetGroupMemberInfo:
enable: false
timeout: 5
failedContinue: true
afterSetGroupMemberInfo:
enable: false
timeout: 5
failedContinue: true
setMessageReactionExtensions:
enable: false
timeout: 5
failedContinue: true
quitGroup:
enable: false
timeout: 5
failedContinue: true
killGroupMember:
enable: false
timeout: 5
failedContinue: true
dismissGroup:
enable: false
timeout: 5
failedContinue: true
joinGroup:
enable: false
timeout: 5
failedContinue: true
groupMsgRead:
enable: false
timeout: 5
failedContinue: true
singleMsgRead:
enable: false
timeout: 5
failedContinue: true
updateUserInfo:
enable: false
timeout: 5
failedContinue: true
beforeUserRegister:
enable: false
timeout: 5
failedContinue: true
afterUserRegister:
enable: false
timeout: 5
failedContinue: true
transferGroupOwner:
enable: false
timeout: 5
failedContinue: true
beforeSetFriendRemark:
enable: false
timeout: 5
failedContinue: true
afterSetFriendRemark:
enable: false
timeout: 5
failedContinue: true
afterGroupMsgRead:
enable: false
timeout: 5
failedContinue: true
afterGroupMsgRevoke:
enable: false
timeout: 5
failedContinue: true
afterJoinGroup:
enable: false
timeout: 5
failedContinue: true
beforeInviteUserToGroup:
enable: false
timeout: 5
failedContinue: true
joinGroupAfter:
enable: false
timeout: 5
failedContinue: true
setGroupInfoAfter:
enable: false
timeout: 5
failedContinue: true
setGroupInfoBefore:
enable: false
timeout: 5
failedContinue: true
revokeMsgAfter:
enable: false
timeout: 5
failedContinue: true
addBlackBefore:
enable: false
timeout: 5
failedContinue: true
addFriendAfter:
enable: false
timeout: 5
failedContinue: true
addFriendAgreeBefore:
enable: false
timeout: 5
failedContinue: true
deleteFriendAfter:
enable: false
timeout: 5
failedContinue: true
importFriendsBefore:
enable: false
timeout: 5
failedContinue: true
importFriendsAfter:
enable: false
timeout: 5
failedContinue: true
removeBlackAfter:
enable: false
timeout: 5
failedContinue: true
###################### Prometheus ######################
# Prometheus configuration for various services
# 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
prometheus:
enable: true
grafanaUrl: http://127.0.0.1:13000/
apiPrometheusPort: [20100]
userPrometheusPort: [ 20110 ]
friendPrometheusPort: [ 20120 ]
messagePrometheusPort: [ 20130 ]
messageGatewayPrometheusPort: [ 20140 ]
groupPrometheusPort: [ 20150 ]
authPrometheusPort: [ 20160 ]
pushPrometheusPort: [ 20170 ]
conversationPrometheusPort: [ 20230 ]
rtcPrometheusPort: [ 21300 ]
thirdPrometheusPort: [ 21301 ]
messageTransferPrometheusPort: [ 21400, 21401, 21402, 21403 ] # List of ports
###################### LocalCache configuration information ######################
# topic: redis subscriber channel
# slotNum: number of slots, multiple slots can prevent too many keys from competing for a lock
# slotSize: number of slots, the number of cached keys per slot, the overall cache quantity is slotNum * slotSize
# successExpire: successful cache time seconds
# failedExpire: failed cache time seconds
# disable local caching and annotate topic, slotNum, and slotSize
localCache:
user:
topic: DELETE_CACHE_USER
slotNum: 100
slotSize: 2000
successExpire: 300
failedExpire: 5
group:
topic: DELETE_CACHE_GROUP
slotNum: 100
slotSize: 2000
successExpire: 300
failedExpire: 5
friend:
topic: DELETE_CACHE_FRIEND
slotNum: 100
slotSize: 2000
successExpire: 300
failedExpire: 5
conversation:
topic: DELETE_CACHE_CONVERSATION
slotNum: 100
slotSize: 2000
successExpire: 300
failedExpire: 5

View File

@ -1,16 +0,0 @@
{{ define "email.to.html" }}
{{ range .Alerts }}
<!-- Begin of OpenIM Alert -->
<div style="border:1px solid #ccc; padding:10px; margin-bottom:10px;">
<h3>OpenIM Alert</h3>
<p><strong>Alert Program:</strong> Prometheus Alert</p>
<p><strong>Severity Level:</strong> {{ .Labels.severity }}</p>
<p><strong>Alert Type:</strong> {{ .Labels.alertname }}</p>
<p><strong>Affected Host:</strong> {{ .Labels.instance }}</p>
<p><strong>Affected Service:</strong> {{ .Labels.job }}</p>
<p><strong>Alert Subject:</strong> {{ .Annotations.summary }}</p>
<p><strong>Trigger Time:</strong> {{ .StartsAt.Format "2006-01-02 15:04:05" }}</p>
</div>
<!-- End of OpenIM Alert -->
{{ end }}
{{ end }}

View File

@ -1,237 +0,0 @@
# Copyright © 2024 OpenIM. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -----------------------------------------------------------------------------
# General Configuration
# This section contains general configuration options for the entire environment.
# These options can be set via environment variables. If both environment variables
# and settings in this .env file exist, the environment variables take precedence.
# -----------------------------------------------------------------------------
# ==========================
# General Configuration
# ==========================
# These settings apply to the overall environment.
# Data storage directory for persistent data.
# Example: DATA_DIR=/path/to/data
DATA_DIR=/data/workspaces/open-im-server
# Docker image registry. Uncomment the preferred one.
# Options: ghcr.io/openimsdk, openim, registry.cn-hangzhou.aliyuncs.com/openimsdk
# IMAGE_REGISTRY="ghcr.io/openimsdk"
# IMAGE_REGISTRY="openim"
# IMAGE_REGISTRY="registry.cn-hangzhou.aliyuncs.com/openimsdk"
IMAGE_REGISTRY=ghcr.io/openimsdk
# ======================================
# ========= Network Configuration ======
# ======================================
# Subnet for the Docker network.
# Default: DOCKER_BRIDGE_SUBNET=172.28.0.0/16
DOCKER_BRIDGE_SUBNET=172.28.0.0/16
# Set and specify the IP addresses of some containers. Generally speaking,
# you do not need to modify these configurations to facilitate debugging
DOCKER_BRIDGE_GATEWAY=172.28.0.1
MONGO_NETWORK_ADDRESS=172.28.0.2
REDIS_NETWORK_ADDRESS=172.28.0.3
KAFKA_NETWORK_ADDRESS=172.28.0.4
ZOOKEEPER_NETWORK_ADDRESS=172.28.0.5
MINIO_NETWORK_ADDRESS=172.28.0.6
OPENIM_WEB_NETWORK_ADDRESS=172.28.0.7
OPENIM_SERVER_NETWORK_ADDRESS=172.28.0.8
OPENIM_CHAT_NETWORK_ADDRESS=172.28.0.9
PROMETHEUS_NETWORK_ADDRESS=172.28.0.10
GRAFANA_NETWORK_ADDRESS=172.28.0.11
NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.12
OPENIM_ADMIN_FRONT_NETWORK_ADDRESS=172.28.0.13
ALERT_MANAGER_NETWORK_ADDRESS=172.28.0.14
# ==============================================================================
# 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=127.0.0.1
# ----- ZooKeeper Configuration -----
# Port for ZooKeeper service.
# Default: ZOOKEEPER_PORT=12181
ZOOKEEPER_PORT=12181
# MongoDB service port configuration.
# Default: MONGO_PORT=37017
MONGO_PORT=37017
# Password for MongoDB admin user. Used for service authentication.
# Default: MONGO_PASSWORD=openIM123
MONGO_PASSWORD=openIM123
# Username for a regular OpenIM user in MongoDB.
# Default: MONGO_OPENIM_USERNAME=openIM
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
MONGO_MAX_POOL_SIZE=100
# ----- Redis Configuration -----
# Port on which Redis in-memory data structure store is running.
# Default: REDIS_PORT=16379
REDIS_PORT=16379
# Password to authenticate with the Redis service.
# Default: REDIS_PASSWORD=openIM123
REDIS_PASSWORD=openIM123
# Kakfa username to authenticate with the Kafka service.
# KAFKA_USERNAME=''
# Port on which Kafka distributed streaming platform is running.
# Default: KAFKA_PORT=19092
KAFKA_PORT=19094
# Topic in Kafka for storing the latest messages in Redis.
# Default: KAFKA_LATESTMSG_REDIS_TOPIC=latestMsgToRedis
KAFKA_LATESTMSG_REDIS_TOPIC=latestMsgToRedis
# MINIO_PORT
# ----------
# MINIO_PORT sets the port for the MinIO object storage service.
# Upon changing this port, the MinIO endpoint URLs in the config/config.yaml file must be updated
# to reflect this change. The endpoints include both the 'endpoint' and 'signEndpoint'
# under the MinIO configuration.
#
# Default: MINIO_PORT=10005
MINIO_PORT=10005
# Access key to authenticate with the MinIO service.
# Default: MINIO_ACCESS_KEY=root
# MINIO_ACCESS_KEY=root
# Secret key corresponding to the access key for MinIO authentication.
# Default: MINIO_SECRET_KEY=openIM123
MINIO_SECRET_KEY=openIM123
# ----- Prometheus Configuration -----
# Port on which Prometheus service is running.
# Default: PROMETHEUS_PORT=19090
PROMETHEUS_PORT=19090
# ----- Grafana Configuration -----
# Port on which Grafana service is running.
# Default: GRAFANA_PORT=13000
GRAFANA_PORT=13000
# ======================================
# ============ OpenIM Web ===============
# ======================================
# Port on which OpenIM web service is running.
# Default: OPENIM_WEB_PORT=11001
OPENIM_WEB_PORT=11001
# ======================================
# ========= OpenIM Server ==============
# ======================================
# Port for the OpenIM WebSockets.
# Default: OPENIM_WS_PORT=10001
OPENIM_WS_PORT=10001
# 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
API_OPENIM_PORT=10002
# ======================================
# ========== OpenIM Chat ===============
# ======================================
# Branch name for OpenIM chat.
# Default: CHAT_IMAGE_VERSION=main
CHAT_IMAGE_VERSION=main
# Port for the OpenIM chat API.
# Default: OPENIM_CHAT_API_PORT=10008
OPENIM_CHAT_API_PORT=10008
# Port for the OpenIM admin API.
# Default: OPENIM_ADMIN_API_PORT=10009
OPENIM_ADMIN_API_PORT=10009
# ======================================
# ========== OpenIM Admin ==============
# ======================================
# Branch name for OpenIM server.
# Default: SERVER_IMAGE_VERSION=main
SERVER_IMAGE_VERSION=main
# Port for the node exporter.
# Default: NODE_EXPORTER_PORT=19100
NODE_EXPORTER_PORT=19100
# Port for the prometheus.
# Default: PROMETHEUS_PORT=19090
PROMETHEUS_PORT=19090
# Port for the grafana.
# Default: GRAFANA_PORT=13000
GRAFANA_PORT=13000
# Port for the admin front.
# Default: OPENIM_ADMIN_FRONT_PORT=11002
OPENIM_ADMIN_FRONT_PORT=11002
# Port for the alertmanager.
# Default: ALERT_MANAGER_PORT=19093
ALERT_MANAGER_PORT=19093

View File

@ -1,36 +0,0 @@
# 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.
groups:
- name: instance_down
rules:
- alert: InstanceDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minutes."
- name: database_insert_failure_alerts
rules:
- alert: DatabaseInsertFailed
expr: (increase(msg_insert_redis_failed_total[5m]) > 0) or (increase(msg_insert_mongo_failed_total[5m]) > 0)
for: 1m
labels:
severity: critical
annotations:
summary: "Increase in MsgInsertRedisFailedCounter or MsgInsertMongoFailedCounter detected"
description: "Either MsgInsertRedisFailedCounter or MsgInsertMongoFailedCounter has increased in the last 5 minutes, indicating failures in message insert operations to Redis or MongoDB,maybe the redis or mongodb is crash."

View File

@ -1,354 +0,0 @@
# 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.
# Determines if a message should be sent. If set to false, it triggers a silent sync without a message. If true, it requires triggering a conversation.
# For rpc notification, send twice: once as a message and once as a notification.
# The options field 'isNotification' indicates if it's a notification.
groupCreated:
isSendMsg: true
# Reliability level of the message sending.
# Set to 1 to send only when online, 2 for guaranteed delivery.
reliabilityLevel: 1
# This setting is effective only when 'isSendMsg' is true.
# It controls whether to count unread messages.
unreadCount: false
# Configuration for offline push notifications.
offlinePush:
# Enables or disables offline push notifications.
enable: false
# Title for the notification when a group is created.
title: "create group title"
# Description for the notification.
desc: "create group desc"
# Additional information for the notification.
ext: "create group ext"
# Content type is not added here.
# Content should use a JSON structure conforming to the protobuf format.
groupInfoSet:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "groupInfoSet title"
desc: "groupInfoSet desc"
ext: "groupInfoSet ext"
joinGroupApplication:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "joinGroupApplication title"
desc: "joinGroupApplication desc"
ext: "joinGroupApplication ext"
memberQuit:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "memberQuit title"
desc: "memberQuit desc"
ext: "memberQuit ext"
groupApplicationAccepted:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "groupApplicationAccepted title"
desc: "groupApplicationAccepted desc"
ext: "groupApplicationAccepted ext"
groupApplicationRejected:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: " title"
desc: " desc"
ext: " ext"
groupOwnerTransferred:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "groupOwnerTransferred title"
desc: "groupOwnerTransferred desc"
ext: "groupOwnerTransferred ext"
memberKicked:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "memberKicked title"
desc: "memberKicked desc"
ext: "memberKicked ext"
memberInvited:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "memberInvited title"
desc: "memberInvited desc"
ext: "memberInvited ext"
memberEnter:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "memberEnter title"
desc: "memberEnter desc"
ext: "memberEnter ext"
groupDismissed:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "groupDismissed title"
desc: "groupDismissed desc"
ext: "groupDismissed ext"
groupMuted:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "groupMuted title"
desc: "groupMuted desc"
ext: "groupMuted ext"
groupCancelMuted:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "groupCancelMuted title"
desc: "groupCancelMuted desc"
ext: "groupCancelMuted ext"
defaultTips:
tips: "group Cancel Muted"
groupMemberMuted:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "groupMemberMuted title"
desc: "groupMemberMuted desc"
ext: "groupMemberMuted ext"
groupMemberCancelMuted:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "groupMemberCancelMuted title"
desc: "groupMemberCancelMuted desc"
ext: "groupMemberCancelMuted ext"
groupMemberInfoSet:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "groupMemberInfoSet title"
desc: "groupMemberInfoSet desc"
ext: "groupMemberInfoSet ext"
groupInfoSetAnnouncement:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "groupInfoSetAnnouncement title"
desc: "groupInfoSetAnnouncement desc"
ext: "groupInfoSetAnnouncement ext"
groupInfoSetName:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "groupInfoSetName title"
desc: "groupInfoSetName desc"
ext: "groupInfoSetName ext"
#############################friend#################################
friendApplicationAdded:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "Somebody applies to add you as a friend"
desc: "Somebody applies to add you as a friend"
ext: "Somebody applies to add you as a friend"
friendApplicationApproved:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: true
title: "Someone applies to add your friend application"
desc: "Someone applies to add your friend application"
ext: "Someone applies to add your friend application"
friendApplicationRejected:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: true
title: "Someone rejected your friend application"
desc: "Someone rejected your friend application"
ext: "Someone rejected your friend application"
friendAdded:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: true
title: "We have become friends"
desc: "We have become friends"
ext: "We have become friends"
friendDeleted:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: true
title: "deleted a friend"
desc: "deleted a friend"
ext: "deleted a friend"
friendRemarkSet:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: true
title: "Your friend's profile has been changed"
desc: "Your friend's profile has been changed"
ext: "Your friend's profile has been changed"
blackAdded:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: true
title: "blocked a user"
desc: "blocked a user"
ext: "blocked a user"
blackDeleted:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: true
title: "Remove a blocked user"
desc: "Remove a blocked user"
ext: "Remove a blocked user"
friendInfoUpdated:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: true
title: "friend info updated"
desc: "friend info updated"
ext: "friend info updated"
#####################user#########################
userInfoUpdated:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: true
title: "Remove a blocked user"
desc: "Remove a blocked user"
ext: "Remove a blocked user"
userStatusChanged:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: false
title: "user status changed"
desc: "user status changed"
ext: "user status changed"
#####################conversation#########################
conversationChanged:
isSendMsg: false
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: true
title: "conversation changed"
desc: "conversation changed"
ext: "conversation changed"
conversationSetPrivate:
isSendMsg: true
reliabilityLevel: 1
unreadCount: false
offlinePush:
enable: true
title: "burn after reading"
desc: "burn after reading"
ext: "burn after reading"

View File

@ -1,173 +0,0 @@
upstream im_msg_gateway{
server 127.0.0.1:10001; #IM Message server address Multiple can be specified according to the deployment
}
upstream im_api{
server 127.0.0.1:10002; #IM Group user api server address Multiple can be specified according to the deployment
}
upstream im_grafana{
server 127.0.0.1:10007; #IM Statistical server address The machine where docker-compose starts
}
upstream im_chat_api{
server 127.0.0.1:10008; #IM Business version login registration server address Multiple can be specified according to the deployment
}
upstream im_admin_api{
server 127.0.0.1:10009; #IM The admin address of the commercial version can specify multiple units according to the deployment situation
}
upstream im_open_rtc{
server 127.0.0.1:7880; #rtc Audio and video call server address Multiple devices can be specified according to the deployment
}
upstream minio_s3_2 {
least_conn;
server 127.0.0.1:10005;
}
upstream minio_console_2 {
least_conn;
server 127.0.0.1:9090;
}
server {
listen 443;
server_name your-domain.com; #your-domain.com
ssl on;
ssl_certificate /etc/nginx/conf.d/ssl/your-domain.com.crt; #2 Certificate
ssl_certificate_key /etc/nginx/conf.d/ssl/your-domain.com.key; #3 Certificate
ssl_session_timeout 5m;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/wasm;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";
error_page 405 =200 $uri;
default_type application/wasm;
location /{ #web demo
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-NginX-Proxy true;
root /data1/online/Pc-Web-Demo/build/; # web im static resource storage path
index index.html;
try_files $uri $uri/ /index.html;
}
location /msg_gateway { #10001 ws
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://im_msg_gateway/;
}
location ^~/api/ { #10002 api
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Request-Api $scheme://$host/api;
proxy_pass http://im_api/;
}
location ^~/grafana/ { #10007 prometheus
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://im_grafana/;
}
location ^~/chat/ { #10008 im_chat_api
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://im_chat_api/;
}
location ^~/complete_admin/ { #10009 admin
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://im_admin_api/;
}
location ^~/open_rtc/ { #7880 rtc
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://im_open_rtc/;
}
}
server {
listen 80;
server_name test-web.rentsoft.cn ; #1 web im end domain name
rewrite ^(.*)$ https://${server_name}$1 permanent;
}
server {
listen 443;
server_name your-domain.com; #your-domain.com
ssl on;
ssl_certificate /etc/nginx/conf.d/ssl/your-domain.com.crt; #Certificate
ssl_certificate_key /etc/nginx/conf.d/ssl/your-domain.com.key; #Certificate
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/wasm;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";
# Allow special characters in headers
ignore_invalid_headers off;
# Allow any size file to be uploaded.
# Set to a value such as 1000m; to restrict file size to a specific value
client_max_body_size 0;
# Disable buffering
proxy_buffering off;
proxy_request_buffering off;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300;
# Default is HTTP/1, keepalive is only enabled in HTTP/1.1
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://minio_s3_2; # This uses the upstream directive definition to load balance
}
location /minio/ui {
rewrite ^/minio/ui/(.*) /$1 break;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
# This is necessary to pass the correct IP to be hashed
real_ip_header X-Real-IP;
proxy_connect_timeout 300;
# To support websockets in MinIO versions released after January 2023
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
chunked_transfer_encoding off;
proxy_pass http://minio_console_2; # This uses the upstream directive definition to load balance
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,99 +0,0 @@
# 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.
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets: ['172.28.0.1:19093']
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
- "instance-down-rules.yml"
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label "job='job_name'"" to any timeseries scraped from this config.
# Monitored information captured by prometheus
- job_name: 'node-exporter'
static_configs:
- targets: [ '172.28.0.1:19100' ]
labels:
namespace: 'default'
# prometheus fetches application services
- job_name: 'openimserver-openim-api'
static_configs:
- targets: [ '172.28.0.1:20100' ]
labels:
namespace: 'default'
- job_name: 'openimserver-openim-msggateway'
static_configs:
- targets: [ '172.28.0.1:20140' ]
labels:
namespace: 'default'
- job_name: 'openimserver-openim-msgtransfer'
static_configs:
- targets: [ 172.28.0.1:21400, 172.28.0.1:21401, 172.28.0.1:21402, 172.28.0.1:21403 ]
labels:
namespace: 'default'
- job_name: 'openimserver-openim-push'
static_configs:
- targets: [ '172.28.0.1:20170' ]
labels:
namespace: 'default'
- job_name: 'openimserver-openim-rpc-auth'
static_configs:
- targets: [ '172.28.0.1:20160' ]
labels:
namespace: 'default'
- job_name: 'openimserver-openim-rpc-conversation'
static_configs:
- targets: [ '172.28.0.1:20230' ]
labels:
namespace: 'default'
- job_name: 'openimserver-openim-rpc-friend'
static_configs:
- targets: [ '172.28.0.1:20120' ]
labels:
namespace: 'default'
- job_name: 'openimserver-openim-rpc-group'
static_configs:
- targets: [ '172.28.0.1:20150' ]
labels:
namespace: 'default'
- job_name: 'openimserver-openim-rpc-msg'
static_configs:
- targets: [ '172.28.0.1:20130' ]
labels:
namespace: 'default'
- job_name: 'openimserver-openim-rpc-third'
static_configs:
- targets: [ '172.28.0.1:21301' ]
labels:
namespace: 'default'
- job_name: 'openimserver-openim-rpc-user'
static_configs:
- targets: [ '172.28.0.1:20110' ]
labels:
namespace: 'default'

View File

@ -51,6 +51,7 @@ services:
ports:
- "12181:2181"
environment:
#JVMFLAGS: "-Xms32m -Xmx128m"
TZ: "Asia/Shanghai"
ALLOW_ANONYMOUS_LOGIN: "yes"
restart: always
@ -70,6 +71,7 @@ services:
command: >
bash -c "/opt/bitnami/scripts/kafka/run.sh & /opt/bitnami/kafka/create-topic.sh; wait"
environment:
#KAFKA_HEAP_OPTS: "-Xms128m -Xmx256m"
TZ: Asia/Shanghai
KAFKA_CFG_NODE_ID: 0
KAFKA_CFG_PROCESS_ROLES: controller,broker
@ -119,3 +121,4 @@ services:
- openim

View File

@ -1,87 +1,4 @@
# This is a comment.
# Each line is a file pattern followed by one or more owners.
# CODEOWNERS file
# This file is used to specify the individuals who are required to review changes in this repository.
# README files
README.md @openimsdk/openim @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
# Contributing guidelines
CONTRIBUTING.md @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
# License files
LICENSE @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
# Makefile
Makefile @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence,
# @cubxxw and @openimsdk/bot will be requested for
# review when someone opens a pull request.
* @openimsdk/openim @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
# Order is important; the last matching pattern takes the most
# precedence. When someone opens a pull request that only
# modifies JS files, only @js-owner and not the global
# owner(s) will be requested for a review.
*.js @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
# You can also use email addresses if you prefer. They'll be
# used to look up users just like we do for commit author
# emails.
*.go 3293172751nss@gmail.com
*.py 3293172751nss@gmail.com
# Teams can be specified as code owners as well. Teams should
# be identified in the format @org/team-name. Teams must have
# explicit write access to the repository. In this example,
# the OpenIMSDK team in the github organization owns all .txt files.
*.txt @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
# The `docs/*` pattern will match files like
# `docs/getting-started.md` but not further nested files like
# `docs/build-app/troubleshooting.md`.
docs/* 3293172751nss@gmail.com @openimsdk/bot @skiffer-git
# In this example, @octocat owns any file in an apps directory
# anywhere in your repository.
api/ @openimsdk/openim @cubxxw @skiffer-git
# This is a comment.
# Each line is a file pattern followed by one or more owners.
# CHANGELOG file
CHANGELOG/* @cubxxw @skiffer-git
# _output directory
_output/* @skiffer-git
# bin directory
bin/* @skiffer-git @FGadvancer
# cmd directory
cmd/*
# config directory
config/* @skiffer-git
# internal directory
internal/ @openimsdk/openim @skiffer-git @FGadvancer
tools @openimsdk/openim @openimsdk/bot @cubxxw @skiffer-git @FGadvancer
# logs directory
logs/* @skiffer-git @FGadvancer
# pkg directory
pkg/a2r @openimsdk/openim @skiffer-git @cubxxw @openimsdk/bot
# scripts directory
scripts/template/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
scripts/enterprise/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
scripts/githooks/* @openimsdk/openim @cubxxw @skiffer-git @FGadvancer
scripts/lib/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
scripts/make-rules/* @openimsdk/openim @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
# test directory
test/mongo @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
test/mysql @FGadvancer @cubxxw @skiffer-git @openimsdk/bot
* @Bloomingg @FGadvancer @skiffer-git @withchao

15
go.mod
View File

@ -1,6 +1,6 @@
module github.com/openimsdk/open-im-server/v3
go 1.20
go 1.21.2
require (
firebase.google.com/go v3.13.0+incompatible
@ -13,9 +13,8 @@ require (
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
github.com/mitchellh/mapstructure v1.5.0
github.com/openimsdk/localcache v0.0.1
github.com/openimsdk/protocol v0.0.64
github.com/openimsdk/tools v0.0.47-alpha.42
github.com/openimsdk/protocol v0.0.65
github.com/openimsdk/tools v0.0.49-alpha.19
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.18.0
github.com/stretchr/testify v1.9.0
@ -32,9 +31,10 @@ require (
github.com/IBM/sarama v1.43.0
github.com/fatih/color v1.14.1
github.com/go-redis/redis v6.15.9+incompatible
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/kelindar/bitmap v1.5.2
github.com/likexian/gokit v0.25.13
github.com/openimsdk/gomake v0.0.6
github.com/openimsdk/gomake v0.0.13
github.com/redis/go-redis/v9 v9.4.0
github.com/robfig/cron/v3 v3.0.1
github.com/shirou/gopsutil v3.21.11+incompatible
@ -74,7 +74,7 @@ require (
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-zookeeper/zk v1.0.3 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect
@ -83,7 +83,6 @@ require (
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
@ -173,5 +172,3 @@ require (
golang.org/x/crypto v0.21.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
replace github.com/openimsdk/localcache => ./pkg/localcache

35
go.sum
View File

@ -22,10 +22,13 @@ github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mo
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
@ -43,6 +46,7 @@ github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5P
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ=
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -66,12 +70,15 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
@ -90,6 +97,7 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
@ -124,8 +132,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@ -137,11 +145,13 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
@ -194,6 +204,7 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kelindar/bitmap v1.5.2 h1:XwX7CTvJtetQZ64zrOkApoZZHBJRkjE23NfqUALA/HE=
@ -209,7 +220,9 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
@ -266,12 +279,12 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/openimsdk/gomake v0.0.6 h1:bJmQWDHBj8PQ7oGJ2SL3Gsx0k5CdI/BPfGzlGcV105s=
github.com/openimsdk/gomake v0.0.6/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
github.com/openimsdk/protocol v0.0.64 h1:OrjSs4CgKN9VLvJvrAsc37O7Ru0E0VllXZQSmG/ab7U=
github.com/openimsdk/protocol v0.0.64/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8=
github.com/openimsdk/tools v0.0.47-alpha.42 h1:wM6t9otTLhXECq8aQcYaZGvBgo/ZAmbNTqVt3g3NHGg=
github.com/openimsdk/tools v0.0.47-alpha.42/go.mod h1:P4oGP1Pd+d4ctbLD5U/XQTgl8yu8Hd3skx640Fr69ko=
github.com/openimsdk/gomake v0.0.13 h1:xLDe/moqgWpRoptHzI4packAWzs4C16b+sVY+txNJp0=
github.com/openimsdk/gomake v0.0.13/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
github.com/openimsdk/protocol v0.0.65 h1:SPT9qyUsFRTTKSKb/FjpS+xr6sxz/Kbnu+su1bxYagc=
github.com/openimsdk/protocol v0.0.65/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8=
github.com/openimsdk/tools v0.0.49-alpha.19 h1:CbASL0yefRSVAmWPVeRnhF7wZKd6umLfz31CIhEgrBs=
github.com/openimsdk/tools v0.0.49-alpha.19/go.mod h1:g7mkHXYUPi0/8aAX8VPMHpnb3hqdV69Jph+bXOGvvNM=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
@ -282,6 +295,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@ -298,6 +312,7 @@ github.com/redis/go-redis/v9 v9.4.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@ -376,6 +391,7 @@ go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFu
go.opentelemetry.io/otel/metric v1.23.0 h1:pazkx7ss4LFVVYSxYew7L5I6qvLXHA0Ap2pwV+9Cnpo=
go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo=
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/trace v1.23.0 h1:37Ik5Ib7xfYVb4V1UtnT97T1jI+AoIYkJyPkuL4iJgI=
go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
@ -383,6 +399,7 @@ go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
@ -489,6 +506,7 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.165.0 h1:zd5d4JIIIaYYsfVy1HzoXYZ9rWCSBxxAglbczzo7Bgc=
google.golang.org/api v0.165.0/go.mod h1:2OatzO7ZDQsoS7IFf3rvsE17/TldiU3F/zxFHeqUB5o=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@ -526,6 +544,7 @@ google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGm
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=

View File

@ -64,10 +64,6 @@ func Start(ctx context.Context, index int, config *Config) error {
return errs.WrapMsg(err, "failed to register discovery service")
}
if err = client.CreateRpcRootNodes(config.Share.RpcRegisterName.GetServiceNames()); err != nil {
return errs.WrapMsg(err, "failed to create RPC root nodes")
}
var (
netDone = make(chan struct{}, 1)
netErr error

View File

@ -80,11 +80,6 @@ func Start(ctx context.Context, index int, config *Config) error {
if err != nil {
return err
}
if err := client.CreateRpcRootNodes(config.Share.RpcRegisterName.GetServiceNames()); err != nil {
return err
}
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
//todo MsgCacheTimeout

View File

@ -83,7 +83,7 @@ type OnlineHistoryRedisConsumerHandler struct {
func NewOnlineHistoryRedisConsumerHandler(kafkaConf *config.Kafka, database controller.CommonMsgDatabase,
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient) (*OnlineHistoryRedisConsumerHandler, error) {
historyConsumerGroup, err := kafka.NewMConsumerGroup(kafkaConf.Build(), kafkaConf.ToRedisGroupID, []string{kafkaConf.ToRedisTopic})
historyConsumerGroup, err := kafka.NewMConsumerGroup(kafkaConf.Build(), kafkaConf.ToRedisGroupID, []string{kafkaConf.ToRedisTopic}, true)
if err != nil {
return nil, err
}
@ -394,7 +394,7 @@ func (och *OnlineHistoryRedisConsumerHandler) ConsumeClaim(
break
}
}
log.ZDebug(context.Background(), "online new session msg come", "highWaterMarkOffset",
log.ZInfo(context.Background(), "online new session msg come", "highWaterMarkOffset",
claim.HighWaterMarkOffset(), "topic", claim.Topic(), "partition", claim.Partition())
var (

View File

@ -33,7 +33,7 @@ type OnlineHistoryMongoConsumerHandler struct {
}
func NewOnlineHistoryMongoConsumerHandler(kafkaConf *config.Kafka, database controller.CommonMsgDatabase) (*OnlineHistoryMongoConsumerHandler, error) {
historyConsumerGroup, err := kafka.NewMConsumerGroup(kafkaConf.Build(), kafkaConf.ToMongoGroupID, []string{kafkaConf.ToMongoTopic})
historyConsumerGroup, err := kafka.NewMConsumerGroup(kafkaConf.Build(), kafkaConf.ToMongoGroupID, []string{kafkaConf.ToMongoTopic}, true)
if err != nil {
return nil, err
}

View File

@ -26,7 +26,7 @@ import (
)
const (
geTUI = "getui"
geTUI = "geTui"
firebase = "fcm"
jPush = "jpush"
)

View File

@ -60,7 +60,7 @@ func NewConsumerHandler(config *Config, offlinePusher offlinepush.OfflinePusher,
var consumerHandler ConsumerHandler
var err error
consumerHandler.pushConsumerGroup, err = kafka.NewMConsumerGroup(config.KafkaConfig.Build(), config.KafkaConfig.ToPushGroupID,
[]string{config.KafkaConfig.ToPushTopic})
[]string{config.KafkaConfig.ToPushTopic}, true)
if err != nil {
return nil, err
}
@ -96,7 +96,7 @@ func (c *ConsumerHandler) handleMs2PsChat(ctx context.Context, msg []byte) {
var err error
switch msgFromMQ.MsgData.SessionType {
case constant.ReadGroupChatType:
err = c.Push2SuperGroup(ctx, pbData.MsgData.GroupID, pbData.MsgData)
err = c.Push2Group(ctx, pbData.MsgData.GroupID, pbData.MsgData)
default:
var pushUserIDList []string
isSenderSync := datautil.GetSwitchFromOptions(pbData.MsgData.Options, constant.IsSenderSync)
@ -108,7 +108,7 @@ func (c *ConsumerHandler) handleMs2PsChat(ctx context.Context, msg []byte) {
err = c.Push2User(ctx, pushUserIDList, pbData.MsgData)
}
if err != nil {
log.ZError(ctx, "push failed", err, "msg", pbData.String())
log.ZWarn(ctx, "push failed", err, "msg", pbData.String())
}
}
@ -179,7 +179,7 @@ func (c *ConsumerHandler) shouldPushOffline(_ context.Context, msg *sdkws.MsgDat
return true
}
func (c *ConsumerHandler) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws.MsgData) (err error) {
func (c *ConsumerHandler) Push2Group(ctx context.Context, groupID string, msg *sdkws.MsgData) (err error) {
log.ZDebug(ctx, "Get super group msg from msg_transfer and push msg", "msg", msg.String(), "groupID", groupID)
var pushToUserIDs []string
if err = c.webhookBeforeGroupOnlinePush(ctx, &c.config.WebhooksConfig.BeforeGroupOnlinePush, groupID, msg,
@ -259,7 +259,7 @@ func (c *ConsumerHandler) groupMessagesHandler(ctx context.Context, groupID stri
*pushToUserIDs = append(*pushToUserIDs, kickedUsers...)
case constant.GroupDismissedNotification:
if msgprocessor.IsNotification(msgprocessor.GetConversationIDByMsg(msg)) { // 消息先到,通知后到
if msgprocessor.IsNotification(msgprocessor.GetConversationIDByMsg(msg)) {
var tips sdkws.GroupDismissedTips
if unmarshalNotificationElem(msg.Content, &tips) != nil {
return err

View File

@ -536,3 +536,46 @@ func (c *conversationServer) GetConversationNotReceiveMessageUserIDs(ctx context
}
return &pbconversation.GetConversationNotReceiveMessageUserIDsResp{UserIDs: userIDs}, nil
}
func (c *conversationServer) UpdateConversation(ctx context.Context, req *pbconversation.UpdateConversationReq) (*pbconversation.UpdateConversationResp, error) {
m := make(map[string]any)
if req.RecvMsgOpt != nil {
m["recv_msg_opt"] = req.RecvMsgOpt.Value
}
if req.AttachedInfo != nil {
m["attached_info"] = req.AttachedInfo.Value
}
if req.Ex != nil {
m["ex"] = req.Ex.Value
}
if req.IsPinned != nil {
m["is_pinned"] = req.IsPinned.Value
}
if req.GroupAtType != nil {
m["group_at_type"] = req.GroupAtType.Value
}
if req.MsgDestructTime != nil {
m["msg_destruct_time"] = req.MsgDestructTime.Value
}
if req.IsMsgDestruct != nil {
m["is_msg_destruct"] = req.IsMsgDestruct.Value
}
if req.BurnDuration != nil {
m["burn_duration"] = req.BurnDuration.Value
}
if req.IsPrivateChat != nil {
m["is_private_chat"] = req.IsPrivateChat.Value
}
if req.MinSeq != nil {
m["min_seq"] = req.MinSeq.Value
}
if req.MaxSeq != nil {
m["max_seq"] = req.MaxSeq.Value
}
if len(m) > 0 {
if err := c.conversationDatabase.UpdateUsersConversationField(ctx, req.UserIDs, req.ConversationID, m); err != nil {
return nil, err
}
}
return &pbconversation.UpdateConversationResp{}, nil
}

77
internal/rpc/msg/clear.go Normal file
View File

@ -0,0 +1,77 @@
package msg
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
"github.com/openimsdk/protocol/conversation"
"github.com/openimsdk/protocol/msg"
"github.com/openimsdk/protocol/wrapperspb"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"strings"
"time"
)
func (m *msgServer) ClearMsg(ctx context.Context, req *msg.ClearMsgReq) (_ *msg.ClearMsgResp, err error) {
if err := authverify.CheckAdmin(ctx, m.config.Share.IMAdminUserID); err != nil {
return nil, err
}
if req.Timestamp > time.Now().UnixMilli() {
return nil, errs.ErrArgs.WrapMsg("request millisecond timestamp error")
}
var (
docNum int
msgNum int
start = time.Now()
)
clearMsg := func(ctx context.Context) (bool, error) {
conversationSeqs := make(map[string]struct{})
defer func() {
req := &conversation.UpdateConversationReq{
MsgDestructTime: wrapperspb.Int64(time.Now().UnixMilli()),
}
for conversationID := range conversationSeqs {
req.ConversationID = conversationID
if err := m.Conversation.UpdateConversations(ctx, req); err != nil {
log.ZError(ctx, "update conversation max seq failed", err, "conversationID", conversationID, "msgDestructTime", req.MsgDestructTime)
}
}
}()
msgs, err := m.MsgDatabase.GetBeforeMsg(ctx, req.Timestamp, 100)
if err != nil {
return false, err
}
if len(msgs) == 0 {
return false, nil
}
for _, msg := range msgs {
index, err := m.MsgDatabase.DeleteDocMsgBefore(ctx, req.Timestamp, msg)
if err != nil {
return false, err
}
if len(index) == 0 {
return false, errs.ErrInternalServer.WrapMsg("delete doc msg failed")
}
docNum++
msgNum += len(index)
conversationID := msg.DocID[:strings.LastIndex(msg.DocID, ":")]
if _, ok := conversationSeqs[conversationID]; !ok {
conversationSeqs[conversationID] = struct{}{}
}
}
return true, nil
}
for {
keep, err := clearMsg(ctx)
if err != nil {
log.ZError(ctx, "clear msg failed", err, "docNum", docNum, "msgNum", msgNum, "cost", time.Since(start))
return nil, err
}
if !keep {
log.ZInfo(ctx, "clear msg success", "docNum", docNum, "msgNum", msgNum, "cost", time.Since(start))
break
}
log.ZInfo(ctx, "clearing message", "docNum", docNum, "msgNum", msgNum, "cost", time.Since(start))
}
return &msg.ClearMsgResp{}, nil
}

View File

@ -18,7 +18,6 @@ import (
"context"
"fmt"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"net/url"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
@ -29,7 +28,6 @@ import (
"github.com/openimsdk/tools/db/mongoutil"
"github.com/openimsdk/tools/db/redisutil"
"github.com/openimsdk/tools/discovery"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/s3"
"github.com/openimsdk/tools/s3/cos"
"github.com/openimsdk/tools/s3/minio"
@ -38,7 +36,6 @@ import (
)
type thirdServer struct {
apiURL string
thirdDatabase controller.ThirdDatabase
s3dataBase controller.S3Database
userRpcClient rpcclient.UserRpcClient
@ -73,18 +70,6 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
if err != nil {
return err
}
apiURL := config.MinioConfig.URL
if apiURL == "" {
return errs.Wrap(fmt.Errorf("api is empty"))
}
if _, err := url.Parse(config.MinioConfig.URL); err != nil {
return err
}
if apiURL[len(apiURL)-1] != '/' {
apiURL += "/"
}
apiURL += "object/"
// Select the oss method according to the profile policy
enable := config.RpcConfig.Object.Enable
var o s3.Interface
@ -103,7 +88,6 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
}
cache.InitLocalCache(&config.LocalCacheConfig)
third.RegisterThirdServer(server, &thirdServer{
apiURL: apiURL,
thirdDatabase: controller.NewThirdDatabase(cache.NewThirdCache(rdb), logdb),
userRpcClient: rpcclient.NewUserRpcClient(client, config.Share.RpcRegisterName.User, config.Share.IMAdminUserID),
s3dataBase: controller.NewS3Database(rdb, o, s3db),

View File

@ -1,149 +0,0 @@
// 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.
package tools
import (
"context"
"math/rand"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
"github.com/openimsdk/protocol/sdkws"
"github.com/openimsdk/tools/log"
"github.com/openimsdk/tools/mcontext"
"github.com/openimsdk/tools/utils/idutil"
"github.com/openimsdk/tools/utils/stringutil"
)
// func (c *MsgTool) ConversationsDestructMsgs() {
// log.ZInfo(context.Background(), "start msg destruct cron task")
// ctx := mcontext.NewCtx(utils.GetSelfFuncName())
// conversations, err := c.conversationDatabase.GetConversationIDsNeedDestruct(ctx)
// if err != nil {
// log.ZError(ctx, "get conversation id need destruct failed", err)
// return
// }
// log.ZDebug(context.Background(), "nums conversations need destruct", "nums", len(conversations))
// for _, conversation := range conversations {
// ctx = mcontext.NewCtx(utils.GetSelfFuncName() + "-" + utils.OperationIDGenerator() + "-" + conversation.ConversationID + "-" + conversation.OwnerUserID)
// log.ZDebug(
// ctx,
// "UserMsgsDestruct",
// "conversationID",
// conversation.ConversationID,
// "ownerUserID",
// conversation.OwnerUserID,
// "msgDestructTime",
// conversation.MsgDestructTime,
// "lastMsgDestructTime",
// conversation.LatestMsgDestructTime,
// )
// now := time.Now()
// seqs, err := c.msgDatabase.UserMsgsDestruct(ctx, conversation.OwnerUserID, conversation.ConversationID, conversation.MsgDestructTime, conversation.LatestMsgDestructTime)
// if err != nil {
// log.ZError(ctx, "user msg destruct failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
// continue
// }
// if len(seqs) > 0 {
// if err := c.conversationDatabase.UpdateUsersConversationField(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]interface{}{"latest_msg_destruct_time": now}); err
// != nil {
// log.ZError(ctx, "updateUsersConversationField failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
// continue
// }
// if err := c.msgNotificationSender.UserDeleteMsgsNotification(ctx, conversation.OwnerUserID, conversation.ConversationID, seqs); err != nil {
// log.ZError(ctx, "userDeleteMsgsNotification failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
// }
// }
// }
//}
func (c *MsgTool) ConversationsDestructMsgs() {
log.ZInfo(context.Background(), "start msg destruct cron task")
ctx := mcontext.NewCtx(stringutil.GetSelfFuncName())
num, err := c.conversationDatabase.GetAllConversationIDsNumber(ctx)
if err != nil {
log.ZError(ctx, "GetAllConversationIDsNumber failed", err)
return
}
const batchNum = 50
log.ZDebug(ctx, "GetAllConversationIDsNumber", "num", num)
if num == 0 {
return
}
count := int(num/batchNum + num/batchNum/2)
if count < 1 {
count = 1
}
maxPage := 1 + num/batchNum
if num%batchNum != 0 {
maxPage++
}
for i := 0; i < count; i++ {
pageNumber := rand.Int63() % maxPage
pagination := &sdkws.RequestPagination{
PageNumber: int32(pageNumber),
ShowNumber: batchNum,
}
conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, pagination)
if err != nil {
log.ZError(ctx, "PageConversationIDs failed", err, "pageNumber", pageNumber)
continue
}
log.ZError(ctx, "PageConversationIDs failed", err, "pageNumber", pageNumber, "conversationIDsNum", len(conversationIDs), "conversationIDs", conversationIDs)
if len(conversationIDs) == 0 {
continue
}
conversations, err := c.conversationDatabase.GetConversationsByConversationID(ctx, conversationIDs)
if err != nil {
log.ZError(ctx, "GetConversationsByConversationID failed", err, "conversationIDs", conversationIDs)
continue
}
temp := make([]*relation.ConversationModel, 0, len(conversations))
for i, conversation := range conversations {
if conversation.IsMsgDestruct && conversation.MsgDestructTime != 0 && (time.Now().Unix() > (conversation.MsgDestructTime+conversation.LatestMsgDestructTime.Unix()+8*60*60)) ||
conversation.LatestMsgDestructTime.IsZero() {
temp = append(temp, conversations[i])
}
}
for _, conversation := range temp {
ctx = mcontext.NewCtx(stringutil.GetSelfFuncName() + "-" + idutil.OperationIDGenerator() + "-" + conversation.ConversationID + "-" + conversation.OwnerUserID)
log.ZDebug(
ctx,
"UserMsgsDestruct",
"conversationID",
conversation.ConversationID,
"ownerUserID",
conversation.OwnerUserID,
"msgDestructTime",
conversation.MsgDestructTime,
"lastMsgDestructTime",
conversation.LatestMsgDestructTime,
)
now := time.Now()
seqs, err := c.msgDatabase.UserMsgsDestruct(ctx, conversation.OwnerUserID, conversation.ConversationID, conversation.MsgDestructTime, conversation.LatestMsgDestructTime)
if err != nil {
log.ZError(ctx, "user msg destruct failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
continue
}
if len(seqs) > 0 {
if err := c.conversationDatabase.UpdateUsersConversationField(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]any{"latest_msg_destruct_time": now}); err != nil {
log.ZError(ctx, "updateUsersConversationField failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
continue
}
c.msgNotificationSender.UserDeleteMsgsNotification(ctx, conversation.OwnerUserID, conversation.ConversationID, seqs)
}
}
}
}

View File

@ -16,105 +16,61 @@ package tools
import (
"context"
"fmt"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/tools/db/redisutil"
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
"github.com/openimsdk/protocol/msg"
"github.com/openimsdk/tools/mcontext"
"github.com/openimsdk/tools/mw"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"os"
"os/signal"
"syscall"
"time"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"github.com/redis/go-redis/v9"
"github.com/robfig/cron/v3"
)
type CronTaskConfig struct {
CronTask config.CronTask
RedisConfig config.Redis
MongodbConfig config.Mongo
ZookeeperConfig config.ZooKeeper
Share config.Share
KafkaConfig config.Kafka
}
func Start(ctx context.Context, config *CronTaskConfig) error {
log.CInfo(ctx, "CRON-TASK server is initializing", "chatRecordsClearTime",
config.CronTask.ChatRecordsClearTime, "msgDestructTime", config.CronTask.MsgDestructTime)
msgTool, err := InitMsgTool(ctx, config)
log.CInfo(ctx, "CRON-TASK server is initializing", "chatRecordsClearTime", config.CronTask.ChatRecordsClearTime, "msgDestructTime", config.CronTask.RetainChatRecords)
if config.CronTask.RetainChatRecords < 1 {
return errs.New("msg destruct time must be greater than 1").Wrap()
}
client, err := kdisc.NewDiscoveryRegister(&config.ZookeeperConfig, &config.Share)
if err != nil {
return errs.WrapMsg(err, "failed to register discovery service")
}
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
ctx = mcontext.SetOpUserID(ctx, config.Share.IMAdminUserID[0])
conn, err := client.GetConn(ctx, config.Share.RpcRegisterName.Msg)
if err != nil {
return err
}
msgTool.convertTools()
rdb, err := redisutil.NewRedisClient(ctx, config.RedisConfig.Build())
if err != nil {
return err
}
// register cron tasks
var crontab = cron.New()
_, err = crontab.AddFunc(config.CronTask.ChatRecordsClearTime,
cronWrapFunc(config, rdb, "cron_clear_msg_and_fix_seq", msgTool.AllConversationClearMsgAndFixSeq))
if err != nil {
return errs.Wrap(err)
}
_, err = crontab.AddFunc(config.CronTask.MsgDestructTime,
cronWrapFunc(config, rdb, "cron_conversations_destruct_msgs", msgTool.ConversationsDestructMsgs))
if err != nil {
return errs.WrapMsg(err, "cron_conversations_destruct_msgs")
}
// start crontab
crontab.Start()
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGTERM)
<-sigs
// stop crontab, Wait for the running task to exit.
cronCtx := crontab.Stop()
select {
case <-cronCtx.Done():
// graceful exit
case <-time.After(15 * time.Second):
// forced exit on timeout
}
return nil
}
// netlock redis lock.
func netlock(rdb redis.UniversalClient, key string, ttl time.Duration) bool {
value := "used"
ok, err := rdb.SetNX(context.Background(), key, value, ttl).Result() // nolint
if err != nil {
// when err is about redis server, return true.
return false
}
return ok
}
func cronWrapFunc(config *CronTaskConfig, rdb redis.UniversalClient, key string, fn func()) func() {
enableCronLocker := config.CronTask.EnableCronLocker
return func() {
// if don't enable cron-locker, call fn directly.
if !enableCronLocker {
fn()
cli := msg.NewMsgClient(conn)
crontab := cron.New()
clearFunc := func() {
now := time.Now()
deltime := now.Add(-time.Hour * 24 * time.Duration(config.CronTask.RetainChatRecords))
ctx := mcontext.SetOperationID(ctx, fmt.Sprintf("cron_%d_%d", os.Getpid(), deltime.UnixMilli()))
log.ZInfo(ctx, "clear chat records", "deltime", deltime, "timestamp", deltime.UnixMilli())
if _, err := cli.ClearMsg(ctx, &msg.ClearMsgReq{Timestamp: deltime.UnixMilli()}); err != nil {
log.ZError(ctx, "cron clear chat records failed", err, "deltime", deltime, "cont", time.Since(now))
return
}
// when acquire redis lock, call fn().
if netlock(rdb, key, 5*time.Second) {
fn()
}
log.ZInfo(ctx, "cron clear chat records success", "deltime", deltime, "cont", time.Since(now))
}
if _, err := crontab.AddFunc(config.CronTask.ChatRecordsClearTime, clearFunc); err != nil {
return errs.Wrap(err)
}
log.ZInfo(ctx, "start cron task", "chatRecordsClearTime", config.CronTask.ChatRecordsClearTime)
crontab.Start()
<-ctx.Done()
return nil
}

View File

@ -1,113 +0,0 @@
// 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.
package tools
import (
"testing"
"time"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/assert"
)
func TestDisLock(t *testing.T) {
rdb := redis.NewClient(&redis.Options{})
defer rdb.Close()
assert.Equal(t, true, netlock(rdb, "cron-1", 1*time.Second))
// if exists, get false
assert.Equal(t, false, netlock(rdb, "cron-1", 1*time.Second))
time.Sleep(2 * time.Second)
// wait for key on timeout, get true
assert.Equal(t, true, netlock(rdb, "cron-1", 2*time.Second))
// set different key
assert.Equal(t, true, netlock(rdb, "cron-2", 2*time.Second))
}
//func TestCronWrapFunc(t *testing.T) {
// rdb := redis.NewClient(&redis.Options{})
// defer rdb.Close()
//
// once := sync.Once{}
// done := make(chan struct{}, 1)
// cb := func() {
// once.Do(func() {
// close(done)
// })
// }
//
// start := time.Now()
// key := fmt.Sprintf("cron-%v", rand.Int31())
// crontab := cron.New(cron.WithSeconds())
// crontab.AddFunc("*/1 * * * * *", cronWrapFunc(config.NewGlobalConfig(), rdb, key, cb))
// crontab.Start()
// <-done
//
// dur := time.Since(start)
// assert.LessOrEqual(t, dur.Seconds(), float64(2*time.Second))
// crontab.Stop()
//}
//
//func TestCronWrapFuncWithNetlock(t *testing.T) {
// conf, err := initCfg()
// if err != nil {
// panic(err)
// }
// conf.EnableCronLocker = true
// rdb := redis.NewClient(&redis.Options{})
// defer rdb.Close()
//
// done := make(chan string, 10)
//
// crontab := cron.New(cron.WithSeconds())
//
// key := fmt.Sprintf("cron-%v", rand.Int31())
// crontab.AddFunc("*/1 * * * * *", cronWrapFunc(conf, rdb, key, func() {
// done <- "host1"
// }))
// crontab.AddFunc("*/1 * * * * *", cronWrapFunc(conf, rdb, key, func() {
// done <- "host2"
// }))
// crontab.Start()
//
// time.Sleep(12 * time.Second)
// // the ttl of netlock is 5s, so expected value is 2.
// assert.Equal(t, len(done), 2)
//
// crontab.Stop()
//}
//
//func initCfg() (*config.GlobalConfig, error) {
// const (
// defaultCfgPath = "../../../../../config/config.yaml"
// )
//
// cfgPath := flag.String("c", defaultCfgPath, "Path to the configuration file")
// data, err := os.ReadFile(*cfgPath)
// if err != nil {
// return nil, errs.WrapMsg(err, "ReadFile unmarshal failed")
// }
//
// conf := config.NewGlobalConfig()
// err = yaml.Unmarshal(data, &conf)
// if err != nil {
// return nil, errs.WrapMsg(err, "InitConfig unmarshal failed")
// }
// return conf, nil
//}

View File

@ -1,226 +0,0 @@
// 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.
package tools
import (
"context"
"fmt"
"github.com/openimsdk/open-im-server/v3/internal/rpc/msg"
"math"
"math/rand"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
"github.com/openimsdk/open-im-server/v3/pkg/util/conversationutil"
"github.com/openimsdk/protocol/sdkws"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"github.com/openimsdk/tools/mcontext"
"github.com/openimsdk/tools/utils/stringutil"
"github.com/redis/go-redis/v9"
)
type MsgTool struct {
msgDatabase controller.CommonMsgDatabase
conversationDatabase controller.ConversationDatabase
userDatabase controller.UserDatabase
groupDatabase controller.GroupDatabase
msgNotificationSender *msg.MsgNotificationSender
config *CronTaskConfig
}
func NewMsgTool(msgDatabase controller.CommonMsgDatabase, userDatabase controller.UserDatabase,
groupDatabase controller.GroupDatabase, conversationDatabase controller.ConversationDatabase,
msgNotificationSender *msg.MsgNotificationSender, config *CronTaskConfig,
) *MsgTool {
return &MsgTool{
msgDatabase: msgDatabase,
userDatabase: userDatabase,
groupDatabase: groupDatabase,
conversationDatabase: conversationDatabase,
msgNotificationSender: msgNotificationSender,
config: config,
}
}
func InitMsgTool(ctx context.Context, config *CronTaskConfig) (*MsgTool, error) {
ch := make(chan int)
<-ch
//mgocli, err := mongoutil.NewMongoDB(ctx, config.MongodbConfig.Build())
//if err != nil {
// return nil, err
//}
//rdb, err := redisutil.NewRedisClient(ctx, config.RedisConfig.Build())
//if err != nil {
// return nil, err
//}
//discov, err := kdisc.NewDiscoveryRegister(&config.ZookeeperConfig, &config.Share)
//if err != nil {
// return nil, err
//}
//discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
//userDB, err := mgo.NewUserMongo(mgocli.GetDB())
//if err != nil {
// return nil, err
//}
////msgDatabase, err := controller.InitCommonMsgDatabase(rdb, mgocli.GetDB(), config)
//if err != nil {
// return nil, err
//}
//userMongoDB := mgo.NewUserMongoDriver(mgocli.GetDB())
//userDatabase := controller.NewUserDatabase(
// userDB,
// cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt()),
// mgocli.GetTx(),
// userMongoDB,
//)
//groupDB, err := mgo.NewGroupMongo(mgocli.GetDB())
//if err != nil {
// return nil, err
//}
//groupMemberDB, err := mgo.NewGroupMember(mgocli.GetDB())
//if err != nil {
// return nil, err
//}
//groupRequestDB, err := mgo.NewGroupRequestMgo(mgocli.GetDB())
//if err != nil {
// return nil, err
//}
//conversationDB, err := mgo.NewConversationMongo(mgocli.GetDB())
//if err != nil {
// return nil, err
//}
//groupDatabase := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, mgocli.GetTx(), nil)
//conversationDatabase := controller.NewConversationDatabase(
// conversationDB,
// cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB),
// mgocli.GetTx(),
//)
//msgRpcClient := rpcclient.NewMessageRpcClient(discov, config.Share.RpcRegisterName.Msg)
//msgNotificationSender := notification.NewMsgNotificationSender(config, rpcclient.WithRpcClient(&msgRpcClient))
//msgTool := NewMsgTool(msgDatabase, userDatabase, groupDatabase, conversationDatabase, msgNotificationSender, config)
//return msgTool, nil
return nil, nil
}
// func (c *MsgTool) AllConversationClearMsgAndFixSeq() {
// ctx := mcontext.NewCtx(utils.GetSelfFuncName())
// log.ZInfo(ctx, "============================ start del cron task ============================")
// conversationIDs, err := c.conversationDatabase.GetAllConversationIDs(ctx)
// if err != nil {
// log.ZError(ctx, "GetAllConversationIDs failed", err)
// return
// }
// for _, conversationID := range conversationIDs {
// conversationIDs = append(conversationIDs, utils.GetNotificationConversationIDByConversationID(conversationID))
// }
// c.ClearConversationsMsg(ctx, conversationIDs)
// log.ZInfo(ctx, "============================ start del cron finished ============================")
//}
func (c *MsgTool) AllConversationClearMsgAndFixSeq() {
ctx := mcontext.NewCtx(stringutil.GetSelfFuncName())
log.ZInfo(ctx, "============================ start del cron task ============================")
num, err := c.conversationDatabase.GetAllConversationIDsNumber(ctx)
if err != nil {
log.ZError(ctx, "GetAllConversationIDsNumber failed", err)
return
}
const batchNum = 50
log.ZDebug(ctx, "GetAllConversationIDsNumber", "num", num)
if num == 0 {
return
}
count := int(num/batchNum + num/batchNum/2)
if count < 1 {
count = 1
}
maxPage := 1 + num/batchNum
if num%batchNum != 0 {
maxPage++
}
for i := 0; i < count; i++ {
pageNumber := rand.Int63() % maxPage
pagination := &sdkws.RequestPagination{
PageNumber: int32(pageNumber),
ShowNumber: batchNum,
}
conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, pagination)
if err != nil {
log.ZError(ctx, "PageConversationIDs failed", err, "pageNumber", pageNumber)
continue
}
log.ZDebug(ctx, "PageConversationIDs failed", "pageNumber", pageNumber, "conversationIDsNum", len(conversationIDs), "conversationIDs", conversationIDs)
if len(conversationIDs) == 0 {
continue
}
c.ClearConversationsMsg(ctx, conversationIDs)
}
log.ZInfo(ctx, "============================ start del cron finished ============================")
}
func (c *MsgTool) ClearConversationsMsg(ctx context.Context, conversationIDs []string) {
for _, conversationID := range conversationIDs {
if err := c.msgDatabase.DeleteConversationMsgsAndSetMinSeq(ctx, conversationID, int64(c.config.CronTask.RetainChatRecords*24*60*60)); err != nil {
log.ZError(ctx, "DeleteUserSuperGroupMsgsAndSetMinSeq failed", err, "conversationID",
conversationID, "DBRetainChatRecords", c.config.CronTask.RetainChatRecords)
}
if err := c.checkMaxSeq(ctx, conversationID); err != nil {
log.ZError(ctx, "fixSeq failed", err, "conversationID", conversationID)
}
}
}
func (c *MsgTool) checkMaxSeqWithMongo(ctx context.Context, conversationID string, maxSeqCache int64) error {
minSeqMongo, maxSeqMongo, err := c.msgDatabase.GetMongoMaxAndMinSeq(ctx, conversationID)
if err != nil {
return err
}
if math.Abs(float64(maxSeqMongo-maxSeqCache)) > 10 {
err = fmt.Errorf("cache max seq and mongo max seq is diff > 10, maxSeqMongo:%d,minSeqMongo:%d,maxSeqCache:%d,conversationID:%s", maxSeqMongo, minSeqMongo, maxSeqCache, conversationID)
return errs.Wrap(err)
}
return nil
}
func (c *MsgTool) checkMaxSeq(ctx context.Context, conversationID string) error {
maxSeq, err := c.msgDatabase.GetMaxSeq(ctx, conversationID)
if err != nil {
if errs.Unwrap(err) == redis.Nil {
return nil
}
return err
}
if err := c.checkMaxSeqWithMongo(ctx, conversationID, maxSeq); err != nil {
return err
}
return nil
}
func (c *MsgTool) FixAllSeq(ctx context.Context) error {
conversationIDs, err := c.conversationDatabase.GetAllConversationIDs(ctx)
if err != nil {
return err
}
for _, conversationID := range conversationIDs {
conversationIDs = append(conversationIDs, conversationutil.GetNotificationConversationIDByConversationID(conversationID))
}
for _, conversationID := range conversationIDs {
if err := c.checkMaxSeq(ctx, conversationID); err != nil {
log.ZWarn(ctx, "fixSeq failed", err, "conversationID", conversationID)
}
}
fmt.Println("fix all seq finished")
return nil
}

View File

@ -1,46 +0,0 @@
// 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.
package tools
import (
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
"github.com/openimsdk/protocol/constant"
"github.com/openimsdk/tools/log"
"github.com/openimsdk/tools/mcontext"
)
func (c *MsgTool) convertTools() {
ctx := mcontext.NewCtx("convert")
conversationIDs, err := c.conversationDatabase.GetAllConversationIDs(ctx)
if err != nil {
log.ZError(ctx, "get all conversation ids failed", err)
return
}
for _, conversationID := range conversationIDs {
conversationIDs = append(conversationIDs, msgprocessor.GetNotificationConversationIDByConversationID(conversationID))
}
_, userIDs, err := c.userDatabase.GetAllUserID(ctx, nil)
if err != nil {
log.ZError(ctx, "get all user ids failed", err)
return
}
log.ZDebug(ctx, "all userIDs", "len userIDs", len(userIDs))
for _, userID := range userIDs {
conversationIDs = append(conversationIDs, msgprocessor.GetConversationIDBySessionType(constant.SingleChatType, userID, userID))
conversationIDs = append(conversationIDs, msgprocessor.GetNotificationConversationID(constant.SingleChatType, userID, userID))
}
log.ZDebug(ctx, "all conversationIDs", "len userIDs", len(conversationIDs))
c.msgDatabase.ConvertMsgsDocLen(ctx, conversationIDs)
}

View File

@ -6,22 +6,12 @@ package main
import (
"github.com/openimsdk/gomake/mageutil"
"os"
"strings"
)
var Default = Build
func Build() {
platforms := os.Getenv("PLATFORMS")
if platforms == "" {
platforms = mageutil.DetectPlatform()
}
for _, platform := range strings.Split(platforms, " ") {
mageutil.CompileForPlatform(platform)
}
mageutil.PrintGreen("All binaries under cmd and tools were successfully compiled.")
mageutil.Build()
}
func Start() {

View File

@ -46,7 +46,6 @@ func IsAppManagerUid(ctx context.Context, imAdminUserID []string) bool {
}
func CheckAdmin(ctx context.Context, imAdminUserID []string) error {
if datautil.Contain(mcontext.GetOpUserID(ctx), imAdminUserID...) {
return nil
}

View File

@ -34,11 +34,8 @@ func NewCronTaskCmd() *CronTaskCmd {
ret := &CronTaskCmd{cronTaskConfig: &cronTaskConfig}
ret.configMap = map[string]any{
OpenIMCronTaskCfgFileName: &cronTaskConfig.CronTask,
RedisConfigFileName: &cronTaskConfig.RedisConfig,
MongodbConfigFileName: &cronTaskConfig.MongodbConfig,
ZookeeperConfigFileName: &cronTaskConfig.ZookeeperConfig,
ShareFileName: &cronTaskConfig.Share,
KafkaConfigFileName: &cronTaskConfig.KafkaConfig,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)

View File

@ -15,16 +15,11 @@
package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/tools"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
type MsgUtilsCmd struct {
cobra.Command
MsgTool *tools.MsgTool
}
func (m *MsgUtilsCmd) AddUserIDFlag() {
@ -146,27 +141,7 @@ func NewSeqCmd() *SeqCmd {
func (s *SeqCmd) GetSeqCmd() *cobra.Command {
s.Command.Run = func(cmdLines *cobra.Command, args []string) {
_, err := tools.InitMsgTool(context.Background(), nil)
if err != nil {
program.ExitWithError(err)
}
userID := s.getUserIDFlag(cmdLines)
superGroupID := s.getSuperGroupIDFlag(cmdLines)
// beginSeq := s.getBeginSeqFlag(cmdLines)
// limit := s.getLimitFlag(cmdLines)
if userID != "" {
// seq, err := msgTool.s(context.Background(), userID)
if err != nil {
panic(err)
}
// println(seq)
} else if superGroupID != "" {
// seq, err := msgTool.GetSuperGroupSeq(context.Background(), superGroupID)
if err != nil {
panic(err)
}
// println(seq)
}
}
return &s.Command
}

View File

@ -15,13 +15,13 @@
package config
import (
"fmt"
"github.com/openimsdk/tools/db/mongoutil"
"github.com/openimsdk/tools/db/redisutil"
"github.com/openimsdk/tools/mq/kafka"
"github.com/openimsdk/tools/s3/cos"
"github.com/openimsdk/tools/s3/minio"
"github.com/openimsdk/tools/s3/oss"
"strings"
"time"
)
@ -52,13 +52,11 @@ type Log struct {
type Minio struct {
Bucket string `mapstructure:"bucket"`
Port int `mapstructure:"port"`
AccessKeyID string `mapstructure:"accessKeyID"`
SecretAccessKey string `mapstructure:"secretAccessKey"`
SessionToken string `mapstructure:"sessionToken"`
InternalIP string `mapstructure:"internalIP"`
ExternalIP string `mapstructure:"externalIP"`
URL string `mapstructure:"url"`
InternalAddress string `mapstructure:"internalAddress"`
ExternalAddress string `mapstructure:"externalAddress"`
PublicRead bool `mapstructure:"publicRead"`
}
@ -108,9 +106,7 @@ type API struct {
type CronTask struct {
ChatRecordsClearTime string `mapstructure:"chatRecordsClearTime"`
MsgDestructTime string `mapstructure:"msgDestructTime"`
RetainChatRecords int `mapstructure:"retainChatRecords"`
EnableCronLocker bool `yaml:"enableCronLocker"`
}
type OfflinePushConfig struct {
@ -476,17 +472,23 @@ func (k *Kafka) Build() *kafka.Config {
},
}
}
func (m *Minio) Build() *minio.Config {
formatEndpoint := func(address string) string {
if strings.HasPrefix(address, "http://") || strings.HasPrefix(address, "https://") {
return address
}
return "http://" + address
}
return &minio.Config{
Bucket: m.Bucket,
Endpoint: fmt.Sprintf("http://%s:%d", m.InternalIP, m.Port),
AccessKeyID: m.AccessKeyID,
SecretAccessKey: m.SecretAccessKey,
SessionToken: m.SessionToken,
SignEndpoint: fmt.Sprintf("http://%s:%d", m.ExternalIP, m.Port),
PublicRead: m.PublicRead,
Endpoint: formatEndpoint(m.InternalAddress),
SignEndpoint: formatEndpoint(m.ExternalAddress),
}
}
func (c *Cos) Build() *cos.Config {
return &cos.Config{

View File

@ -31,6 +31,8 @@ func TestLoadOpenIMRpcUserConfig(t *testing.T) {
var user User
err := LoadConfig("../../../config/openim-rpc-user.yml", "IMENV_OPENIM_RPC_USER", &user)
assert.Nil(t, err)
//export IMENV_OPENIM_RPC_USER_RPC_LISTENIP="0.0.0.0"
assert.Equal(t, "0.0.0.0", user.RPC.ListenIP)
assert.Equal(t, []int{10110}, user.RPC.Ports)
//export IMENV_OPENIM_RPC_USER_RPC_PORTS="10110,10111,10112"
assert.Equal(t, []int{10110, 10111, 10112}, user.RPC.Ports)
}

View File

@ -1 +1 @@
3.6.0
3.7.0

View File

@ -17,6 +17,8 @@ package controller
import (
"context"
"encoding/json"
"errors"
"strings"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
@ -102,6 +104,10 @@ type CommonMsgDatabase interface {
RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*relation.UserCount, dateCount map[string]int64, err error)
RangeGroupSendCount(ctx context.Context, start time.Time, end time.Time, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, groups []*relation.GroupCount, dateCount map[string]int64, err error)
ConvertMsgsDocLen(ctx context.Context, conversationIDs []string)
// clear msg
GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*relation.MsgDocModel, error)
DeleteDocMsgBefore(ctx context.Context, ts int64, doc *relation.MsgDocModel) ([]int, error)
}
func NewCommonMsgDatabase(msgDocModel relation.MsgDocModelInterface, msg cache.MsgCache, seq cache.SeqCache, kafkaConf *config.Kafka) (CommonMsgDatabase, error) {
@ -796,7 +802,7 @@ func (db *commonMsgDatabase) deleteMsgRecursion(ctx context.Context, conversatio
}
log.ZDebug(ctx, "doc info", "conversationID", conversationID, "index", index, "docID", msgDocModel.DocID, "len", len(msgDocModel.Msg))
if int64(len(msgDocModel.Msg)) > db.msgTable.GetSingleGocMsgNum() {
log.ZWarn(ctx, "msgs too large", nil, "lenth", len(msgDocModel.Msg), "docID:", msgDocModel.DocID)
log.ZWarn(ctx, "msgs too large", nil, "length", len(msgDocModel.Msg), "docID:", msgDocModel.DocID)
}
if msgDocModel.IsFull() && msgDocModel.Msg[len(msgDocModel.Msg)-1].Msg.SendTime+(remainTime*1000) < timeutil.GetCurrentTimestampByMill() {
log.ZDebug(ctx, "doc is full and all msg is expired", "docID", msgDocModel.DocID)
@ -1047,3 +1053,72 @@ func (db *commonMsgDatabase) FindOneByDocIDs(ctx context.Context, conversationID
func (db *commonMsgDatabase) ConvertMsgsDocLen(ctx context.Context, conversationIDs []string) {
db.msgDocDatabase.ConvertMsgsDocLen(ctx, conversationIDs)
}
func (db *commonMsgDatabase) GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*relation.MsgDocModel, error) {
return db.msgDocDatabase.GetBeforeMsg(ctx, ts, limit)
}
func (db *commonMsgDatabase) DeleteDocMsgBefore(ctx context.Context, ts int64, doc *relation.MsgDocModel) ([]int, error) {
var notNull int
index := make([]int, 0, len(doc.Msg))
for i, message := range doc.Msg {
if message.Msg != nil {
notNull++
if message.Msg.SendTime < ts {
index = append(index, i)
}
}
}
if len(index) == 0 {
return index, nil
}
maxSeq := doc.Msg[index[len(index)-1]].Msg.Seq
conversationID := doc.DocID[:strings.LastIndex(doc.DocID, ":")]
if err := db.setMinSeq(ctx, conversationID, maxSeq+1); err != nil {
return index, err
}
if len(index) == notNull {
return index, db.msgDocDatabase.DeleteDoc(ctx, doc.DocID)
} else {
return index, db.msgDocDatabase.DeleteMsgByIndex(ctx, doc.DocID, index)
}
}
//func (db *commonMsgDatabase) ClearMsg(ctx context.Context, ts int64) (err error) {
// var (
// docNum int
// msgNum int
// start = time.Now()
// )
// for {
// msgs, err := db.msgDocDatabase.GetBeforeMsg(ctx, ts, 100)
// if err != nil {
// return err
// }
// if len(msgs) == 0 {
// return nil
// }
// for _, msg := range msgs {
// num, err := db.deleteOneMsg(ctx, ts, msg)
// if err != nil {
// return err
// }
// docNum++
// msgNum += num
// }
// }
//}
func (db *commonMsgDatabase) setMinSeq(ctx context.Context, conversationID string, seq int64) error {
dbSeq, err := db.seq.GetMinSeq(ctx, conversationID)
if err != nil {
if errors.Is(errs.Unwrap(err), redis.Nil) {
return nil
}
return err
}
if dbSeq >= seq {
return nil
}
return db.seq.SetMinSeq(ctx, conversationID, seq)
}

View File

@ -56,7 +56,16 @@ func (c *ConversationMgo) Delete(ctx context.Context, groupIDs []string) (err er
}
func (c *ConversationMgo) UpdateByMap(ctx context.Context, userIDs []string, conversationID string, args map[string]any) (rows int64, err error) {
res, err := mongoutil.UpdateMany(ctx, c.coll, bson.M{"owner_user_id": bson.M{"$in": userIDs}, "conversation_id": conversationID}, bson.M{"$set": args})
if len(args) == 0 {
return 0, nil
}
filter := bson.M{
"conversation_id": conversationID,
}
if len(userIDs) > 0 {
filter["owner_user_id"] = bson.M{"$in": userIDs}
}
res, err := mongoutil.UpdateMany(ctx, c.coll, filter, bson.M{"$set": args})
if err != nil {
return 0, err
}

View File

@ -267,58 +267,80 @@ func (m *MsgMgo) MarkSingleChatMsgsAsRead(ctx context.Context, userID string, do
}
func (m *MsgMgo) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*relation.MsgInfoModel, error) {
var pipe mongo.Pipeline
condition := bson.A{}
if req.SendTime != "" {
// Changed to keyed fields for bson.M to avoid govet errors
condition = append(condition, bson.M{"$eq": bson.A{bson.M{"$dateToString": bson.M{"format": "%Y-%m-%d", "date": bson.M{"$toDate": "$$item.msg.send_time"}}}, req.SendTime}})
}
if req.ContentType != 0 {
condition = append(condition, bson.M{"$eq": bson.A{"$$item.msg.content_type", req.ContentType}})
}
if req.SessionType != 0 {
condition = append(condition, bson.M{"$eq": bson.A{"$$item.msg.session_type", req.SessionType}})
}
where := make(bson.A, 0, 6)
if req.RecvID != "" {
condition = append(condition, bson.M{"$regexFind": bson.M{"input": "$$item.msg.recv_id", "regex": req.RecvID}})
where = append(where, bson.M{"msgs.msg.recv_id": req.RecvID})
}
if req.SendID != "" {
condition = append(condition, bson.M{"$regexFind": bson.M{"input": "$$item.msg.send_id", "regex": req.SendID}})
where = append(where, bson.M{"msgs.msg.send_id": req.SendID})
}
or := bson.A{
bson.M{"doc_id": bson.M{"$regex": "^si_", "$options": "i"}},
bson.M{"doc_id": bson.M{"$regex": "^g_", "$options": "i"}},
bson.M{"doc_id": bson.M{"$regex": "^sg_", "$options": "i"}},
if req.ContentType != 0 {
where = append(where, bson.M{"msgs.msg.content_type": req.ContentType})
}
// Use bson.D with keyed fields to specify the order explicitly
pipe = mongo.Pipeline{
{{"$match", bson.D{{Key: "$or", Value: or}}}},
{{"$project", bson.D{
{Key: "msgs", Value: bson.D{
{Key: "$filter", Value: bson.D{
{Key: "input", Value: "$msgs"},
{Key: "as", Value: "item"},
{Key: "cond", Value: bson.D{{Key: "$and", Value: condition}}},
}},
}},
{Key: "doc_id", Value: 1},
}}},
{{"$unwind", bson.M{"path": "$msgs"}}},
{{"$sort", bson.M{"msgs.msg.send_time": -1}}},
if req.SessionType != 0 {
where = append(where, bson.M{"msgs.msg.session_type": req.SessionType})
}
type docModel struct {
DocID string `bson:"doc_id"`
Msg *relation.MsgInfoModel `bson:"msgs"`
if req.SendTime != "" {
sendTime, err := time.Parse(time.DateOnly, req.SendTime)
if err != nil {
return 0, nil, errs.ErrArgs.WrapMsg("invalid sendTime", "req", req.SendTime, "format", time.DateOnly, "cause", err.Error())
}
where = append(where,
bson.M{
"msgs.msg.send_time": bson.M{
"$gte": sendTime.UnixMilli(),
},
},
bson.M{
"msgs.msg.send_time": bson.M{
"$lt": sendTime.Add(time.Hour * 24).UnixMilli(),
},
},
)
}
msgsDocs, err := mongoutil.Aggregate[*docModel](ctx, m.coll, pipe)
pipeline := bson.A{
bson.M{
"$unwind": "$msgs",
},
}
if len(where) > 0 {
pipeline = append(pipeline, bson.M{
"$match": bson.M{"$and": where},
})
}
pipeline = append(pipeline,
bson.M{
"$project": bson.M{
"_id": 0,
"msg": "$msgs.msg",
},
},
bson.M{
"$count": "count",
},
)
count, err := mongoutil.Aggregate[int32](ctx, m.coll, pipeline)
if err != nil {
return 0, nil, err
}
msgs := make([]*relation.MsgInfoModel, 0)
for _, doc := range msgsDocs {
msgInfo := doc.Msg
if len(count) == 0 || count[0] == 0 {
return 0, nil, nil
}
pipeline = pipeline[:len(pipeline)-1]
pipeline = append(pipeline,
bson.M{
"$skip": (req.Pagination.GetPageNumber() - 1) * req.Pagination.GetShowNumber(),
},
bson.M{
"$limit": req.Pagination.GetShowNumber(),
},
)
msgs, err := mongoutil.Aggregate[*relation.MsgInfoModel](ctx, m.coll, pipeline)
if err != nil {
return 0, nil, err
}
for i := range msgs {
msgInfo := msgs[i]
if msgInfo == nil || msgInfo.Msg == nil {
continue
}
@ -350,17 +372,17 @@ func (m *MsgMgo) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (
}
msgs = append(msgs, msgInfo)
}
start := (req.Pagination.PageNumber - 1) * req.Pagination.ShowNumber
n := int32(len(msgs))
if start >= n {
return n, []*relation.MsgInfoModel{}, nil
}
if start+req.Pagination.ShowNumber < n {
msgs = msgs[start : start+req.Pagination.ShowNumber]
} else {
msgs = msgs[start:]
}
return n, msgs, nil
//start := (req.Pagination.PageNumber - 1) * req.Pagination.ShowNumber
//n := int32(len(msgs))
//if start >= n {
// return n, []*relation.MsgInfoModel{}, nil
//}
//if start+req.Pagination.ShowNumber < n {
// msgs = msgs[start : start+req.Pagination.ShowNumber]
//} else {
// msgs = msgs[start:]
//}
return count[0], msgs, nil
}
func (m *MsgMgo) RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*relation.UserCount, dateCount map[string]int64, err error) {
@ -896,3 +918,89 @@ func (m *MsgMgo) ConvertMsgsDocLen(ctx context.Context, conversationIDs []string
}
}
}
func (m *MsgMgo) GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*relation.MsgDocModel, error) {
return mongoutil.Aggregate[*relation.MsgDocModel](ctx, m.coll, []bson.M{
{
"$match": bson.M{
"msgs.msg.send_time": bson.M{
"$lt": ts,
},
},
},
{
"$project": bson.M{
"_id": 0,
"doc_id": 1,
"msgs.msg.send_time": 1,
"msgs.msg.seq": 1,
},
},
{
"$limit": limit,
},
})
}
func (m *MsgMgo) DeleteMsgByIndex(ctx context.Context, docID string, index []int) error {
if len(index) == 0 {
return nil
}
model := &relation.MsgInfoModel{DelList: []string{}}
set := make(map[string]any)
for i := range index {
set[fmt.Sprintf("msgs.%d", i)] = model
}
return mongoutil.UpdateOne(ctx, m.coll, bson.M{"doc_id": docID}, bson.M{"$set": set}, true)
}
//func (m *MsgMgo) ClearMsg(ctx context.Context, t time.Time) (int64, error) {
// ts := t.UnixMilli()
// var count int64
// for {
// msgs, err := m.GetBeforeMsg(ctx, ts, 100)
// if err != nil {
// return count, err
// }
// if len(msgs) == 0 {
// return count, nil
// }
// for _, msg := range msgs {
// num, err := m.deleteOneMsg(ctx, ts, msg)
// count += num
// if err != nil {
// return count, err
// }
// }
// }
//}
func (m *MsgMgo) DeleteDoc(ctx context.Context, docID string) error {
return mongoutil.DeleteOne(ctx, m.coll, bson.M{"doc_id": docID})
}
//func (m *MsgMgo) DeleteDocMsg(ctx context.Context, ts int64, doc *relation.MsgDocModel) (int64, error) {
// var notNull int
// index := make([]int, 0, len(doc.Msg))
// for i, message := range doc.Msg {
// if message.Msg != nil {
// notNull++
// if message.Msg.SendTime < ts {
// index = append(index, i)
// }
// }
// }
// if len(index) == 0 {
// return 0, errs.New("no msg to delete").WrapMsg("deleteOneMsg", "docID", doc.DocID)
// }
// if len(index) == notNull {
// if err := m.DeleteDoc(ctx, doc.DocID); err != nil {
// return 0, err
// }
// } else {
// if err := m.setNullMsg(ctx, doc.DocID, index); err != nil {
// return 0, err
// }
// }
// return int64(len(index)), nil
//}

View File

@ -116,6 +116,12 @@ type MsgDocModelInterface interface {
RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*UserCount, dateCount map[string]int64, err error)
RangeGroupSendCount(ctx context.Context, start time.Time, end time.Time, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, groups []*GroupCount, dateCount map[string]int64, err error)
ConvertMsgsDocLen(ctx context.Context, conversationIDs []string)
DeleteDoc(ctx context.Context, docID string) error
DeleteMsgByIndex(ctx context.Context, docID string, index []int) error
GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*MsgDocModel, error)
//ClearMsg(ctx context.Context, t time.Time) (int64, error)
}
func (MsgDocModel) TableName() string {

View File

@ -33,6 +33,7 @@ const (
func NewDiscoveryRegister(zookeeperConfig *config.ZooKeeper, share *config.Share) (discovery.SvcDiscoveryRegistry, error) {
switch share.Env {
case zookeeperConst:
return zookeeper.NewZkClient(
zookeeperConfig.Address,
zookeeperConfig.Schema,

View File

@ -19,8 +19,8 @@ import (
"hash/fnv"
"unsafe"
"github.com/openimsdk/localcache/link"
"github.com/openimsdk/localcache/lru"
"github.com/openimsdk/open-im-server/v3/pkg/localcache/link"
"github.com/openimsdk/open-im-server/v3/pkg/localcache/lru"
)
type Cache[V any] interface {

View File

@ -1,5 +0,0 @@
module github.com/openimsdk/localcache
go 1.19
require github.com/hashicorp/golang-lru/v2 v2.0.7

View File

@ -1 +0,0 @@
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=

View File

@ -18,7 +18,7 @@ import (
"context"
"time"
"github.com/openimsdk/localcache/lru"
"github.com/openimsdk/open-im-server/v3/pkg/localcache/lru"
)
func defaultOption() *option {

View File

@ -17,9 +17,9 @@ package rpccache
import (
"context"
"github.com/openimsdk/localcache"
"github.com/openimsdk/open-im-server/v3/pkg/common/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/localcache"
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
pbconversation "github.com/openimsdk/protocol/conversation"
"github.com/openimsdk/tools/errs"

View File

@ -17,9 +17,9 @@ package rpccache
import (
"context"
"github.com/openimsdk/localcache"
"github.com/openimsdk/open-im-server/v3/pkg/common/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/localcache"
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
"github.com/openimsdk/tools/log"
"github.com/redis/go-redis/v9"

View File

@ -17,9 +17,9 @@ package rpccache
import (
"context"
"github.com/openimsdk/localcache"
"github.com/openimsdk/open-im-server/v3/pkg/common/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/localcache"
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
"github.com/openimsdk/protocol/sdkws"
"github.com/openimsdk/tools/errs"

View File

@ -17,9 +17,9 @@ package rpccache
import (
"context"
"github.com/openimsdk/localcache"
"github.com/openimsdk/open-im-server/v3/pkg/common/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/localcache"
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
"github.com/openimsdk/protocol/sdkws"
"github.com/openimsdk/tools/errs"

View File

@ -82,6 +82,11 @@ func (c *ConversationRpcClient) SetConversations(ctx context.Context, userIDs []
return err
}
func (c *ConversationRpcClient) UpdateConversations(ctx context.Context, conversation *pbconversation.UpdateConversationReq) error {
_, err := c.Client.UpdateConversation(ctx, conversation)
return err
}
func (c *ConversationRpcClient) GetConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) {
resp, err := c.Client.GetConversationIDs(ctx, &pbconversation.GetConversationIDsReq{UserID: ownerUserID})
if err != nil {

View File

@ -212,6 +212,11 @@ func (m *MessageRpcClient) GetConversationMaxSeq(ctx context.Context, conversati
return resp.MaxSeq, nil
}
func (m *MessageRpcClient) ClearMsg(ctx context.Context, ts int64) error {
_, err := m.Client.ClearMsg(ctx, &msg.ClearMsgReq{Timestamp: ts})
return err
}
type NotificationSender struct {
contentTypeConf map[int32]config.NotificationConfig
sessionTypeConf map[int32]int32

View File

@ -1,31 +0,0 @@
CHANGELOG
go.mod
go.sum
third_party/
translations/
logs
.git
.golangci.yml
docs/readme/README_uk.md
docs/readme/README_cs.md
docs/readme/README_hu.md
docs/readme/README_es.md
docs/readme/README_fa.md
docs/readme/README_fr.md
docs/readme/README_de.md
docs/readme/README_pl.md
docs/readme/README_id.md
docs/readme/README_fi.md
docs/readme/README_ml.md
docs/readme/README_ja.md
docs/readme/README_nl.md
docs/readme/README_it.md
docs/readme/README_ru.md
docs/readme/README_pt_BR
docs/readme/README_eo.md
docs/readme/README_ko.md
docs/readme/README_ar.md
docs/readme/README_vi.md
docs/readme/README_da.md
docs/readme/README_el.md
docs/readme/README_tr.md

View File

@ -1,311 +0,0 @@
# OpenIM Scripts Directory Structure
- [OpenIM Scripts Directory Structure](#openim-scripts-directory-structure)
- [log directory](#log-directory)
- [Supported platforms](#supported-platforms)
- [Get started quickly - demo.sh](#get-started-quickly---demosh)
- [Guide: Using and Understanding OpenIM Utility Functions](#guide-using-and-understanding-openim-utility-functions)
- [Table of Contents](#table-of-contents)
- [1. Checking the Status of Services by Ports](#1-checking-the-status-of-services-by-ports)
- [Function: `openim::util::check_ports`](#function-openimutilcheck_ports)
- [Example:](#example)
- [2. Checking the Status of Services by Process Names](#2-checking-the-status-of-services-by-process-names)
- [Function: `openim::util::check_process_names`](#function-openimutilcheck_process_names)
- [Example:](#example-1)
- [3. Stopping Services by Ports](#3-stopping-services-by-ports)
- [Function: `openim::util::stop_services_on_ports`](#function-openimutilstop_services_on_ports)
- [Example:](#example-2)
- [4. Stopping Services by Process Names](#4-stopping-services-by-process-names)
- [Function: `openim::util::stop_services_with_name`](#function-openimutilstop_services_with_name)
- [Example:](#example-3)
- [system management and installation of openim via Linux system](#system-management-and-installation-of-openim-via-linux-system)
- [examples](#examples)
This document outlines the directory structure for scripts in the OpenIM Server project. These scripts play a critical role in various areas like building, deploying, running and managing the services of OpenIM.
```bash
scripts/
├── README.md # Documentation for the scripts directory.
├── advertise.sh # Script to advertise or broadcast services.
├── batch_start_all.sh # Batch script to start all services.
├── build-all-service.sh # Script to build all services.
├── build.cmd # Command script for building (usually for Windows).
├── check-all.sh # Check script for all components or services.
├── cherry-pick.sh # Helper script for git cherry-pick operations.
├── common.sh # Common utilities and shared functions.
├── coverage.awk # AWK script for processing code coverage data.
├── coverage.sh # Script to gather and report code coverage.
├── demo.sh # Demonstration or example script.
├── docker-check-service.sh # Docker script to check services' status.
├── docker-start-all.sh # Docker script to start all containers/services.
├── ensure-tag.sh # Ensure correct tags or labeling.
├── env_check.sh # Environment verification and checking.
├── gen-swagger-docs.sh # Script to generate Swagger documentation.
├── genconfig.sh # Generate configuration files.
├── gendoc.sh # General documentation generation script.
├── githooks # Directory containing git hooks.
│ ├── commit-msg # Git hook for commit messages.
│ ├── pre-commit # Pre-commit git hook.
│ └── pre-push # Pre-push git hook.
├── golangci.yml # Configuration for GolangCI linting.
├── init-config.sh # Initialize configurations.
├── init-env.sh # Initialize the environment.
├── init-pwd.sh # Initialize or set password.
├── install # Installation scripts directory.
│ ├── README.md # Installation documentation.
│ ├── common.sh # Common utilities for installation.
│ ├── dependency.sh # Script to install dependencies.
│ ├── environment.sh # Set up the environment during installation.
│ ├── install-protobuf.sh # Install Protocol Buffers.
│ ├── install.sh # Main installation script.
│ ├── openim-api.sh # Install OpenIM API.
│ ├── openim-crontask.sh # Install OpenIM crontask.
│ ├── openim-man.sh # Install OpenIM management tool.
│ ├── openim-msggateway.sh # Install OpenIM message gateway.
│ ├── openim-msgtransfer.sh # Install OpenIM message transfer.
│ ├── openim-push.sh # Install OpenIM push service.
│ ├── openim-rpc.sh # Install OpenIM RPC.
│ ├── openim-tools.sh # Install OpenIM tools.
│ ├── test.sh # Installation testing script.
│ └── vimrc # Vim configuration file.
├── install-im-server.sh # Script to install the OpenIM server.
├── install_im_compose.sh # Install OpenIM using Docker Compose.
├── lib # Library or utility scripts directory.
│ ├── chat.sh # Utilities related to chat.
│ ├── color.sh # Color-related utilities.
│ ├── golang.sh # Golang utilities.
│ ├── init.sh # Initialization utilities.
│ ├── logging.sh # Logging utilities.
│ ├── release.sh # Release related utilities.
│ ├── util.sh # General utility functions.
│ └── version.sh # Version management utilities.
├── list-feature-tests.sh # Script to list feature tests.
├── make-rules # Makefile rule templates.
│ ├── common.mk # Common make rules.
│ ├── copyright.mk # Copyright related make rules.
│ ├── dependencies.mk # Dependency management rules.
│ ├── gen.mk # Generic or general rules.
│ ├── golang.mk # Golang-specific make rules.
│ ├── image.mk # Image or container-related rules.
│ ├── release.mk # Release specific rules.
│ ├── swagger.mk # Swagger documentation rules.
│ └── tools.mk # Tooling-related make rules.
├── mongo-init.sh # MongoDB initialization script.
├── release.sh # Script for releasing or deployment.
├── run-in-gopath.sh # Script to run commands within GOPATH.
├── start-all.sh # Script to start all services.
├── start.bat # Batch file to start services (usually for Windows).
├── stop-all.sh # Script to stop all services.
├── template # Directory containing template files.
│ ├── LICENSE # License template.
│ ├── LICENSE_TEMPLATES # Collection of license templates.
│ ├── boilerplate.txt # Boilerplate template.
│ ├── footer.md.tmpl # Footer template for markdown.
│ ├── head.md.tmpl # Header template for markdown.
│ └── project_README.md # Project README template.
├── update-generated-docs.sh # Update generated documentation.
├── update-yamlfmt.sh # Update YAML formatting.
├── verify-pkg-names.sh # Verify package names.
├── verify-shellcheck.sh # Shell script linting verification.
├── verify-spelling.sh # Spelling verification script.
├── verify-typecheck.sh # Type checking verification.
├── verify-yamlfmt.sh # Verify YAML format.
└── wait-for-it.sh # Script to wait for a condition or service to be ready.
```
The purpose of having a structured scripts directory like this is to make the operations of OpenIM Server clear and easy to manage. Each script has its own responsibility, making it easier to maintain and update. It's also helpful for newcomers who can easily understand what each part of the system is doing by just looking at this directory structure.
Each directory and script in the structure should be understood as a part of a larger whole. All scripts work together to ensure the smooth operation and maintenance of the OpenIM Server.
## log directory
**PATH:** `scripts/lib/logging.sh`
+ [log details](../docs/contrib/bash-log.md)
## Supported platforms
- Linux x86_64 (linux_amd64) : 64-bit Linux for most desktop and server systems.
- Windows x86_64 (windows_amd64) : 64-bit version for most Windows operating systems.
- macOS x86_64 (darwin_amd64) : 64-bit version for Apple Macintosh computers.
- Linux ARM64 (linux_arm64) : For ARM-based 64-bit Linux systems such as Raspberry Pi 4 and Jetson Nano.
- Linux s390x (linux_s390x) : 64-bit Linux for IBM System z hosts.
- Linux MIPS64 (linux_mips64) : 64-bit Linux for MIPS architecture.
- Linux MIPS64LE (linux_mips64le) : Suitable for 64-bit Linux systems with little endian MIPS architecture.
## Get started quickly - demo.sh
Is the `demo.sh` script teaching you how to quickly get started with OpenIM development and use
Steps to run demo:
```sh
$ make demo
```
More about `make` read:
+ [makefile](../docs/contrib/go-code.md)
Instructions for producing the demo movie:
```bash
# Create temporary directory
mkdir /tmp/kb-demo
cd /tmp/kb-demo
asciinema rec
<path-to-KB-repo>/scripts/demo/run.sh
<CTRL-C> to terminate the script
<CTRL-D> to terminate the asciinema recording
<CTRL-C> to save the recording locally
# Edit the recorded file by editing the controller-gen path
# Once you are happy with the recording, use svg-term program to generate the svg
svg-term --cast=<movie-id> --out _output/demo.svg --window
```
Here you will learn how to test a script, We take the four functions for starting and checking a service as an example.
## Guide: Using and Understanding OpenIM Utility Functions
This document provides an overview of the four utility functions designed for managing processes and services. These functions can check the status of services based on ports and process names, as well as stop services based on the same criteria.
### Table of Contents
- [1. Checking the Status of Services by Ports](#checking-the-status-of-services-by-ports)
- [2. Checking the Status of Services by Process Names](#checking-the-status-of-services-by-process-names)
- [3. Stopping Services by Ports](#stopping-services-by-ports)
- [4. Stopping Services by Process Names](#stopping-services-by-process-names)
### 1. Checking the Status of Services by Ports
#### Function: `openim::util::check_ports`
This function checks the status of services running on specified ports.
**Usage**:
```bash
$ openim::util::check_ports <port1> <port2> ...
```
**Design**:
- The function iterates through each provided port.
- It uses the `lsof` command to identify if there is a service running on the specified port.
- If a service is running, it logs the command, PID, and start time of the service.
- If a service is not running, it logs that the port is not started.
- If any service is not running, the function returns a status of 1.
#### Example:
```bash
$ openim::util::check_ports 8080 8081 8082
```
### 2. Checking the Status of Services by Process Names
#### Function: `openim::util::check_process_names`
This function checks the status of services based on their process names.
**Usage**:
```bash
$ openim::util::check_process_names <process_name1> <process_name2> ...
```
**Design**:
- The function uses `pgrep` to find process IDs associated with the given process names.
- If processes are found, it logs the command, PID, associated port, and start time.
- If no processes are found for a name, it logs that the process is not started.
- If any process is not running, the function returns a status of 1.
#### Example:
```bash
$ openim::util::check_process_names nginx mysql redis
```
### 3. Stopping Services by Ports
#### Function: `openim::util::stop_services_on_ports`
This function attempts to stop services running on the specified ports.
**Usage**:
```bash
$ openim::util::stop_services_on_ports <port1> <port2> ...
```
**Design**:
- The function uses the `lsof` command to identify services running on the specified ports.
- If a service is running on a port, it tries to terminate the associated process using the `kill` command.
- It logs successful terminations and any failures.
- If any service couldn't be stopped, the function returns a status of 1.
#### Example:
```bash
$ openim::util::stop_services_on_ports 8080 8081 8082
```
### 4. Stopping Services by Process Names
#### Function: `openim::util::stop_services_with_name`
This function attempts to stop services based on their process names.
**Usage**:
```bash
$ openim::util::stop_services_with_name <process_name1> <process_name2> ...
```
**Design**:
- The function uses `pgrep` to identify processes associated with the specified names.
- If processes are found, it tries to terminate them using the `kill` command.
- It logs successful terminations and any failures.
- If any service couldn't be stopped, the function returns a status of 1.
#### Example:
```bash
$ openim::util::stop_services_with_name nginx apache
```
### system management and installation of openim via Linux system
```bash
$ ./scripts/install/install.sh
```
## examples
Scripts to perform various build, install, analysis, etc operations.
The script directory design of OpenIM and the writing of scripts and tools refer to many excellent open source projects, such as helm, iam, kubernetes, docker, etc.
Maybe they'll give you inspiration for later maintenance...
These scripts keep the root level Makefile small and simple.
Examples:
* https://github.com/kubernetes/helm/tree/master/scripts
* https://github.com/cockroachdb/cockroach/tree/master/scripts
* https://github.com/hashicorp/terraform/tree/master/scripts

View File

@ -1,112 +0,0 @@
#!/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.
set -e
. $(dirname ${BASH_SOURCE})/lib/init.sh
trap 'openim::util::onCtrlC' INT
print_with_delay() {
text="$1"
delay="$2"
for i in $(seq 0 $((${#text}-1))); do
printf "${text:$i:1}"
sleep $delay
done
printf "\n"
}
print_progress() {
total="$1"
delay="$2"
printf "["
for i in $(seq 1 $total); do
printf "#"
sleep $delay
done
printf "]\n"
}
function openim_logo() {
# Set text color to cyan for header and URL
echo -e "\033[0;36m"
# Display fancy ASCII Art logo
# look http://patorjk.com/software/taag/#p=display&h=1&v=1&f=Doh&t=OpenIM
print_with_delay '
OOOOOOOOO IIIIIIIIIIMMMMMMMM MMMMMMMM
OO:::::::::OO I::::::::IM:::::::M M:::::::M
OO:::::::::::::OO I::::::::IM::::::::M M::::::::M
O:::::::OOO:::::::O II::::::IIM:::::::::M M:::::::::M
O::::::O O::::::Oppppp ppppppppp eeeeeeeeeeee nnnn nnnnnnnn I::::I M::::::::::M M::::::::::M
O:::::O O:::::Op::::ppp:::::::::p ee::::::::::::ee n:::nn::::::::nn I::::I M:::::::::::M M:::::::::::M
O:::::O O:::::Op:::::::::::::::::p e::::::eeeee:::::een::::::::::::::nn I::::I M:::::::M::::M M::::M:::::::M
O:::::O O:::::Opp::::::ppppp::::::pe::::::e e:::::enn:::::::::::::::n I::::I M::::::M M::::M M::::M M::::::M
O:::::O O:::::O p:::::p p:::::pe:::::::eeeee::::::e n:::::nnnn:::::n I::::I M::::::M M::::M::::M M::::::M
O:::::O O:::::O p:::::p p:::::pe:::::::::::::::::e n::::n n::::n I::::I M::::::M M:::::::M M::::::M
O:::::O O:::::O p:::::p p:::::pe::::::eeeeeeeeeee n::::n n::::n I::::I M::::::M M:::::M M::::::M
O::::::O O::::::O p:::::p p::::::pe:::::::e n::::n n::::n I::::I M::::::M MMMMM M::::::M
O:::::::OOO:::::::O p:::::ppppp:::::::pe::::::::e n::::n n::::nII::::::IIM::::::M M::::::M
OO:::::::::::::OO p::::::::::::::::p e::::::::eeeeeeee n::::n n::::nI::::::::IM::::::M M::::::M
OO:::::::::OO p::::::::::::::pp ee:::::::::::::e n::::n n::::nI::::::::IM::::::M M::::::M
OOOOOOOOO p::::::pppppppp eeeeeeeeeeeeee nnnnnn nnnnnnIIIIIIIIIIMMMMMMMM MMMMMMMM
p:::::p
p:::::p
p:::::::p
p:::::::p
p:::::::p
ppppppppp
' 0.0001
# Display product URL
print_with_delay "Discover more and contribute at: https://github.com/openimsdk/open-im-server" 0.01
# Reset text color back to normal
echo -e "\033[0m"
# Set text color to green for product description
echo -e "\033[1;32m"
print_with_delay "Open-IM-Server: Reinventing Instant Messaging" 0.01
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 "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
# Reset text color back to normal
echo -e "\033[0m"
# Set text color to yellow for the Slack link
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
# Reset text color back to normal
echo -e "\033[0m"
}
function main() {
openim_logo
}
main "$@"

View File

@ -1,173 +0,0 @@
#!/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()

View File

@ -1,72 +0,0 @@
#!/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 runs `make build` command.
# The command compiles all Makefile configs.
# Args:
# WHAT: Directory names to build. If any of these directories has a 'main'
# package, the build will produce executable files under $(OUT_DIR)/bin/platforms OR $(OUT_DIR)/bin—tools/platforms.
# If not specified, "everything" will be built.
# Usage: `scripts/build-all-service.sh`.
# Example: `scripts/build-go.sh WHAT=cmd/kubelet`.
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
source "${OPENIM_ROOT}/scripts/lib/init.sh"
# CPU core number
pushd "${OPENIM_ROOT}/tools/ncpu" >/dev/null
cpu_count=$(go run .)
popd >/dev/null
openim::color::echo ${GREEN_PREFIX} "======> cpu_count=$cpu_count"
openim::log::info "Building OpenIM, Parallel compilation compile=$cpu_count"
compile_count=$((cpu_count / 2))
# For help output
ARGHELP=""
if [[ "$#" -gt 0 ]]; then
ARGHELP="'$*'"
fi
openim::color::echo $COLOR_CYAN "NOTE: $0 has been replaced by 'make multiarch' or 'make build'"
echo
echo "The equivalent of this invocation is: "
echo " make build ${ARGHELP}"
echo " ./scripts/build-all-service.sh ${ARGHELP}"
echo
echo " Example: "
echo " Print a single binary:"
echo " make build BINS=openim-api"
echo " ./scripts/build-all-service.sh BINS=openim-api"
echo " Print : Enable debugging and logging"
echo " make build BINS=openim-api V=1 DEBUG=1"
echo " ./scripts/build-all-service.sh BINS=openim-api V=1 DEBUG=1"
echo
if [ -z "$*" ]; then
openim::log::info "no args, build all service"
make --no-print-directory -C "${OPENIM_ROOT}" -j$compile_count build
else
openim::log::info "build service: $*"
make --no-print-directory -C "${OPENIM_ROOT}" -j$compile_count build "$*"
fi
if [ $? -eq 0 ]; then
openim::log::success "all service build success, run 'make start' or './scripts/start-all.sh'"
else
openim::log::error "make build Error, script exits"
fi

View File

@ -1,113 +0,0 @@
#!/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 check openim service is running normally
#
# Usage: `scripts/check-all.sh`.
# Encapsulated as: `make check`.
# READ: https://github.com/openimsdk/open-im-server/tree/main/scripts/install/environment.sh
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
source "${OPENIM_ROOT}/scripts/install/common.sh"
if openim::util::is_running_in_container; then
exec >> ${DOCKER_LOG_FILE} 2>&1
fi
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() {
local service_names=("$@")
local half_length=$((${#service_names[@]} / 2))
local service_ports=("${service_names[@]:half_length}")
echo "+-------------------------+----------+"
echo "| Service Name | Port |"
echo "+-------------------------+----------+"
for ((index=0; index < half_length; index++)); do
printf "| %-23s | %-8s |\n" "${service_names[$index]}" "${service_ports[$index]}"
done
echo "+-------------------------+----------+"
}
# Assuming OPENIM_SERVER_NAME_TARGETS and OPENIM_SERVER_PORT_TARGETS are defined
# Similarly for OPENIM_DEPENDENCY_TARGETS and OPENIM_DEPENDENCY_PORT_TARGETS
# Print out services and their ports
print_services_and_ports "${OPENIM_SERVER_NAME_TARGETS[@]}" "${OPENIM_SERVER_PORT_TARGETS[@]}"
# Print out dependencies and their ports
print_services_and_ports "${OPENIM_DEPENDENCY_TARGETS[@]}" "${OPENIM_DEPENDENCY_PORT_TARGETS[@]}"
# OpenIM check
#echo "++ The port being checked: ${OPENIM_SERVER_PORT_LISTARIES[@]}"
openim::log::info "\n## Check all dependent components service ports"
#echo "++ The port being checked: ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]}"
# Later, after discarding Docker, the Docker keyword is unreliable, and Kubepods is used
if grep -qE 'docker|kubepods' /proc/1/cgroup || [ -f /.dockerenv ]; then
openim::color::echo ${COLOR_CYAN} "Environment in the interior of the container"
else
openim::color::echo ${COLOR_CYAN}"The environment is outside the container"
openim::util::check_ports ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]}
fi
if [[ $? -ne 0 ]]; then
openim::log::error_exit "The service does not start properly, please check the port, query variable definition!"
echo "+++ https://github.com/openimsdk/open-im-server/tree/main/scripts/install/environment.sh +++"
else
openim::log::success "All components depended on by OpenIM are running normally! "
fi
openim::log::status "Check OpenIM service:"
openim::log::colorless "${OPENIM_OUTPUT_HOSTBIN}/openim-msgtransfer"
result=$(. $(dirname ${BASH_SOURCE})/install/openim-msgtransfer.sh openim::msgtransfer::check)
if [[ $? -ne 0 ]]; then
#echo "+++ cat openim log file >>> ${LOG_FILE}"
openim::log::error "The service is not running properly, please check the logs $result"
fi
openim::log::status "Check OpenIM service:"
for item in "${OPENIM_ALL_SERVICE_LIBRARIES_NO_TRANSFER[@]}"; do
openim::log::colorless "$item"
done
result=$(openim::util::check_process_names ${OPENIM_ALL_SERVICE_LIBRARIES_NO_TRANSFER[@]})
if [[ $? -ne 0 ]]; then
#echo "+++ cat OpenIM log file >>> ${LOG_FILE}"
openim::log::error "The service is not running properly, please check the logs "
echo "$result"
exit 1
else
openim::log::status "List the ports listened to by the OpenIM service:"
openim::util::find_ports_for_all_services ${OPENIM_ALL_SERVICE_LIBRARIES_NO_TRANSFER[@]}
openim::util::find_ports_for_all_services ${OPENIM_MSGTRANSFER_BINARY[@]}
openim::log::success "All OpenIM services are running normally! "
fi

View File

@ -1,252 +0,0 @@
#!/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.
# Usage Instructions: https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/gitcherry-pick.md
# Checkout a PR from GitHub. (Yes, this is sitting in a Git tree. How
# meta.) Assumes you care about pulls from remote "upstream" and
# checks them out to a branch named:
# automated-cherry-pick-of-<pr>-<target branch>-<timestamp>
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
source "${OPENIM_ROOT}/scripts/lib/init.sh"
REPO_ROOT="$(git rev-parse --show-toplevel)"
declare -r REPO_ROOT
cd "${REPO_ROOT}"
STARTINGBRANCH=$(git symbolic-ref --short HEAD)
declare -r STARTINGBRANCH
declare -r REBASEMAGIC="${REPO_ROOT}/.git/rebase-apply"
DRY_RUN=${DRY_RUN:-""}
REGENERATE_DOCS=${REGENERATE_DOCS:-""}
UPSTREAM_REMOTE=${UPSTREAM_REMOTE:-upstream}
FORK_REMOTE=${FORK_REMOTE:-origin}
MAIN_REPO_ORG=${MAIN_REPO_ORG:-$(git remote get-url "$UPSTREAM_REMOTE" | awk '{gsub(/webhook[s]:\/\/|git@/,"")}1' | awk -F'[@:./]' 'NR==1{print $3}')}
MAIN_REPO_NAME=${MAIN_REPO_NAME:-$(git remote get-url "$UPSTREAM_REMOTE" | awk '{gsub(/webhook[s]:\/\/|git@/,"")}1' | awk -F'[@:./]' 'NR==1{print $4}')}
if [[ -z ${GITHUB_USER:-} ]]; then
openim::log::error_exit "Please export GITHUB_USER=<your-user> (or GH organization, if that's where your fork lives)"
fi
if ! command -v gh > /dev/null; then
openim::log::error_exit "Can't find 'gh' tool in PATH, please install from https://github.com/cli/cli"
fi
if [[ "$#" -lt 2 ]]; then
echo "${0} <remote branch> <pr-number>...: cherry pick one or more <pr> onto <remote branch> and leave instructions for proposing pull request"
echo
echo " Checks out <remote branch> and handles the cherry-pick of <pr> (possibly multiple) for you."
echo " Examples:"
echo " $0 upstream/release-v3.1 12345 # Cherry-picks PR 12345 onto upstream/release-v3.1 and proposes that as a PR."
echo " $0 upstream/release-v3.1 12345 56789 # Cherry-picks PR 12345, then 56789 and proposes the combination as a single PR."
echo
echo " Set the DRY_RUN environment var to skip git push and creating PR."
echo " This is useful for creating patches to a release branch without making a PR."
echo " When DRY_RUN is set the script will leave you in a branch containing the commits you cherry-picked."
echo
echo " Set the REGENERATE_DOCS environment var to regenerate documentation for the target branch after picking the specified commits."
echo " This is useful when picking commits containing changes to API documentation."
echo
echo " Set UPSTREAM_REMOTE (default: upstream) and FORK_REMOTE (default: origin)"
echo " to override the default remote names to what you have locally."
echo
echo " For merge process info, see https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/gitcherry-pick.md"
exit 2
fi
# Checks if you are logged in. Will error/bail if you are not.
gh auth status
if git_status=$(git status --porcelain --untracked=no 2>/dev/null) && [[ -n "${git_status}" ]]; then
openim::log::error_exit "!!! Dirty tree. Clean up and try again."
fi
if [[ -e "${REBASEMAGIC}" ]]; then
openim::log::error_exit "!!! 'git rebase' or 'git am' in progress. Clean up and try again."
fi
declare -r BRANCH="$1"
shift 1
declare -r PULLS=( "$@" )
function join { local IFS="$1"; shift; echo "$*"; }
PULLDASH=$(join - "${PULLS[@]/#/#}") # Generates something like "#12345-#56789"
declare -r PULLDASH
PULLSUBJ=$(join " " "${PULLS[@]/#/#}") # Generates something like "#12345 #56789"
declare -r PULLSUBJ
openim::log::status "Updating remotes..."
git remote update "${UPSTREAM_REMOTE}" "${FORK_REMOTE}"
if ! git log -n1 --format=%H "${BRANCH}" >/dev/null 2>&1; then
openim::log::error " '${BRANCH}' not found. The second argument should be something like ${UPSTREAM_REMOTE}/release-0.21."
openim::log::error " (In particular, it needs to be a valid, existing remote branch that I can 'git checkout'.)"
exit 1
fi
NEWBRANCHREQ="automated-cherry-pick-of-${PULLDASH}" # "Required" portion for tools.
declare -r NEWBRANCHREQ
NEWBRANCH="$(echo "${NEWBRANCHREQ}-${BRANCH}" | sed 's/\//-/g')"
declare -r NEWBRANCH
NEWBRANCHUNIQ="${NEWBRANCH}-$(date +%s)"
declare -r NEWBRANCHUNIQ
openim::log::info "+++ Creating local branch ${NEWBRANCHUNIQ}"
cleanbranch=""
gitamcleanup=false
function return_to_kansas {
if [[ "${gitamcleanup}" == "true" ]]; then
echo
openim::log::status "Aborting in-progress git am."
git am --abort >/dev/null 2>&1 || true
fi
# return to the starting branch and delete the PR text file
if [[ -z "${DRY_RUN}" ]]; then
echo
openim::log::status "Returning you to the ${STARTINGBRANCH} branch and cleaning up."
git checkout -f "${STARTINGBRANCH}" >/dev/null 2>&1 || true
if [[ -n "${cleanbranch}" ]]; then
git branch -D "${cleanbranch}" >/dev/null 2>&1 || true
fi
fi
}
trap return_to_kansas EXIT
SUBJECTS=()
function make-a-pr() {
local rel
rel="$(basename "${BRANCH}")"
echo
openim::log::status "Creating a pull request on GitHub at ${GITHUB_USER}:${NEWBRANCH}"
local numandtitle
numandtitle=$(printf '%s\n' "${SUBJECTS[@]}")
prtext=$(cat <<EOF
Cherry pick of ${PULLSUBJ} on ${rel}.
${numandtitle}
For details on the cherry pick process, see the [cherry pick requests](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/gitcherry-pick.md) page.
\`\`\`release-note
\`\`\`
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}"
}
git checkout -b "${NEWBRANCHUNIQ}" "${BRANCH}"
cleanbranch="${NEWBRANCHUNIQ}"
gitamcleanup=true
for pull in "${PULLS[@]}"; do
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"
echo
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" || {
conflicts=false
while unmerged=$(git status --porcelain | grep ^U) && [[ -n ${unmerged} ]] \
|| [[ -e "${REBASEMAGIC}" ]]; do
conflicts=true # <-- We should have detected conflicts once
echo
openim::log::status "Conflicts detected:"
echo
(git status --porcelain | grep ^U) || echo "!!! None. Did you git am --continue?"
echo
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
echo
if ! [[ "${REPLY}" =~ ^[yY]$ ]]; then
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
fi
}
# set the subject
subject=$(grep -m 1 "^Subject" "/tmp/${pull}.patch" | sed -e 's/Subject: \[PATCH//g' | sed 's/.*] //')
SUBJECTS+=("#${pull}: ${subject}")
# remove the patch file from /tmp
rm -f "/tmp/${pull}.patch"
done
gitamcleanup=false
# Re-generate docs (if needed)
if [[ -n "${REGENERATE_DOCS}" ]]; then
echo
echo "Regenerating docs..."
if ! scripts/generate-docs.sh; then
echo
echo "scripts/gendoc.sh FAILED to complete."
exit 1
fi
fi
if [[ -n "${DRY_RUN}" ]]; then
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
echo " git checkout ${STARTINGBRANCH}"
echo
echo "To delete this branch:"
echo
echo " git branch -D ${NEWBRANCHUNIQ}"
exit 0
fi
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 "This isn't normal. Leaving you with push instructions:"
echo
openim::log::status "First manually push the branch this script created:"
echo
echo " git push REMOTE ${NEWBRANCHUNIQ}:${NEWBRANCH}"
echo
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
make-a-pr
cleanbranch=""
exit 0
fi
echo
openim::log::status "I'm about to do the following to push to GitHub (and I'm assuming ${FORK_REMOTE} is your personal fork):"
echo
echo " git push ${FORK_REMOTE} ${NEWBRANCHUNIQ}:${NEWBRANCH}"
echo
read -p "+++ Proceed (anything other than 'y' aborts the cherry-pick)? [y/n] " -r
if ! [[ "${REPLY}" =~ ^[yY]$ ]]; then
echo "Aborting." >&2
exit 1
fi
git push "${FORK_REMOTE}" -f "${NEWBRANCHUNIQ}:${NEWBRANCH}"
make-a-pr

View File

@ -1,516 +0,0 @@
#!/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.
# shellcheck disable=SC2034 # Variables sourced in other scripts.
# Common utilities, variables and checks for all build scripts.
# Unset CDPATH, having it set messes up with script import paths
unset CDPATH
USER_ID=$(id -u)
GROUP_ID=$(id -g)
DOCKER_OPTS=${DOCKER_OPTS:-""}
IFS=" " read -r -a DOCKER <<< "docker ${DOCKER_OPTS}"
DOCKER_HOST=${DOCKER_HOST:-""}
DOCKER_MACHINE_NAME=${DOCKER_MACHINE_NAME:-"openim-dev"}
readonly DOCKER_MACHINE_DRIVER=${DOCKER_MACHINE_DRIVER:-"virtualbox --virtualbox-cpu-count -1"}
# This will canonicalize the path
OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd -P)
# Please do not refer to lib after referring to common
. $(dirname ${BASH_SOURCE})/lib/init.sh
# Constants
readonly OPENIM_BUILD_IMAGE_REPO=openim-build
#readonly OPENIM_BUILD_IMAGE_CROSS_TAG="$(cat "${OPENIM_ROOT}/build/build-image/cross/VERSION")"
readonly OPENIM_DOCKER_REGISTRY="${OPENIM_DOCKER_REGISTRY:-k8s.gcr.io}"
readonly OPENIM_BASE_IMAGE_REGISTRY="${OPENIM_BASE_IMAGE_REGISTRY:-us.gcr.io/k8s-artifacts-prod/build-image}"
# This version number is used to cause everyone to rebuild their data containers
# and build image. This is especially useful for automated build systems like
# Jenkins.
#
# Increment/change this number if you change the build image (anything under
# build/build-image) or change the set of volumes in the data container.
#readonly OPENIM_BUILD_IMAGE_VERSION_BASE="$(cat "${OPENIM_ROOT}/build/build-image/VERSION")"
#readonly OPENIM_BUILD_IMAGE_VERSION="${OPENIM_BUILD_IMAGE_VERSION_BASE}-${OPENIM_BUILD_IMAGE_CROSS_TAG}"
# Here we map the output directories across both the local and remote _output
# directories:
#
# *_OUTPUT_ROOT - the base of all output in that environment.
# *_OUTPUT_SUBPATH - location where golang stuff is built/cached. Also
# persisted across docker runs with a volume mount.
# *_OUTPUT_BINPATH - location where final binaries are placed. If the remote
# is really remote, this is the stuff that has to be copied
# back.
# OUT_DIR can come in from the Makefile, so honor it.
readonly LOCAL_OUTPUT_ROOT="${OPENIM_ROOT}/${OUT_DIR:-_output}"
readonly LOCAL_OUTPUT_SUBPATH="${LOCAL_OUTPUT_ROOT}/bin"
readonly LOCAL_OUTPUT_BINPATH="${LOCAL_OUTPUT_SUBPATH}/platforms"
readonly LOCAL_OUTPUT_BINTOOLSPATH="${LOCAL_OUTPUT_SUBPATH}/tools"
readonly LOCAL_OUTPUT_GOPATH="${LOCAL_OUTPUT_SUBPATH}/go"
readonly LOCAL_OUTPUT_IMAGE_STAGING="${LOCAL_OUTPUT_ROOT}/images"
# This is the port on the workstation host to expose RSYNC on. Set this if you
# are doing something fancy with ssh tunneling.
readonly OPENIM_RSYNC_PORT="${OPENIM_RSYNC_PORT:-}"
# This is the port that rsync is running on *inside* the container. This may be
# mapped to OPENIM_RSYNC_PORT via docker networking.
readonly OPENIM_CONTAINER_RSYNC_PORT=8730
# Get the set of master binaries that run in Docker (on Linux)
# Entry format is "<name-of-binary>,<base-image>".
# Binaries are placed in /usr/local/bin inside the image.
#
# $1 - server architecture
openim::build::get_docker_wrapped_binaries() {
local arch=$1
local debian_base_version=v2.1.0
local debian_iptables_version=v12.1.0
### If you change any of these lists, please also update DOCKERIZED_BINARIES
### in build/BUILD. And openim::golang::server_image_targets
local targets=(
"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-crontask,${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-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-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-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-third,${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[@]}"
}
# ---------------------------------------------------------------------------
# Basic setup functions
# Verify that the right utilities and such are installed for building openim. Set
# up some dynamic constants.
# Args:
# $1 - boolean of whether to require functioning docker (default true)
#
# Vars set:
# OPENIM_ROOT_HASH
# OPENIM_BUILD_IMAGE_TAG_BASE
# OPENIM_BUILD_IMAGE_TAG
# OPENIM_BUILD_IMAGE
# OPENIM_BUILD_CONTAINER_NAME_BASE
# OPENIM_BUILD_CONTAINER_NAME
# OPENIM_DATA_CONTAINER_NAME_BASE
# OPENIM_DATA_CONTAINER_NAME
# OPENIM_RSYNC_CONTAINER_NAME_BASE
# OPENIM_RSYNC_CONTAINER_NAME
# DOCKER_MOUNT_ARGS
# LOCAL_OUTPUT_BUILD_CONTEXT
function openim::build::verify_prereqs() {
local -r require_docker=${1:-true}
openim::log::status "Verifying Prerequisites...."
openim::build::ensure_tar || return 1
openim::build::ensure_rsync || return 1
if ${require_docker}; then
openim::build::ensure_docker_in_path || return 1
openim::util::ensure_docker_daemon_connectivity || return 1
if (( OPENIM_VERBOSE > 6 )); then
openim::log::status "Docker Version:"
"${DOCKER[@]}" version | openim::log::info_from_stdin
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_BUILD_IMAGE_TAG_BASE="build-${OPENIM_ROOT_HASH}"
#OPENIM_BUILD_IMAGE_TAG="${OPENIM_BUILD_IMAGE_TAG_BASE}-${OPENIM_BUILD_IMAGE_VERSION}"
#OPENIM_BUILD_IMAGE="${OPENIM_BUILD_IMAGE_REPO}:${OPENIM_BUILD_IMAGE_TAG}"
OPENIM_BUILD_CONTAINER_NAME_BASE="openim-build-${OPENIM_ROOT_HASH}"
#OPENIM_BUILD_CONTAINER_NAME="${OPENIM_BUILD_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}"
OPENIM_RSYNC_CONTAINER_NAME_BASE="openim-rsync-${OPENIM_ROOT_HASH}"
#OPENIM_RSYNC_CONTAINER_NAME="${OPENIM_RSYNC_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}"
OPENIM_DATA_CONTAINER_NAME_BASE="openim-build-data-${OPENIM_ROOT_HASH}"
#OPENIM_DATA_CONTAINER_NAME="${OPENIM_DATA_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}"
#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"
}
# ---------------------------------------------------------------------------
# Utility functions
function openim::build::docker_available_on_osx() {
if [[ -z "${DOCKER_HOST}" ]]; then
if [[ -S "/var/run/docker.sock" ]]; then
openim::log::status "Using Docker for MacOS"
return 0
fi
openim::log::status "No docker host is set. Checking options for setting one..."
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 "See: https://docs.docker.com/engine/installation/mac/ for installation instructions."
return 1
elif [[ -n "$(which docker-machine)" ]]; then
openim::build::prepare_docker_machine
fi
fi
}
function openim::build::prepare_docker_machine() {
openim::log::status "docker-machine was found."
local available_memory_bytes
available_memory_bytes=$(sysctl -n hw.memsize 2>/dev/null)
local bytes_in_mb=1048576
# 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.
local memory_divisor=2
local virtualbox_memory_mb=$(( available_memory_bytes / (bytes_in_mb * memory_divisor) ))
docker-machine inspect "${DOCKER_MACHINE_NAME}" &> /dev/null || {
openim::log::status "Creating a machine to build OPENIM"
docker-machine create --driver "${DOCKER_MACHINE_DRIVER}" \
--virtualbox-memory "${virtualbox_memory_mb}" \
--engine-env HTTP_PROXY="${OPENIMRNETES_HTTP_PROXY:-}" \
--engine-env HTTPS_PROXY="${OPENIMRNETES_HTTPS_PROXY:-}" \
--engine-env NO_PROXY="${OPENIMRNETES_NO_PROXY:-127.0.0.1}" \
"${DOCKER_MACHINE_NAME}" > /dev/null || {
openim::log::error "Something went wrong creating a machine."
openim::log::error "Try the following: "
openim::log::error "docker-machine create -d ${DOCKER_MACHINE_DRIVER} --virtualbox-memory ${virtualbox_memory_mb} ${DOCKER_MACHINE_NAME}"
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
local docker_machine_out
while ! docker_machine_out=$(docker-machine env "${DOCKER_MACHINE_NAME}" 2>&1); do
if [[ ${docker_machine_out} =~ "Error checking TLS connection" ]]; then
echo "${docker_machine_out}"
docker-machine regenerate-certs "${DOCKER_MACHINE_NAME}"
else
sleep 1
fi
done
eval "$(docker-machine env "${DOCKER_MACHINE_NAME}")"
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() {
[[ $(sed --version 2>&1) == *GNU* ]]
}
function openim::build::ensure_rsync() {
if [[ -z "$(which rsync)" ]]; then
openim::log::error "Can't find 'rsync' in PATH, please fix and retry."
return 1
fi
}
function openim::build::update_dockerfile() {
if openim::build::is_gnu_sed; then
sed_opts=(-i)
else
sed_opts=(-i '')
fi
sed "${sed_opts[@]}" "s/OPENIM_BUILD_IMAGE_CROSS_TAG/${OPENIM_BUILD_IMAGE_CROSS_TAG}/" "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
}
function openim::build::set_proxy() {
if [[ -n "${OPENIMRNETES_HTTPS_PROXY:-}" ]]; then
echo "ENV https_proxy $OPENIMRNETES_HTTPS_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
fi
if [[ -n "${OPENIMRNETES_HTTP_PROXY:-}" ]]; then
echo "ENV http_proxy $OPENIMRNETES_HTTP_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
fi
if [[ -n "${OPENIMRNETES_NO_PROXY:-}" ]]; then
echo "ENV no_proxy $OPENIMRNETES_NO_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
fi
}
function openim::build::ensure_docker_in_path() {
if [[ -z "$(which docker)" ]]; then
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."
return 1
fi
}
function openim::build::ensure_tar() {
if [[ -n "${TAR:-}" ]]; then
return
fi
# Find gnu tar if it is available, bomb out if not.
TAR=tar
if which gtar &>/dev/null; then
TAR=gtar
else
if which gnutar &>/dev/null; then
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
}
function openim::build::has_docker() {
which docker &> /dev/null
}
function openim::build::has_ip() {
which ip &> /dev/null && ip -Version | grep 'iproute2' &> /dev/null
}
# Detect if a specific image exists
#
# $1 - image repo name
# $2 - image tag
function openim::build::docker_image_exists() {
[[ -n $1 && -n $2 ]] || {
openim::log::error "Internal error. Image not specified in docker_image_exists."
exit 2
}
[[ $("${DOCKER[@]}" images -q "${1}:${2}") ]]
}
# Delete all images that match a tag prefix except for the "current" version
#
# $1: The image repo/name
# $2: The tag base. We consider any image that matches $2*
# $3: The current image not to delete if provided
function openim::build::docker_delete_old_images() {
# In Docker 1.12, we can replace this with
# docker images "$1" --format "{{.Tag}}"
for tag in $("${DOCKER[@]}" images "${1}" | tail -n +2 | awk '{print $2}') ; do
if [[ "${tag}" != "${2}"* ]] ; then
V=3 openim::log::status "Keeping image ${1}:${tag}"
continue
fi
if [[ -z "${3:-}" || "${tag}" != "${3}" ]] ; then
V=2 openim::log::status "Deleting image ${1}:${tag}"
"${DOCKER[@]}" rmi "${1}:${tag}" >/dev/null
else
V=3 openim::log::status "Keeping image ${1}:${tag}"
fi
done
}
# Stop and delete all containers that match a pattern
#
# $1: The base container prefix
# $2: The current container to keep, if provided
function openim::build::docker_delete_old_containers() {
# In Docker 1.12 we can replace this line with
# docker ps -a --format="{{.Names}}"
for container in $("${DOCKER[@]}" ps -a | tail -n +2 | awk '{print $NF}') ; do
if [[ "${container}" != "${1}"* ]] ; then
V=3 openim::log::status "Keeping container ${container}"
continue
fi
if [[ -z "${2:-}" || "${container}" != "${2}" ]] ; then
V=2 openim::log::status "Deleting container ${container}"
openim::build::destroy_container "${container}"
else
V=3 openim::log::status "Keeping container ${container}"
fi
done
}
# Takes $1 and computes a short has for it. Useful for unique tag generation
function openim::build::short_hash() {
[[ $# -eq 1 ]] || {
openim::log::error "Internal error. No data based to short_hash."
exit 2
}
local short_hash
if which md5 >/dev/null 2>&1; then
short_hash=$(md5 -q -s "$1")
else
short_hash=$(echo -n "$1" | md5sum)
fi
echo "${short_hash:0:10}"
}
# Pedantically kill, wait-on and remove a container. The -f -v options
# to rm don't actually seem to get the job done, so force kill the
# container, wait to ensure it's stopped, then try the remove. This is
# a workaround for bug https://github.com/docker/docker/issues/3968.
function openim::build::destroy_container() {
"${DOCKER[@]}" kill "$1" >/dev/null 2>&1 || true
if [[ $("${DOCKER[@]}" version --format '{{.Server.Version}}') = 17.06.0* ]]; then
# Workaround https://github.com/moby/moby/issues/33948.
# TODO: remove when 17.06.0 is not relevant anymore
DOCKER_API_VERSION=v1.29 "${DOCKER[@]}" wait "$1" >/dev/null 2>&1 || true
else
"${DOCKER[@]}" wait "$1" >/dev/null 2>&1 || true
fi
"${DOCKER[@]}" rm -f -v "$1" >/dev/null 2>&1 || true
}
# ---------------------------------------------------------------------------
# Building
function openim::build::clean() {
if openim::build::has_docker ; then
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_DATA_CONTAINER_NAME_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"
"${DOCKER[@]}" rmi "$("${DOCKER[@]}" images -q --filter 'dangling=true')" 2> /dev/null || true
fi
if [[ -d "${LOCAL_OUTPUT_ROOT}" ]]; then
openim::log::status "Removing _output directory"
rm -rf "${LOCAL_OUTPUT_ROOT}"
fi
}
# Set up the context directory for the openim-build image and build it.
function openim::build::build_image() {
mkdir -p "${LOCAL_OUTPUT_BUILD_CONTEXT}"
# 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}"
cp /etc/localtime "${LOCAL_OUTPUT_BUILD_CONTEXT}/"
cp "${OPENIM_ROOT}/build/build-image/Dockerfile" "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
cp "${OPENIM_ROOT}/build/build-image/rsyncd.sh" "${LOCAL_OUTPUT_BUILD_CONTEXT}/"
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"
openim::build::update_dockerfile
openim::build::set_proxy
openim::build::docker_build "${OPENIM_BUILD_IMAGE}" "${LOCAL_OUTPUT_BUILD_CONTEXT}" 'false'
# 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_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_images "${OPENIM_BUILD_IMAGE_REPO}" "${OPENIM_BUILD_IMAGE_TAG_BASE}" "${OPENIM_BUILD_IMAGE_TAG}"
openim::build::ensure_data_container
openim::build::sync_to_container
}
# Build a docker image from a Dockerfile.
# $1 is the name of the image to build
# $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
function openim::build::docker_build() {
local -r image=$1
local -r context_dir=$2
local -r pull="${3:-true}"
local -ra build_cmd=("${DOCKER[@]}" build -t "${image}" "--pull=${pull}" "${context_dir}")
openim::log::status "Building Docker image ${image}"
local docker_output
docker_output=$("${build_cmd[@]}" 2>&1) || {
cat <<EOF >&2
+++ Docker build command failed for ${image}
${docker_output}
To retry manually, run:
${build_cmd[*]}
EOF
return 1
}
}
function openim::build::ensure_data_container() {
# If the data container exists AND exited successfully, we can use it.
# Otherwise nuke it and start over.
local ret=0
local code=0
code=$(docker inspect \
-f '{{.State.ExitCode}}' \
"${OPENIM_DATA_CONTAINER_NAME}" 2>/dev/null) || ret=$?
if [[ "${ret}" == 0 && "${code}" != 0 ]]; then
openim::build::destroy_container "${OPENIM_DATA_CONTAINER_NAME}"
ret=1
fi
if [[ "${ret}" != 0 ]]; then
openim::log::status "Creating data container ${OPENIM_DATA_CONTAINER_NAME}"
# We have to ensure the directory exists, or else the docker run will
# create it as root.
mkdir -p "${LOCAL_OUTPUT_GOPATH}"
# 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
# container and chowns the GOPATH.
#
# The data container creates volumes for all of the directories that store
# intermediates for the Go build. This enables incremental builds across
# Docker sessions. The *_cgo paths are re-compiled versions of the go std
# libraries for true static building.
local -ra docker_cmd=(
"${DOCKER[@]}" run
--volume "${REMOTE_ROOT}" # white-out the whole output dir
--volume /usr/local/go/pkg/linux_386_cgo
--volume /usr/local/go/pkg/linux_amd64_cgo
--volume /usr/local/go/pkg/linux_arm_cgo
--volume /usr/local/go/pkg/linux_arm64_cgo
--volume /usr/local/go/pkg/linux_ppc64le_cgo
--volume /usr/local/go/pkg/darwin_amd64_cgo
--volume /usr/local/go/pkg/darwin_386_cgo
--volume /usr/local/go/pkg/windows_amd64_cgo
--volume /usr/local/go/pkg/windows_386_cgo
--name "${OPENIM_DATA_CONTAINER_NAME}"
--hostname "${HOSTNAME}"
"${OPENIM_BUILD_IMAGE}"
chown -R "${USER_ID}":"${GROUP_ID}"
"${REMOTE_ROOT}"
/usr/local/go/pkg/
)
"${docker_cmd[@]}"
fi
}
# Build all openim commands.
function openim::build::build_command() {
openim::log::status "Running build command..."
make -C "${OPENIM_ROOT}" multiarch
}

View File

@ -1,13 +0,0 @@
#!/usr/bin/env awk
{
print $0
if (match($0, /^total:/)) {
sub(/%/, "", $NF);
printf("test coverage is %s%(quality gate is %s%)\n", $NF, target)
if (strtonum($NF) < target) {
printf("test coverage does not meet expectations: %d%, please add test cases!\n", target)
exit 1;
}
}
}

View File

@ -1,29 +0,0 @@
#!/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.
# http://stackoverflow.com/a/21142256/2055281
echo "mode: atomic" > coverage.txt
for d in $(find ./* -maxdepth 10 -type d); do
if ls $d/*.go &> /dev/null; then
go test -coverprofile=profile.out -covermode=atomic $d
if [ -f profile.out ]; then
cat profile.out | grep -v "mode: " >> /tmp/coverage.txt
rm profile.out
fi
fi
done

View File

@ -1,29 +0,0 @@
#!/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.
#fixme This scripts is the total startup scripts
#fixme The full name of the shell scripts that needs to be started is placed in the need_to_start_server_shell array
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
source "${OPENIM_ROOT}/scripts/install/common.sh"
openim::log::info "\n# Use Docker to start all OpenIM service"
trap 'openim::util::onCtrlC' INT
"${OPENIM_ROOT}"/scripts/start-all.sh 2>&1 &
tail -f ${DOCKER_LOG_FILE}

View File

@ -1,26 +0,0 @@
#!/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.
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
version="${VERSION}"
if [ "${version}" == "" ];then
version=v$(${OPENIM_ROOT}/_output/tools/gsemver bump)
fi
if [ -z "$(git tag -l ${version})" ];then
git tag -a -m "release version ${version}" ${version}
fi

View File

@ -1,73 +0,0 @@
#!/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.
# Script to generate docs from the latest swagger spec.
# The root of the build/dist directory
OPENIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
source "${OPENIM_ROOT}"/scripts/lib/util.sh
mkdir -p ${OPENIM_OUTPUT_TMP}
cd ${OPENIM_OUTPUT_TMP}
# gendocs takes "input.json" as the input swagger spec.
# $1 is expected to be <group>_<version>
cp ${OPENIM_OUTPUT_TMP}/swagger-source/"$1".json ${OPENIM_OUTPUT_TMP}/input.json
./gradle-2.5/bin/gradle gendocs --info
#insert a TOC for top level API objects
buf="== Top Level API Objects\n\n"
top_level_models=$(grep '&[A-Za-z]*{},' /register.go | sed 's/.*&//;s/{},//')
# check if the top level models exist in the definitions.adoc. If they exist,
# their name will be <version>.<model_name>
VERSION="${1#*_}"
for m in ${top_level_models}
do
if grep -xq "=== ${VERSION}.${m}" ./definitions.adoc
then
buf+="* <<${VERSION}.${m}>>\n"
fi
done
sed -i "1i ${buf}" ./definitions.adoc
# fix the links in .adoc, replace <<x.y>> with link:definitions.html#_x_y[x.y], and lowercase the _x_y part
sed -i -e 's|<<\(.*\)\.\(.*\)>>|link:#_\L\1_\2\E[\1.\2]|g' ./definitions.adoc
sed -i -e 's|<<\(.*\)\.\(.*\)>>|link:../definitions#_\L\1_\2\E[\1.\2]|g' ./paths.adoc
# fix the link to <<any>>
sed -i -e 's|<<any>>|link:#_any[any]|g' ./definitions.adoc
sed -i -e 's|<<any>>|link:../definitions#_any[any]|g' ./paths.adoc
# change the title of paths.adoc from "paths" to "operations"
sed -i 's|== Paths|== Operations|g' ./paths.adoc
# $$ has special meaning in asciidoc, we need to escape it
sed -i 's|\$\$|+++$$+++|g' ./definitions.adoc
echo -e "=== any\nRepresents an untyped JSON map - see the description of the field for more info about the structure of this object." >> ./definitions.adoc
asciidoctor definitions.adoc
asciidoctor paths.adoc
cp "$OPENIM_OUTPUT_TMP/definitions.html" "$OPENIM_OUTPUT_TMP/_output/"
cp "$OPENIM_OUTPUT_TMP/paths.html" "$OPENIM_OUTPUT_TMP/_output/operations.html"
success "SUCCESS"

View File

@ -1,56 +0,0 @@
#!/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.
# Function of this script: Generate the OPENIM component YAML configuration file according to the scripts/environment.sh configuration.
# eg./scripts/genconfig.sh scripts/install/environment.sh scripts/template/config.yaml
# Read: https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/init-config.md
env_file="$1"
template_file="$2"
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
source "${OPENIM_ROOT}/scripts/lib/init.sh"
if [ $# -ne 2 ];then
openim::log::error "Usage: scripts/genconfig.sh scripts/environment.sh configs/config.yaml"
exit 1
fi
if [ -z "${OPENIM_IP}" ]; then
openim::util::require-dig
fi
source "${env_file}"
declare -A envs
set +u
for env in $(sed -n 's/^[^#].*${\(.*\)}.*/\1/p' ${template_file})
do
if [ -z "$(eval echo \$${env})" ];then
openim::log::error "environment variable '${env}' not set"
missing=true
fi
done
if [ "${missing}" ];then
openim::log::error "You may run 'source scripts/environment.sh' to set these environment"
exit 1
fi
eval "cat << EOF
$(cat ${template_file})
EOF"

View File

@ -1,84 +0,0 @@
#!/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.
#!/bin/bash
DEFAULT_DIRS=("pkg")
BASE_URL="github.com/openimsdk/open-im-server/v3"
REMOVE_DOC=false
usage() {
echo "Usage: $0 [OPTIONS]"
echo
echo "This script iterates over directories. By default, it generates doc.go files for 'pkg' and 'internal/pkg'."
echo
echo "Options:"
echo " -d DIRS, --dirs DIRS Specify directories to process, 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 " -r, --remove Remove all doc.go files in the specified directories."
echo " -h, --help Show this help message."
echo
}
process_dir() {
local dir="$1"
local base_url="$2"
local remove_doc="$3"
find "$dir" -type d | while read -r d; do
if [ "$remove_doc" = true ]; then
if [ -f "$d/doc.go" ]; then
echo "Removing $d/doc.go"
rm -f "$d/doc.go"
fi
else
if [ ! -f "$d/doc.go" ] && ls "$d/"*.go &>/dev/null; then
echo "Creating $d/doc.go"
echo "package $(basename "$d") // import \"$base_url/$(echo "$d" | sed "s|^\./||")\"" >"$d/doc.go"
fi
fi
done
}
while [[ $# -gt 0 ]]; do
case "$1" in
-d|--dirs)
IFS=',' read -ra DIRS <<< "$2"
shift 2
;;
-u|--url)
BASE_URL="$2"
shift 2
;;
-r|--remove)
REMOVE_DOC=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
usage
exit 1
;;
esac
done
DIRS=(${DIRS:-"${DEFAULT_DIRS[@]}"})
for dir in "${DIRS[@]}"; do
process_dir "$dir" "$BASE_URL" "$REMOVE_DOC"
done

View File

@ -1,265 +0,0 @@
#!/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 automatically initializes various configuration files and can generate example files.
# Root directory of the OpenIM project
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
# Source initialization script
source "${OPENIM_ROOT}/scripts/lib/init.sh"
# Default environment file
readonly ENV_FILE=${ENV_FILE:-"${OPENIM_ROOT}/scripts/install/environment.sh"}
# Templates for configuration files
declare -A TEMPLATES=(
["${OPENIM_ROOT}/deployments/templates/env-template.yaml"]="${OPENIM_ROOT}/.env"
["${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/alertmanager.yml"]="${OPENIM_ROOT}/config/alertmanager.yml"
)
# Templates for example files
declare -A EXAMPLES=(
["${OPENIM_ROOT}/deployments/templates/env-template.yaml"]="${OPENIM_ROOT}/config/templates/env.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/alertmanager.yml"]="${OPENIM_ROOT}/config/templates/alertmanager.yml.template"
)
# Templates for config Copy file
declare -A COPY_TEMPLATES=(
["${OPENIM_ROOT}/deployments/templates/email.tmpl"]="${OPENIM_ROOT}/config/email.tmpl"
["${OPENIM_ROOT}/deployments/templates/instance-down-rules.yml"]="${OPENIM_ROOT}/config/instance-down-rules.yml"
["${OPENIM_ROOT}/deployments/templates/notification.yaml"]="${OPENIM_ROOT}/config/notification.yaml"
)
# Templates for config Copy file
declare -A COPY_EXAMPLES=(
["${OPENIM_ROOT}/deployments/templates/email.tmpl"]="${OPENIM_ROOT}/config/templates/email.tmpl.template"
["${OPENIM_ROOT}/deployments/templates/instance-down-rules.yml"]="${OPENIM_ROOT}/config/templates/instance-down-rules.yml.template"
["${OPENIM_ROOT}/deployments/templates/notification.yaml"]="${OPENIM_ROOT}/config/templates/notification.yaml.template"
)
# Command-line options
FORCE_OVERWRITE=false
SKIP_EXISTING=false
GENERATE_EXAMPLES=false
CLEAN_CONFIG=false
CLEAN_EXAMPLES=false
FILES_PROCESSED=false
# Function to display help information
show_help() {
echo "Usage: $(basename "$0") [options]"
echo "Options:"
echo " -h, --help Show this help message"
echo " --force Overwrite existing files without prompt"
echo " --skip Skip generation if file exists"
echo " --examples Generate example files"
echo " --clean-config Clean all configuration files"
echo " --clean-examples Clean all example files"
}
# Function to generate and copy configuration files
generate_config_files() {
# Handle TEMPLATES array
for template in "${!TEMPLATES[@]}"; do
local output_file="${TEMPLATES[$template]}"
process_file "$template" "$output_file" true
done
# Handle COPY_TEMPLATES array
for template in "${!COPY_TEMPLATES[@]}"; do
local output_file="${COPY_TEMPLATES[$template]}"
process_file "$template" "$output_file" false
done
}
# Function to generate example files
generate_example_files() {
env_cmd="env -i"
env_vars["OPENIM_IP"]="127.0.0.1"
env_vars["LOG_STORAGE_LOCATION"]="../../"
for var in "${!env_vars[@]}"; do
env_cmd+=" $var='${env_vars[$var]}'"
done
# Processing EXAMPLES array
for template in "${!EXAMPLES[@]}"; do
local example_file="${EXAMPLES[$template]}"
process_file "$template" "$example_file" true
done
# Processing COPY_EXAMPLES array
for template in "${!COPY_EXAMPLES[@]}"; do
local example_file="${COPY_EXAMPLES[$template]}"
process_file "$template" "$example_file" false
done
}
# Function to process a single file, either by generating or copying
process_file() {
local template=$1
local output_file=$2
local use_genconfig=$3
if [[ -f "${output_file}" ]]; then
if [[ "${FORCE_OVERWRITE}" == true ]]; then
openim::log::info "Force overwriting ${output_file}."
elif [[ "${SKIP_EXISTING}" == true ]]; then
#openim::log::info "Skipping generation of ${output_file} as it already exists."
return
else
echo -n "File ${output_file} already exists. Overwrite? (Y/N): "
read -r -n 1 REPLY
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
openim::log::info "Skipping generation of ${output_file}."
return
fi
fi
else
if [[ "${SKIP_EXISTING}" == true ]]; then
openim::log::info "Generating ${output_file} as it does not exist."
fi
fi
if [[ "$use_genconfig" == true ]]; then
openim::log::info "⌚ Working with template file: ${template} to generate ${output_file}..."
if [[ ! -f "${OPENIM_ROOT}/scripts/genconfig.sh" ]]; then
openim::log::error "genconfig.sh script not found"
exit 1
fi
if [[ -n "${env_cmd}" ]]; then
{
printf "debugggggggggggggggggggg file: %s template: %s\n" "${ENV_FILE}" "${template}"
} | tee /tmp/debug.log
eval "$env_cmd ${OPENIM_ROOT}/scripts/genconfig.sh '${ENV_FILE}' '${template}' > '${output_file}'" || {
openim::log::error "Error processing template file ${template}"
exit 1
}
else
"${OPENIM_ROOT}/scripts/genconfig.sh" "${ENV_FILE}" "${template}" > "${output_file}" || {
openim::log::error "Error processing template file ${template}"
exit 1
}
fi
else
openim::log::info "📋 Copying ${template} to ${output_file}..."
cp "${template}" "${output_file}" || {
openim::log::error "Error copying template file ${template}"
exit 1
}
fi
FILES_PROCESSED=true
}
clean_config_files() {
local all_templates=("${TEMPLATES[@]}" "${COPY_TEMPLATES[@]}")
for output_file in "${all_templates[@]}"; do
if [[ -f "${output_file}" ]]; then
rm -f "${output_file}"
openim::log::info "Removed configuration file: ${output_file}"
fi
done
}
# Function to clean example files
clean_example_files() {
local all_examples=("${EXAMPLES[@]}" "${COPY_EXAMPLES[@]}")
for example_file in "${all_examples[@]}"; do
if [[ -f "${example_file}" ]]; then
rm -f "${example_file}"
openim::log::info "Removed example file: ${example_file}"
fi
done
}
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
show_help
exit 0
;;
--force)
FORCE_OVERWRITE=true
shift
;;
--skip)
SKIP_EXISTING=true
shift
;;
--examples)
GENERATE_EXAMPLES=true
shift
;;
--clean-config)
CLEAN_CONFIG=true
shift
;;
--clean-examples)
CLEAN_EXAMPLES=true
shift
;;
*)
echo "Unknown option: $1"
show_help
exit 1
;;
esac
done
# Clean configuration files if --clean-config option is provided
if [[ "${CLEAN_CONFIG}" == true ]]; then
clean_config_files
fi
# Clean example files if --clean-examples option is provided
if [[ "${CLEAN_EXAMPLES}" == true ]]; then
clean_example_files
fi
# Generate configuration files if requested
if [[ "${FORCE_OVERWRITE}" == true || "${SKIP_EXISTING}" == false ]] && [[ "${CLEAN_CONFIG}" == false ]]; then
generate_config_files
fi
# Generate configuration files if requested
if [[ "${SKIP_EXISTING}" == true ]]; then
generate_config_files
fi
# Generate example files if --examples option is provided
if [[ "${GENERATE_EXAMPLES}" == true ]] && [[ "${CLEAN_EXAMPLES}" == false ]]; then
generate_example_files
fi
if [[ "${FILES_PROCESSED}" == true ]]; then
openim::log::success "Configuration and example files operation complete!"
fi

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